【问题标题】:Simple Paths between 2 nodes2个节点之间的简单路径
【发布时间】:2012-06-21 17:10:02
【问题描述】:

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

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

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

如果代码也处理循环图会更好,即如果图中有循环,但是如果没有路径 两个节点之间包含循环,路径数应为FINITE,否则为INFINITE。

【问题讨论】:

  • 我想你误读了 CLRS,你会引用关于从书中找到 O(n) 中所有路径的确切段落吗?
  • Saeed,恐怕我没看错。这是CLRS 3版第614,22.4.2页的练习题!

标签: algorithm graph


【解决方案1】:

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,但我在几分钟的搜索中找不到任何东西,除了 cstheory 上的 unsourced question

好的,这是一些伪代码。我将之前算法的内容与拓扑排序进行了整合,并添加了一些循环检测逻辑。如果st 之间存在循环,num_paths 的值可能不准确,但会根据t 是否可达而为零非零。并非循环中的每个节点都将in_cycle 设置为true,但每个SCC 根(在Tarjan 的SCC 算法的意义上)都会,当且仅当s 和t 之间存在循环时,这足以触发提前退出。

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]

【讨论】:

  • ,您能否建议如何修改它以检测循环,因为在这种情况下,numpaths 将是无限的?
  • 丰富,非常感谢。它像一个梦一样工作。但是当图中有一个循环时它不能处理这种情况(是的,我承认我问过 DAG),但如果可以建议修改的话。 !
  • 您可以在确定拓扑顺序的同时检测循环 - DFS 将在灰色节点上加倍。
  • 但这会发现图中存在的每个循环,即使从源和接收器都无法访问该循环。
  • 顺便说一句,出于教学原因,我将 WHITE/GRAY/BLACK 和 in_cycle 分开,但有效的实现可以使用 WHITE/GRAYNOCYCLE/GRAYCYCLE/BLACK 四种组合状态。
猜你喜欢
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多