All the paths between 2 nodes in graph

2019-02-23 09:52发布

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 : map

4条回答
欢心
2楼-- · 2019-02-23 10:13

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.

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

查看更多
我只想做你的唯一
3楼-- · 2019-02-23 10:17

In the BFS algorithm you must not stop after you find a solution. 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. 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.

查看更多
Deceive 欺骗
4楼-- · 2019-02-23 10:18

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. 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. 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. 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. You could explore the graph of all paths of the given graph, using BFS, and select the paths that you want. 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). 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. This way you can search the entire graph of paths for a graph, whether directed, or undirected.

查看更多
Animai°情兽
5楼-- · 2019-02-23 10:36

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.

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.

I would suggest trying to do this with DFS, though this may be fixable for BFS with some thinking. 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

查看更多
登录 后发表回答