예제 #1
0
        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);
        }
예제 #2
0
        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);
        }