我有一个具有以下邻接列表的DAG
L | G, B, P
G | P, I
B | I
P | I
I | R
R | \
我想查找从L
到R
的所有路径。我知道我必须做某种DFS,这就是我到目前为止所做的。 (请原谅Javascript)
function dfs(G, start_vertex) {
const fringe = []
const visited = new Set()
const output = []
fringe.push(start_vertex)
while (fringe.length != 0) {
const vertex = fringe.pop()
if (!visited.has(vertex)) {
output.push(vertex)
for (neighbor in G[vertex].neighbors) {
fringe.push(neighbor)
}
visited.add(vertex)
}
}
return output
}
dfs(G, "L")
的输出是[ 'L', 'P', 'I', 'R', 'B', 'G' ]
,这确实是此图的深度优先遍历,但不是我正在寻找的结果。在做了一些搜索之后,我意识到可能有一个递归的解决方案,但是有一些关于这个问题的评论是“NP-hard”和关于“指数路径”的一些我不明白的。
答案 0 :(得分:2)
所有路径head
到顶点vertex
的路径都可以拆分为头head||v
的路径,其中v
与head
的最终顶点相邻,除非head
的最终顶点已经vertex
:(伪javascript,可能有语法问题)
function print_all_rec(G, head, vertex){
if(head[head.length-1] == vertex){
print(head); //we're here
return;
}
for(v in head[head.length-1].neighbors){
var newHead = head; newHead.append(v);
print_all_rec(G, newHead, vertex);
}
}
function print_all_routes(G, from, to){
var start = [];
start.append(from);
print_all_rec(G, start, to);
}
答案 1 :(得分:2)
问题确实是np-hard,因为两个节点之间可能的路径数量与节点数呈指数关系。所以没有办法解决最坏情况下的指数运行时间。