繁体   English   中英

图中2个节点之间的所有路径

[英]All the paths between 2 nodes in graph

我必须进行一个不知情的搜索(广度优先搜索)程序,它接受两个节点并返回它们之间的所有路径。

public void BFS(Nod start, Nod end) {
            Queue<Nod> queue = new Queue<Nod>();
            queue.Enqueue(start);
            while (queue.Count != 0)
            {
                Nod u = queue.Dequeue();
                if (u == end)  break;
                else
                {
                    u.data = "Visited";
                    foreach (Edge edge in u.getChildren())
                    {
                        if (edge.getEnd().data == "")
                        {
                            edge.getEnd().data = "Visited";
                            if (edge.getEnd() != end)
                            {
                                edge.getEnd().setParent(u);
                            }
                            else
                            {
                                edge.getEnd().setParent(u);
                                cost = 0; 
                                PrintPath(edge.getEnd(), true);
                                edge.getEnd().data = "";
                                //return;
                            }
                        }
                        queue.Enqueue(edge.getEnd());
                    }
                }
            }
        }

我的问题是,我只获得两条路径,而不是所有路径,我不知道在我的代码中编辑什么来获取它们。 我的问题输入基于这张地图: 地图

广度优先搜索是生成所有可能路径的一种奇怪方式,原因如下:您需要跟踪BFS中的每个单独路径是否已遍历该节点,而不是完全遍历该节点。

举一个简单的例子

1----2
 \    \
  3--- 4----5

我们想要从1到5的所有路径。我们排队1,然后是2和3,然后是4,然后是5.我们已经失去了通过4到5的两条路径的事实。

我建议尝试用DFS来做这件事,尽管这可能是BFS可以解决的问题。 排队的每个东西都是路径,而不是单个节点,因此可以看到该路径是否访问过每个节点。 如此,这是浪费的记忆

在BFS算法中,您必须在找到解决方案后停止。 一个想法是为你访问过的所有城市设置数据null,除了第一个,让函数运行一点点。 我没有时间给你写一个片段但是如果你没有得到它我会写至少一个伪代码。 如果你不理解我的想法发表你的问题的评论,我会尝试更好地解释。

路径是一系列顶点,其中没有顶点重复多次。 根据这个定义,你可以编写一个递归算法,它应该按如下方式工作:将四个参数传递给函数,称之为F(u, v, intermediate_list, no_of_vertices) ,其中u是当前源(当我们递归时它将改变) , v是目的地, intermediate_list是一个最初应为空的顶点列表,每次我们使用顶点时,我们都会将它添加到列表中,以避免在路径中多次使用顶点,而no_of_vertices是我们想要找到的路径的长度,其下限应为2 ,上限由V (顶点数)限定。 本质上,该函数应返回一个路径列表,其源为u ,目标为v ,每个路径的长度为no_of_vertices 创建一个初始空列表并调用F(u, v, {}, 2), F(u, v, {}, 3), ..., F(u, v, {}, V) ,每个时间将F的输出与我们打算存储所有路径的列表合并。 尝试实现这一点,如果你仍然遇到麻烦,我会为你编写伪代码。

编辑:使用BFS解决上述问题:广度优先搜索是一种可用于探索图形的所有状态的算法。 您可以使用BFS浏览给定图形的所有路径的图形,并选择所需的路径。 对于每个顶点v ,将以下状态添加到队列中: (v, {v}, {v}) ,其中每个状态定义为: (current_vertex, list_of_vertices_already_visited, current_path) 现在,当队列不为空时,弹出队列的顶部元素,对于current_vertex每个边e ,如果list_of_vertices_already_visited已经存在尾部顶点x ,则推送新状态(x, list_of_vertices_already_visited + {x}, current_path -> x)到队列,并在将其从队列中弹出时处理每个路径。 通过这种方式,您可以搜索图表的整个路径图,无论是定向还是无向。

听起来像是家庭作业。 但有趣的是那种。

以下是伪代码,首先是深度而不是先呼吸(所以应该转换为队列类型算法,并且可能包含错误,但是一般的jist应该是清楚的。

class Node{
  Vector[Link] connections;
  String name;
}

class Link{
  Node destination;
  int distance;
}

Vector[Vector[Node]] paths(Node source, Node end_dest, Vector[Vector[Node]] routes){
  for each route in routes{
    bool has_next = false;
    for each connection in source.connections{
      if !connection.destination in route {
        has_next = true;
        route.push(destination);
        if (!connection.destination == end_dest){
          paths(destination, end_dest, routes);
        }
      }
    }
    if !has_next {
      routes.remove(route) //watch out here, might mess up the iteration
    }
  }
  return routes;
}

编辑:这实际上是您正在寻找的问题的答案吗? 或者你真的想找到最短路径? 如果是后者,请使用Dijkstra的算法: http//en.wikipedia.org/wiki/Dijkstra%27s_algorithm

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM