2个节点之间的简单路径

时间:2012-06-19 15:52:55

标签: algorithm graph

我知道我自己,其他许多人可能都在这里,

嗯,根据 CLRS(3版,22.4.2),有一种O(n)算法,用于查找有向无环图中2个节点之间的所有简单路径。 我经历了类似的问题,Number of paths between two nodes in a DAGAll the paths between 2 nodes in graph,但在两种情况下,都没有提到正确的解释或伪代码,或者如果是,我怀疑它是最有效的问题({{1} })。

如果有人真的可以发布一个确切的代码或伪代码来解决这个问题,因为当我浏览了所有上述链接时,我并没有真正找到1个单独的答案。

如果代码还处理循环图表会更好,例如如果图中有一个周期,但如果没有路径两个节点之间包含周期,路径数应该 FINITE,否则为INFINITE。

1 个答案:

答案 0 :(得分:5)

Jeremiah Willcockanswer是正确的,但很清楚细节。这是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之外,我在几分钟的搜索中找不到任何东西。

好的,这是一些伪代码。我已经将前一算法的内容与拓扑排序集成在一起,并添加了一些循环检测逻辑。如果st之间有一个周期,则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]