简体   繁体   English

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

[英]All the paths between 2 nodes in graph

I have to make an uninformed search (Breadth-first-Search) program which takes two nodes and return all the paths between them. 我必须进行一个不知情的搜索(广度优先搜索)程序,它接受两个节点并返回它们之间的所有路径。

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());
                    }
                }
            }
        }

My problem is that i only get two paths instead of all and i don't know what to edit in my code to get them all. 我的问题是,我只获得两条路径,而不是所有路径,我不知道在我的代码中编辑什么来获取它们。 The input of my problem is based on this map : 我的问题输入基于这张地图: 地图

Breadth first search is a strange way to generate all possible paths for the following reason: you'd need to keep track of whether each individual path in the BFS had traversed the node, not that it had been traversed at all. 广度优先搜索是生成所有可能路径的一种奇怪方式,原因如下:您需要跟踪BFS中的每个单独路径是否已遍历该节点,而不是完全遍历该节点。

Take a simple example 举一个简单的例子

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

We want all paths from 1 to 5. We queue up 1, then 2 and 3, then 4, then 5. We've lost the fact that there are two paths through 4 to 5. 我们想要从1到5的所有路径。我们排队1,然后是2和3,然后是4,然后是5.我们已经失去了通过4到5的两条路径的事实。

I would suggest trying to do this with DFS, though this may be fixable for BFS with some thinking. 我建议尝试用DFS来做这件事,尽管这可能是BFS可以解决的问题。 Each thing queued would be a path, not a single node, so one could see if that path had visited each node. 排队的每个东西都是路径,而不是单个节点,因此可以看到该路径是否访问过每个节点。 This is wasteful memory wise, thoug 如此,这是浪费的记忆

In the BFS algorithm you must not stop after you find a solution. 在BFS算法中,您必须在找到解决方案后停止。 One idea is to set data null for all the cities you visited except the first one and let the function run a little bit longer. 一个想法是为你访问过的所有城市设置数据null,除了第一个,让函数运行一点点。 I don't have time to write you a snippet but if ou don't get it i will write at least a pseudocode. 我没有时间给你写一个片段但是如果你没有得到它我会写至少一个伪代码。 If you didn't understood my idea post a comment with your question and i will try to explain better. 如果你不理解我的想法发表你的问题的评论,我会尝试更好地解释。

A path is a sequence of vertices where no vertex is repeated more than once. 路径是一系列顶点,其中没有顶点重复多次。 Given this definition, you could write a recursive algorithm which shall work as follows: Pass four parameters to the function, call it F(u, v, intermediate_list, no_of_vertices) , where u is the current source (which shall change as we recurse), v is the destination, intermediate_list is a list of vertices which shall be initially empty, and every time we use a vertex, we'll add it to the list to avoid using a vertex more than once in our path, and no_of_vertices is the length of the path that we would like to find, which shall be lower bounded by 2 , and upper bounded by V , the number of vertices. 根据这个定义,你可以编写一个递归算法,它应该按如下方式工作:将四个参数传递给函数,称之为F(u, v, intermediate_list, no_of_vertices) ,其中u是当前源(当我们递归时它将改变) , v是目的地, intermediate_list是一个最初应为空的顶点列表,每次我们使用顶点时,我们都会将它添加到列表中,以避免在路径中多次使用顶点,而no_of_vertices是我们想要找到的路径的长度,其下限应为2 ,上限由V (顶点数)限定。 Essentially, the function shall return a list of paths whose source is u , destination is v , and whose length of each path is no_of_vertices . 本质上,该函数应返回一个路径列表,其源为u ,目标为v ,每个路径的长度为no_of_vertices Create an initial empty list and make calls to F(u, v, {}, 2), F(u, v, {}, 3), ..., F(u, v, {}, V) , each time merging the output of F with the list where we intend to store all paths. 创建一个初始空列表并调用F(u, v, {}, 2), F(u, v, {}, 3), ..., F(u, v, {}, V) ,每个时间将F的输出与我们打算存储所有路径的列表合并。 Try to implement this, and if you still face trouble, I'll write the pseudo-code for you. 尝试实现这一点,如果你仍然遇到麻烦,我会为你编写伪代码。

Edit: Solving the above problem using BFS: Breadth first search is an algorithm that could be used to explore all the states of a graph. 编辑:使用BFS解决上述问题:广度优先搜索是一种可用于探索图形的所有状态的算法。 You could explore the graph of all paths of the given graph, using BFS, and select the paths that you want. 您可以使用BFS浏览给定图形的所有路径的图形,并选择所需的路径。 For each vertex v , add the following states to the queue: (v, {v}, {v}) , where each state is defined as: (current_vertex, list_of_vertices_already_visited, current_path) . 对于每个顶点v ,将以下状态添加到队列中: (v, {v}, {v}) ,其中每个状态定义为: (current_vertex, list_of_vertices_already_visited, current_path) Now, while the queue is not empty, pop off the top element of the queue, for each edge e of the current_vertex , if the tail vertex x doesn't already exist in the list_of_vertices_already_visited , push the new state (x, list_of_vertices_already_visited + {x}, current_path -> x) to the queue, and process each path as you pop it off the queue. 现在,当队列不为空时,弹出队列的顶部元素,对于current_vertex每个边e ,如果list_of_vertices_already_visited已经存在尾部顶点x ,则推送新状态(x, list_of_vertices_already_visited + {x}, current_path -> x)到队列,并在将其从队列中弹出时处理每个路径。 This way you can search the entire graph of paths for a graph, whether directed, or undirected. 通过这种方式,您可以搜索图表的整个路径图,无论是定向还是无向。

Sounds like homework. 听起来像是家庭作业。 But the fun kind. 但有趣的是那种。

The following is pseudocode, is depth first instead of breath first (so should be converted to a queue type algorithm, and may contain bugs, but the general jist should be clear. 以下是伪代码,首先是深度而不是先呼吸(所以应该转换为队列类型算法,并且可能包含错误,但是一般的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;
}

Edit: Is this actually the answer to the question you are looking for? 编辑:这实际上是您正在寻找的问题的答案吗? Or do you actually want to find the shortest path? 或者你真的想找到最短路径? If it's the latter, use Dijkstra's algorithm: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm 如果是后者,请使用Dijkstra的算法: http//en.wikipedia.org/wiki/Dijkstra%27s_algorithm

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

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