我知道我自己,其他许多人可能都在这里,
嗯,根据 CLRS(3版,22.4.2),有一种O(n)算法,用于查找有向无环图中2个节点之间的所有简单路径。 我经历了类似的问题,Number of paths between two nodes in a DAG和All the paths between 2 nodes in graph,但在两种情况下,都没有提到正确的解释或伪代码,或者如果是,我怀疑它是最有效的问题({{1} })。
如果有人真的可以发布一个确切的代码或伪代码来解决这个问题,因为当我浏览了所有上述链接时,我并没有真正找到1个单独的答案。
如果代码还处理循环图表会更好,例如如果图中有一个周期,但如果没有路径两个节点之间包含周期,路径数应该 FINITE,否则为INFINITE。
答案 0 :(得分:5)
Jeremiah Willcock的answer是正确的,但很清楚细节。这是DAG的线性时间算法。
for each node v, initialize num_paths[v] = 0
let t be the destination and set num_paths[t] = 1
for each node v in reverse topological order (sinks before sources):
for each successor w of v:
set num_paths[v] = num_paths[v] + num_paths[w]
let s be the origin and return num_paths[s]
我很确定一般有向图的问题是#P-complete,但除了unsourced question之外,我在几分钟的搜索中找不到任何东西。
好的,这是一些伪代码。我已经将前一算法的内容与拓扑排序集成在一起,并添加了一些循环检测逻辑。如果s
和t
之间有一个周期,则num_paths
的值可能不准确,但根据t
是否可达,将为零非零。并非周期中的每个节点都将in_cycle
设置为true,但每个SCC根(在Tarjan的SCC算法意义上)将足以触发提前退出,当且仅当s和之间存在循环时吨。
REVISED ALGORITHM
let the origin be s
let the destination be t
for each node v, initialize
color[v] = WHITE
num_paths[v] = 0
in_cycle[v] = FALSE
num_paths[t] = 1
let P be an empty stack
push (ENTER, s) onto P
while P is not empty:
pop (op, v) from P
if op == ENTER:
if color[v] == WHITE:
color[v] = GRAY
push (LEAVE, v) onto P
for each successor w of v:
push (ENTER, w) onto P
else if color[v] == GRAY:
in_cycle[v] = TRUE
else: # op == LEAVE
color[v] = BLACK
for each successor w of v:
set num_paths[v] = num_paths[v] + num_paths[w]
if num_paths[v] > 0 and in_cycle[v]:
return infinity
return num_paths[s]