![](/img/trans.png)
[英]A star search: a lot of nodes and a “slow” CheckLink between nodes… any suggestions?
[英]suggestions how to keep “calculated” a lot of “dependent” parameters
我有几个指标需要“始终保持最新”。 即,当发生任何更改时,我需要重新计算“从属”。 我有几个级别,仅在计算上一个级别时才应计算每个下一个级别。 让我通过这张照片来解释一下:
在某个时候,假设法郎改变了。 然后,我们应该:
或者,如果一次更改比索,法郎和第纳尔,那么我们应该:
因此,无论何时遇到Level 0
任何东西,我们都应该重新计算所有其他级别。 但
最直接的解决方案是:
我想我的问题是众所周知的,也许您可以向我建议一般的解决方案。 我不想重新发明轮子:)谢谢!
我认为基于级别的方法是合理的,前提是侦听器始终处于较低级别。
有一个包含您的实际数据的2D数组,第一个索引是级别,第二个索引是级别上的位置。 让每个元素都有一个willBeRecalculated
标志。
每个级别都有一个toBeRecalculated
列表(因此是一个列表数组)。
对于每个元素,都有一个包含2个整数的元素(侦听器)列表-一个用于级别,一个用于索引。
对于每个要修改的元素,在适当的级别将元素添加到toBeRecalculated
并将willBeRecalculated
设置为true。
然后从第一级到最后一级进行toBeRecalculated
,重新计算每个元素,将其willBeRecalculated
设置为false,然后对于每个侦听器,查找适用的元素,如果willBeRecalculated
为true,则什么也不做,否则,将willBeRecalculated
设置为true并添加toBeRecalculated
在其(侦听器)级别上重新计算。
这种方法不会遍历所有数据来检查需要修改/已修改的内容,它仅检查适用的元素,并且没有重复的计算。
为了这:
(对于我的缩写,我只是拿了每个单词的第一个字母。我使用的是0索引数组)
实际数据:
[[E, U, P, F, D],
[E+U, F/D],
[E/E+D, F/D/P],
[P+E/E+U]
]
听众:
E:[(1,0), (2,0)] // E+U and E/E+U
U:[(1,0)] // E+U
P:[(2,1), (3,0)]
F:[(1,1)]
D:[(1,1)]
E+U:[(2,0)]
F/D:[(2,1)]
E/E+U:[(3,0)]
修改E
和U
:
将E
和U
添加到toBeRecalculated[0]
并将两者的willBeRecalculated
设置为true。
进行toBeRecalculated[0]
。
修改E
,将willBeRecalculated
设置为false并将E+U
的willBeRecalculated
为true并将其添加到toBeRecalculated[1]
并将E/E+U
的willBeRecalculated
为true并将其添加到toBeRecalculated[2]
。
修改U
,将它的willBeRecalculated
设置为false,然后检查E+U
的willBeRecalculated
,看它是正确的,所以什么也不做。
然后进行toBeRecalculated[1]
。 修改E+U
,将willBeRecalculated
设置为false并检查E/E+U
的willBeRecalculated
并查看它的正确性,因此不执行任何操作。
最好让侦听器作为元素的指针,而不是级别和索引变量。
好吧,当您说要处理关卡时,就会想到某种树数据结构。
但是对于您的问题,我认为对某种有向无环图建模是可行的。
您的图表可能看起来像这样(所有方向都朝下)。
root
/ / | \ \
E U P F D
\ /
\ /
(Euro + Usd)
如果像树形数据结构那样遍历该对象,则每次对货币进行的更新时,每个转换率都将精确更新一次。
我认为您可以在此处使用多态。 有一个货币列表,每个货币都包含一个向量,该向量带有所有去污元素的指针(指向基类)。
基类迫使它们包括一个函数update()
,该函数在每次更新当前货币时都会调用。
反作用元素依次具有它们所依赖的每种货币的指针,并在其update()
实现中使用它们来更新自身。
#include<iostream>
#include <vector>
class c_node_combi_base;
class currency
{
std::vector<c_node_combi_base*> m_dependant;
double m_val;
public:
double value (void) const { return m_val; }
void reg (c_node_combi_base * p) { m_dependant.push_back(p); }
void update (double val);
};
class c_node_combi_base
{
std::vector<currency*> currencies;
public:
virtual void update (void) = 0;
};
template<size_t N, typename OP> // templated to differentiate types of nodes
class currency_node : public c_node_combi_base
{
};
struct divide_d
{
double operator() (const double x, const double y) const {return x/y;}
};
template<typename OPT> // node type 2
class currency_node<2u, OPT>
: public c_node_combi_base
{
currency *A, *B;
OPT _op;
double m_val;
public:
currency_node (currency * a, currency * b)
: A(a), B(b), _op(), m_val(_op(A->value(), B->value()))
{
A->reg(this);
B->reg(this);
}
void update (void)
{
m_val = _op(A->value(), B->value());
}
double value (void) { return m_val; }
};
void currency::update (double value)
{
m_val = value;
for (size_t i=0; i<m_dependant.size(); ++i)
{
m_dependant[i]->update();
}
}
这样可以:
int main (void)
{
currency franc, dinar;
franc.update(9.9);
dinar.update(3.3);
currency_node<2, divide_d> franc_dinar(&franc, &dinar);
std::cout << franc_dinar.value() << std::endl;
dinar.update(1.1); // updates franc_dinar automatically
std::cout << franc_dinar.value() << std::endl;
}
印刷:
3
9
也许您可以拥有货币的std::vector<std::weak_ptr>
,而每个节点持有每种货币的std::shared_ptr
,因此除非没有其他节点引用,否则这些货币可能不会超出范围/被销毁他们
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.