Algorithm 枚举所有可能路径的算法

Algorithm 枚举所有可能路径的算法,algorithm,graph-theory,graph-algorithm,depth-first-search,breadth-first-search,Algorithm,Graph Theory,Graph Algorithm,Depth First Search,Breadth First Search,考虑下图: 我试图找到一种方法来枚举从源节点到目标节点的所有可能路径。例如,从A到E,我们有以下可能的路径: A B C D E A B C E A C D E A C E 请注意,对于CDE,实际上有两条路径,因为其中一条路径使用边F3,另一条使用边F5。另外,由于a和C之间有一个循环,最终可能会有无限多条路径,但出于这个目的,我只对从源到目标的路径上没有重复节点的路径感兴趣 我编写了一个深度优先搜索(DFS)算法,但问题是当两个节点之间有多条边(如上面的边F3和F5)时,我不确定如何处理

考虑下图:

我试图找到一种方法来枚举从源节点到目标节点的所有可能路径。例如,从A到E,我们有以下可能的路径:

A B C D E
A B C E
A C D E
A C E
请注意,对于CDE,实际上有两条路径,因为其中一条路径使用边F3,另一条使用边F5。另外,由于a和C之间有一个循环,最终可能会有无限多条路径,但出于这个目的,我只对从源到目标的路径上没有重复节点的路径感兴趣

我编写了一个深度优先搜索(DFS)算法,但问题是当两个节点之间有多条边(如上面的边F3和F5)时,我不确定如何处理它。我的算法只返回路径
acde
ace
,而不是其他路径。在
A B C E
的情况下,我理解其原因,因为它从A开始,然后转到C并构建这些路径,但当DFS返回到节点B时,它会尝试转到C,但C已经被访问,因此它会停止

不管怎样,我只是想知道是否有办法做到这一点,或者这可能是NP完全的

如果您想查看我的DFS,代码如下(很抱歉宏滥用,我在竞赛编程中使用这些,所以这有点习惯)

无论如何,我只是想知道是否有办法做到这一点,或者这可能是NP完全的。
我不相信你能输出
n多项式时间内的可能路径。如果每个节点都连接到另一个节点,那么这就是如何得到的

但问题是,如果两个节点之间有多条边(如上面的边F3和F5)
所以,你要考虑边<代码> f3< /代码>和<代码> f5<代码>,对吗?在调用
dfs
之前删除重复边可能是最简单的选择

因为它从A开始,然后转到C并构建这些路径,但当DFS返回到节点B时,它会尝试转到C,但C已被访问,因此它会停止。
那么,让我们把
C
标记为不再访问

void dfs(char at) {
    vis[at] = true;

    // do stuff with 'at'

    vis[at] = false;
}

我的猜测是,如果你说

J->K->L->O->T
J->M->N->O->T

我认为你的“我们以前到过这里吗”测试不应该只看当前节点,而是看你到达那里的路径。因此,不要检查“O”,检查“JMNO”和“JKLO”。

以下是使用BFS的方法:可以使用以下(
python
)函数(使用两个节点之间的递归路径查找函数修改BFS)查找非循环图中两个节点之间的所有可能路径:

例如,对于以下图(DAG)G(通过从给定图中移除有向圈和多条边),由

G = {'A':['B','C'], 'B':['C'], 'C':['D', 'E', 'F'], 'D':['E'], 'E':['I'], 'F':['G', 'H']}
如果我们想查找节点
'A'
'E'
之间的所有路径(使用上述定义的函数
查找所有路径(查找所有父节点(G,'A'),'A','E'))
,它将根据需要返回以下路径:

# ACDE
# ABCDE
# ACE
# ABCE

我怀疑这是topcoder的问题。在这种情况下,输入大小的限制是什么?嗨,Kit,很高兴在这里遇到你!这不是来自algo竞赛的TC问题,该搜索将在DB中完成。因此,大小几乎可以是无限的。我在想也许没有真正的解决办法,你觉得呢?很高兴见到你:)如果输入没有限制,那么你将很难输出所有的n!解决。但是如果结果的大小是有限的或者它是某种非常稀疏的图,这可能会起作用。在应用程序中,您忘记了从节点B开始的边。这可以解释为什么它找不到路径A B C D E和A B C E。@Patrick-Yep,也注意到了,谢谢!谢谢,DFS和回溯按照您的建议进行了工作。这一点很好,但我相信Nikita建议的回溯方法可以解决这个问题。当它到达T时,它将一路“回溯”到J(将节点标记为沿途未访问),然后它将再次沿着路径递归以获得第二条路径。
from collections import defaultdict

# modified BFS
def find_all_parents(G, s):
    Q = [s]
    parents = defaultdict(set)
    while len(Q) != 0:
        v = Q[0]
        Q.pop(0)
        for w in G.get(v, []):
            parents[w].add(v)
            Q.append(w) 
    return parents

# recursive path-finding function (assumes that there exists a path in G from a to b)   
def find_all_paths(parents, a, b): 
    return [a] if a == b else [y + b for x in list(parents[b]) for y in find_all_paths(parents, a, x)]
G = {'A':['B','C'], 'B':['C'], 'C':['D', 'E', 'F'], 'D':['E'], 'E':['I'], 'F':['G', 'H']}
# ACDE
# ABCDE
# ACE
# ABCE