Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 循环无向图中的所有可能路径_Java_C++_Algorithm - Fatal编程技术网

Java 循环无向图中的所有可能路径

Java 循环无向图中的所有可能路径,java,c++,algorithm,Java,C++,Algorithm,我正在尝试开发一种算法,用于识别图形中两个节点之间的所有可能路径,如本例所示: 事实上,我只需要知道哪些节点出现在所有现有路径中 在网络上,只有关于DFS、A*或dijkstra的参考资料,但我认为它们在这种情况下不起作用 有人知道如何解决这个问题吗?从起始节点运行DFS,并保留自己的堆栈,告诉您在任何给定时间看到了哪些节点。注意循环:当您两次看到一个节点时,您有一个循环,您必须中止当前路径。注意不要访问节点的父节点,以避免长度为1的循环(在DFS函数中添加parent参数将有所帮助) 然后,

我正在尝试开发一种算法,用于识别图形中两个节点之间的所有可能路径,如本例所示:

事实上,我只需要知道哪些节点出现在所有现有路径中

在网络上,只有关于DFS、A*或dijkstra的参考资料,但我认为它们在这种情况下不起作用


有人知道如何解决这个问题吗?

从起始节点运行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