I'm trying build a method which returns the shortest path from one node to another in an unweighted graph. I considered the use of Dijkstra's but this seems a bit overkill since I only want one pair. Instead I have implemented a breadth-first search, but the trouble is that my returning list contains some of the nodes that I don't want - how can I modify my code to achieve my goal?
public List<Node> getDirections(Node start, Node finish){
List<Node> directions = new LinkedList<Node>();
Queue<Node> q = new LinkedList<Node>();
Node current = start;
q.add(current);
while(!q.isEmpty()){
current = q.remove();
directions.add(current);
if (current.equals(finish)){
break;
}else{
for(Node node : current.getOutNodes()){
if(!q.contains(node)){
q.add(node);
}
}
}
}
if (!current.equals(finish)){
System.out.println("can't reach destination");
}
return directions;
}
In the case of unweighted graphs, there will be no edge weights. In that case, the shortest path T will become the path between the given 2 vertices with the minimum number of edges.
Unweighted graph: breadth-first search The root of the tree is the node you started the breadth-first search from. To find the distance from node A to any other node, we simply count the number of edges in the tree. And so we find that the shortest path between A and F is 2.
If the question is whether or not DFS can find a shortest path in unweighted or weighted graph: the answer is YES! You simply have to traverse ALL possible paths from source to destination and keep the minimum path sum.
As i realised from the comments, Dijkstra's algorithm doesn't work for unweighted graphs. By unweighted graphs I assume you mean a constant weight of (say) 1 per edge. Otherwise it is unclear what a shortest path might mean.
Actually your code will not finish in cyclic graphs, consider graph 1 -> 2 -> 1. You must have some array where you can flag which node's you've visited already. And also for each node you can save previous nodes, from which you came. So here is correct code:
private Map<Node, Boolean>> vis = new HashMap<Node, Boolean>(); private Map<Node, Node> prev = new HashMap<Node, Node>(); public List getDirections(Node start, Node finish){ List directions = new LinkedList(); Queue q = new LinkedList(); Node current = start; q.add(current); vis.put(current, true); while(!q.isEmpty()){ current = q.remove(); if (current.equals(finish)){ break; }else{ for(Node node : current.getOutNodes()){ if(!vis.contains(node)){ q.add(node); vis.put(node, true); prev.put(node, current); } } } } if (!current.equals(finish)){ System.out.println("can't reach destination"); } for(Node node = finish; node != null; node = prev.get(node)) { directions.add(node); } directions.reverse(); return directions; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With