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