图形序列化

时间:2008-08-07 00:22:54

标签: algorithm sorting graph-algorithm directed-graph

我正在寻找一种简单的算法来“序列化”有向图。特别是我有一组在执行顺序上具有相互依赖性的文件,我想在编译时找到正确的顺序。我知道它必须是一件相当普遍的事情 - 编译器会一直这样做 - 但我的google-fu今天一直很弱。什么是'go-to'算法呢?

4 个答案:

答案 0 :(得分:57)

Topological Sort(来自维基百科):

  

在图论中,拓扑排序或   定向的拓扑排序   非循环图(DAG)是线性的   每个节点的排序顺序   节点在所有节点之前到达   它有出站边缘。每个DAG都有   一个或多个拓扑排序。

伪代码:

L ← Empty list where we put the sorted elements
Q ← Set of all nodes with no incoming edges
while Q is non-empty do
    remove a node n from Q
    insert n into L
    for each node m with an edge e from n to m do
        remove edge e from the graph
        if m has no other incoming edges then
            insert m into Q
if graph has edges then
    output error message (graph has a cycle)
else 
    output message (proposed topologically sorted order: L)

答案 1 :(得分:1)

我希望那些需要它的工具只是以深度优先的方式遍历树,当它们点击叶子时,只需处理它(例如编译)并将其从图中删除(或将其标记为已处理,并处理节点)将所有叶子作为叶片加工。)

只要它是DAG,这个简单的基于堆栈的步行应该是微不足道的。

答案 2 :(得分:1)

如果图表包含周期,那么如何存在允许的文件执行顺序? 在我看来,如果图表包含周期,那么你就没有解决方案了 通过上述算法正确报告。

答案 3 :(得分:0)

我想出了一个相当天真的递归算法(伪代码):

Map<Object, List<Object>> source; // map of each object to its dependency list
List<Object> dest; // destination list

function resolve(a):
    if (dest.contains(a)) return;
    foreach (b in source[a]):
        resolve(b);
    dest.add(a);

foreach (a in source):
    resolve(a);

最大的问题是它无法检测循环依赖 - 它可以进入无限递归(即堆栈溢出; -p)。我能看到的唯一方法是将递归算法转换为带有手动堆栈的交互算法,并手动检查堆栈中是否有重复的元素。

任何人都有更好的东西吗?