【问题标题】:Problems with a simple dependency algorithm简单依赖算法的问题
【发布时间】:2010-11-14 14:23:48
【问题描述】:

在我的 webapp 中,我们有很多字段汇总了其他字段,而这些字段汇总了更多字段。我知道这是一个有向无环图。

当页面加载时,我计算所有字段的值。我真正想做的是将我的 DAG 转换为一维列表,其中包含计算字段的有效顺序。

例如: A = B + D,D = B + C,B = C + E 高效计算顺序:E -> C -> B -> D -> A

现在我的算法只是迭代地简单地插入到一个列表中,但我遇到了一些开始中断的情况。我在想,需要的是把所有的依赖关系计算成一个树结构,然后从那里把它转换成一维形式?有没有一种简单的算法可以将这种树转换为有效的排序?

【问题讨论】:

    标签: algorithm sorting tree dependencies directed-acyclic-graphs


    【解决方案1】:

    您在寻找topological sort 吗?这对 DAG 施加了排序(序列或列表)。例如,电子表格使用它来确定单元格之间的依赖关系以进行计算。

    【讨论】:

    • 非常感谢,这正是我所追求的。
    【解决方案2】:

    您想要的是深度优先搜索。

    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。

    【讨论】:

    • 非常感谢这个例子!这正是我想做的,尽管我最终选择了迭代算法。
    猜你喜欢
    • 2011-08-07
    • 2010-11-16
    • 2021-10-24
    • 2021-08-23
    • 2011-08-11
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多