Java 循环无向图中的所有可能路径
我正在尝试开发一种算法,用于识别图形中两个节点之间的所有可能路径,如本例所示: 事实上,我只需要知道哪些节点出现在所有现有路径中 在网络上,只有关于DFS、A*或dijkstra的参考资料,但我认为它们在这种情况下不起作用Java 循环无向图中的所有可能路径,java,c++,algorithm,Java,C++,Algorithm,我正在尝试开发一种算法,用于识别图形中两个节点之间的所有可能路径,如本例所示: 事实上,我只需要知道哪些节点出现在所有现有路径中 在网络上,只有关于DFS、A*或dijkstra的参考资料,但我认为它们在这种情况下不起作用 有人知道如何解决这个问题吗?从起始节点运行DFS,并保留自己的堆栈,告诉您在任何给定时间看到了哪些节点。注意循环:当您两次看到一个节点时,您有一个循环,您必须中止当前路径。注意不要访问节点的父节点,以避免长度为1的循环(在DFS函数中添加parent参数将有所帮助) 然后,
有人知道如何解决这个问题吗?从起始节点运行DFS,并保留自己的堆栈,告诉您在任何给定时间看到了哪些节点。注意循环:当您两次看到一个节点时,您有一个循环,您必须中止当前路径。注意不要访问节点的父节点,以避免长度为1的循环(在DFS函数中添加
parent
参数将有所帮助)
然后,当到达目标节点时,输出堆栈的内容
一旦DFS完成,您将拥有所有路径 您可以使用DFS查找所有路径,如| Vlad所述。要查找每个路径中出现的节点,只需维护一个布尔数组,该数组表示到目前为止每个节点是否出现在每个路径中。当DFS找到路径时,遍历路径以外的每个顶点,并将相应的数组值设置为false。完成后,只有值为true的顶点才会出现在每个路径中 伪代码:
int source;
int sink;
int nVerts;
bool inAllPaths[nVerts]; // init to all true
bool visited[nVerts]; // init to all false
stack<int> path; // init empty
bool dfs(int u)
if (visited[u])
return;
if (u == sink)
for i = 0 to nVerts-1
if !stack.contains(i)
inAllPaths[i] = false;
return true;
else
visited[u] = true;
stack.push(u);
foreach edge (u, v)
dfs(v);
stack.pop();
visited[u] = false;
return false;
main()
dfs(source);
// inAllPaths contains true at vertices that exist in all paths
// from source to sink.
// Using the same initialisation as above, but with a slight modification
// to dfs: change the foreach loop to
foreach edge (u, v)
if (dfs(v))
return true; // exit as soon as we find a path
main()
for i = 0 to nVerts-1
set all visited to false;
if (inAllPaths[i])
visited[i] = true;
if (dfs(source))
inAllPaths[i] = false;
visited[i] = false;
不幸的是,在搜索路径时,这仍然是指数最坏情况。您可以通过将搜索更改为广度优先搜索来解决此问题。如果我没有弄错的话,这应该会给你带来更好的性能。对于这个问题,我首先会从你的一个目标节点u上的DFS得到树t。然后,将第二个目标节点v上的子树s中的所有节点涂成蓝色
For each node k in subtree s,
if k has an edge to a non-blue node x
then k is true and x is true.
此外,标记v为true。最后,我将使用一个递归函数,一直到叶子。差不多
function(node n){
if(n = null)
return false
if(function(n.left) or function(n.right) or n.val){
n.val = true
return true
}
else
return false
}
标记为true的所有节点都是从u到v路径中的节点。运行时最多为(顶点+边),因为DFS=(V+E)for循环最多为(V)递归最多为(V)如果顶点可以从a到达,则它位于从a到B的路径上,而B可以从a到达 所以:从a开始进行整体填充。标记所有顶点。
从B开始进行溢流填充,然后沿相反方向填充边缘。您遇到的所有标记顶点都是解决方案的一部分。我知道这已经有一段时间了,但我来这里寻找一些算法来查找SQL或Java中的所有路径(不仅仅是最短路径),我发现了这三个(我只是发布它们以保持概念的组织):
- 爪哇 (依赖项:图形、ST、集合、In、在中找到)
- SQL(PostgreSQL)
使用递归传递闭包(a、b、距离、路径字符串)检查
,
- PL/SQL(Oracle)
结果:
Distance Path 3 A>B>C>G 5 A>B>C>E>F>G 3 A>B>D>G 2 A>C>G 4 A>C>E>F>G
如果您在注释中输入行
以n1…
和开始,其中n2…
查询将返回所有图形中的所有路径。?到目前为止,你尝试了什么?如果图形是循环的,不是会有无限多条路径吗?@jalf,我也这么认为,但维基百科说存在一些分歧。“没有重复顶点的路径称为简单路径,除了起点和终点的必要重复之外,没有重复顶点或边的循环称为简单循环。在现代图论中,通常隐含“简单”;即,“循环”表示“简单循环”,“路径”表示“简单路径”,但这种约定并不总是obs。”特别是在应用图论方面
Distance Path
3 A>B>C>G
5 A>B>C>E>F>G
3 A>B>D>G
2 A>C>G
4 A>C>E>F>G