在我的webapp中,我们有许多字段总结了其他字段,这些字段总结了更多字段。我知道这是一个有向无环图。
当页面加载时,我计算所有字段的值。我真正想要做的是将我的DAG转换为一维列表,其中包含一个有效的顺序来计算字段。
例如: A = B + D,D = B + C,B = C + E. 有效的计算顺序:E - > C - > B - > D - >甲
现在我的算法只是迭代地插入到List中,但是我遇到了一些开始破坏的情况。我在想什么需要将所有依赖项解决为树结构,并从那里将其转换为一维形式?是否有一个简单的算法将这样的树转换为有效的排序?
答案 0 :(得分:29)
您在寻找topological sort吗?这在DAG上强制排序(序列或列表)。例如,它被电子表格用于计算单元格之间的依赖关系以进行计算。
答案 1 :(得分:9)
你想要的是深度优先搜索。
function ExamineField(Field F)
{
if (F.already_in_list)
return
foreach C child of F
{
call ExamineField(C)
}
AddToList(F)
}
然后依次在每个字段上调用ExamineField(),并根据您的规范以最佳顺序填充列表。
请注意,如果字段是循环(即,您有类似A = B + C,B = A + D),则必须修改算法以使其不会进入一个无限循环。
对于您的示例,调用将是:
ExamineField(A)
ExamineField(B)
ExamineField(C)
AddToList(C)
ExamineField(E)
AddToList(E)
AddToList(B)
ExamineField(D)
ExamineField(B)
(already in list, nothing happens)
ExamineField(C)
(already in list, nothing happens)
AddToList(D)
AddToList(A)
ExamineField(B)
(already in list, nothing happens)
ExamineField(C)
(already in list, nothing happens)
ExamineField(D)
(already in list, nothing happens)
ExamineField(E)
(already in list, nothing happens)
该列表将以C,E,B,D,A结束。