我正在寻找一个很好的算法来解决以下问题。
我有以下VARIABLES和FORMULAS列表(var的结果是所有公式的总和):
var1, result=10
- 5+5=10
var2, result=15
- var1+5
var3, result=30
- var1+var2+5
现在我正在寻找一种计算所有参考文献的好方法。如果我正在更改var1并且结果现在是15,我必须计算所有引用的var1。首先我遇到了var2和recalc var2,如果var2的结果发生变化,我必须将所有引用的公式重新计算为var2。因此我会recalc var3两次(var2改变,var1改变)......
有没有解决方案在这种情况下不对两次计算var3?
THX!
答案 0 :(得分:3)
是的,你可以确保你只使用一个(最多)重新计算每个变量,使用没有循环依赖的事实(变量x
无需y
才能计算,同时y
也需要x
)。
这是通过将问题建模为graph来完成的,其中所有变量都是顶点,“所需”关系是有向边。 (因此,如果变量x
“需要计算变量y
,则存在边(y,x)
}。
现在,由于No-Cyclic依赖,这实际上是Directed Acyclic Graph,您可以topological sort(这在预处理中只能执行一次)。请注意,在您的情况下,图表很可能已经排序,正弦值是按时间顺序排列的事件,按时间顺序排列是拓扑排序。
对图形进行拓扑排序(如果需要),以及变量何时更改:
Upon variable change:
1. Mark all changed variables
2. From first variable to last (according to topological sort), for each variable x:
2.1. If there is some dependency `(y,x)` on the graph such that `y` is marked:
2.1.1. mark x
2.1.2. recalculate x
很容易看出,根据这种方法,每个变量最多计算一次。
答案 1 :(得分:1)
保留需要重新计算的变量/公式列表。使用此列表可以查看所有依赖项是否都是最新的。 如果不是这种情况,则应推迟更新变量。
回到您的示例,然后说var1
更改。
第一步是将var
放入列表中并检查所有依赖变量/公式。这些是var2
和var3
,因此也将它们放在列表中。
接下来检查var2
的依赖变量/公式(当你把它放在列表中时),这是var3
,它已经在列表中,所以保留它。上次检查var3
(您也添加了它),没有任何内容取决于var3
,所以您已经完成了。 (注意递归行为!)
第二步是更新您的值。因此,找到一个具有所有依赖关系的变量/公式。只有var1
没有依赖关系,所以从列表中弹出它并计算其值。
接下来在列表中找到另一个变量/公式,var3
仍然依赖于var2
(仍然/也在列表中),因此只有var2
适合处理。
因此,从列表中弹出var2
并计算其值。
继续处理列表,直到它为空。
假设您没有循环依赖关系:所有内容只计算一次!