按到端节点的距离对图进行排序

sort graph by distance to end nodes

我有一个图表中的节点列表。该图是有向的,不包含循环。此外,一些节点被标记为 "end" 个节点。每个节点都有一组我可以使用的输入节点。

问题如下:如何按到任何可达端节点的最大距离对列表中的节点进行排序(升序)?这是图表的外观示例。

我已经添加了计算的距离,之后我可以对节点进行排序(灰色)。末端节点的距离为 0,而 C、D 和 G 的距离为 1。但是,F 的距离为 3,因为通过 D 的方法会更短 (2)。

我做了一个我认为的概念,问题就解决了。这是一些伪代码:

sortedTable<Node, depth> // used to store nodes and their currently calculated distance
tempTable<Node>// used to store nodes 
currentDepth = 0;

- fill tempTable with end nodes

while( tempTable is not empty)
{

    - create empty newTempTable<Node node>

    // add tempTable to sortedTable
    for (every "node" in tempTable)
    {
        if("node" is in sortedTable)
        {
            - overwrite depth in sortedTable with currentDepth
        }
        else 
        {
            - add (node, currentDepth) to sortedTable
        }

        // get the node in the next layer
        for ( every "newNode" connected to node)
        {
            - add newNode to newTempTable
        }

        - tempTable = newTempTable  
    }
    currentDepth++;
}

这种方法应该有效。然而,该算法的问题在于它基本上是从基于每个端节点的图形创建树,然后为每个深度更正旧的距离计算。例如:G 的深度为 1(直接在 B 上计算),然后是深度 3(在 A、D 和 F 上计算),然后是深度 4(在 A、C、E 和 F 上计算)。

你有更好的解决这个问题的方法吗?

可以用dynamic programming来完成。

图是图上的DAG, so first do a topological sort,让排序顺序为v1,v2,v3,...,vn。

现在,为所有"end node"设置D(v)=0,并且从最后到第一(根据拓扑顺序)做:

D(v) = max { D(u) + 1, for each edge (v,u) }

之所以有效,是因为该图是一个 DAG,当以相反的拓扑顺序完成时,所有出边 (v,u) 的所有 D(u) 的值都是已知的。


图表中的示例:

拓扑排序(一种可能):

H,G,B,F,D,E,C,A

那么,算法:

init: 

D(B)=D(A)=0

从后往前走:

D(A) - no out edges, done
D(C) = max{D(A) + 1} = max{0+1}=1
D(E) = max{D(C) + 1} = 2
D(D) = max{D(A) + 1} = 1
D(F) = max{D(E)+1, D(D)+1} = max{2+1,1+1} = 3
D(B) = 0
D(G) = max{D(B)+1,D(F)+1} = max{1,4}=4
D(H) = max{D(G) + 1} = 5

附带说明一下,如果图不是 DAG,而是一般图,则这是 Longest Path Problem 的变体,即 NP-Complete。
幸运的是,当我们的图是 DAG 时,它确实有一个有效的解决方案。