我有一个属于图表的节点列表。该图是定向的,不包含循环。此外,一些节点被标记为" 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上计算)。
你有更好的解决方案吗?
答案 0 :(得分:2)
可以使用dynamic programming完成。
图表是DAG,因此首先在图表上执行topological sort,让排序的顺序为v1,v2,v3,...,vn。
现在,为所有“结束节点”设置D(v)=0
,从最后到第一个设置(根据拓扑顺序):
D(v) = max { D(u) + 1, for each edge (v,u) }
这是有效的,因为图表是DAG,当按照拓扑顺序颠倒完成时,所有传出边D(u)
的所有(v,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时,它确实有一个有效的解决方案。