public List <GraphVertex> GetPath(Graph graph, GraphVertex start, GraphVertex end) { if (graph == null || start == null || end == null || !graph.AllVertices.ContainsKey(start.Id) || !graph.AllVertices.ContainsKey(end.Id)) { // error condition pertaining to the input arguments throw new ArgumentException(); } MinHeapMap <GraphVertex> priorityQueue = new MinHeapMap <GraphVertex>(graph.AllVertices.Count); Dictionary <GraphVertex, GraphVertex> backtrack = new Dictionary <GraphVertex, GraphVertex>(); Dictionary <GraphVertex, int> finalDistance = new Dictionary <GraphVertex, int>(); // start node will have a distance of 0+manhattandistance start.CurrentDistance = ManhattanDistance(start, end); priorityQueue.Insert(start); backtrack[start] = null; while (priorityQueue.Count > 0) { GraphVertex vertex = priorityQueue.ExtractMin(); finalDistance[vertex] = vertex.CurrentDistance; if (vertex == end) { // return the path from start to end return(BackTractToGetThePath(backtrack, start, end)); } foreach (KeyValuePair <GraphVertex, int> edge in vertex.NeighbourEdges) { GraphVertex neighbour = edge.Key; int edgeWeight = edge.Value; if (!finalDistance.ContainsKey(neighbour)) { // this node's minimum distance has not yet been calculated if (neighbour.CurrentDistance > vertex.CurrentDistance + edgeWeight) { // A better distance has been found for neighbour neighbour.CurrentDistance = vertex.CurrentDistance + edgeWeight; neighbour.DistanceWithHeuristic = vertex.CurrentDistance + edgeWeight + ManhattanDistance(vertex, neighbour); priorityQueue.AddOrChangePriority(neighbour); backtrack[neighbour] = vertex; } } } } // we do not have a path from source to destination return(null); }
public List <int> GetShortestPath(List <GraphVertex> allVertices, GraphVertex source, GraphVertex destination) { List <GraphVertex> shortestPath = new List <GraphVertex>(); DistanceHeapMap = new MinHeapMap <GraphVertexWithDistance>(allVertices.Count); ParentBacktrack = new Dictionary <int, int>(); FinalDistance = new Dictionary <int, int>(); foreach (GraphVertex gv in allVertices) { if (gv == source) { DistanceHeapMap.Insert(new GraphVertexWithDistance(gv, 0)); } else { DistanceHeapMap.Insert(new GraphVertexWithDistance(gv)); } } while (DistanceHeapMap.Count != 0) { GraphVertexWithDistance currentVertex = DistanceHeapMap.ExtractMin(); FinalDistance[currentVertex.Id] = currentVertex.Distance; if (currentVertex.Id == destination.Id) { // we have reached the destination return(BacktrackToGetPath(currentVertex.Id, 0)); } foreach (KeyValuePair <GraphVertex, int> edge in currentVertex.NeighbouringEdgesWithWeight) { if (DistanceHeapMap.AllEntities.ContainsKey(edge.Key.Id)) { GraphVertexWithDistance endVertex = DistanceHeapMap.AllEntities[edge.Key.Id]; if (endVertex.Distance > currentVertex.Distance + edge.Value) { GraphVertexWithDistance gvClone = endVertex.ShallowClone(); gvClone.Distance = currentVertex.Distance + edge.Value; ParentBacktrack[endVertex.Id] = currentVertex.Id; DistanceHeapMap.ChangePriority(endVertex, gvClone); } } } } // we do not have a path from source to destination return(null); }