public Graph GetTree()
        {
            // initialize the graph that will hold the MST
            Graph mst = new KevinGraph();

            // initialize the priority queue that will hold the vertices outside the MST
            PriorityQueue remainingVertices = new KevinPriorityQueue();

            foreach (GraphVertex v in weightedGraph.GetAllVertices())
            {
                remainingVertices.Enqueue(new MSTPriorityQueueNode(data: v, priority: int.MaxValue));
            }

            Dictionary <string, GraphEdge> lowestCostEdgeForVertex = new Dictionary <string, GraphEdge>();

            while (remainingVertices.Count() > 0)
            {
                // Get the vertex with the lowest code to add to the MST
                // The first vertex is chosen arbitrarily because all vertices start with max cost.
                PriorityQueueNode currentNode   = remainingVertices.Dequeue();
                GraphVertex       currentVertex = currentNode.Data as GraphVertex;

                // Add the vertex and its lowest cost edge (if any) to the MST
                mst.AddVertex(currentVertex.UniqueKey);
                if (lowestCostEdgeForVertex.ContainsKey(currentVertex.UniqueKey))
                {
                    GraphEdge lowestCostEdge = lowestCostEdgeForVertex[currentVertex.UniqueKey];
                    // TO-DO: why?
                    mst.AddEdge(lowestCostEdge.SourceVertexUniqueKey, lowestCostEdge.TargetVertexUniqueKey, lowestCostEdge.Weight);
                    mst.AddEdge(lowestCostEdge.TargetVertexUniqueKey, lowestCostEdge.SourceVertexUniqueKey, lowestCostEdge.Weight);
                }

                // update the minimum cost for each adjacent vertex, and the associated edge
                foreach (GraphEdge edge in currentVertex.GetIncidentEdges())
                {
                    GraphVertex edgeTarget = weightedGraph.GetVertexByUniqueKey(edge.TargetVertexUniqueKey);

                    if (!remainingVertices.Contains(edgeTarget.UniqueKey))
                    {
                        continue;
                    }

                    int newCost = edge.Weight;
                    PriorityQueueNode targetNode = remainingVertices.Peek(edgeTarget.UniqueKey);
                    if (newCost < targetNode.Priority)
                    {
                        remainingVertices.ChangePriority(targetNode.Data.UniqueKey, newCost);
                        lowestCostEdgeForVertex[edgeTarget.UniqueKey] = edge;
                    }
                }
            }

            return(mst);
        }
Exemple #2
0
        public List <GraphVertex> FindShortestPath(
            string startVertexUniqueKey,
            string targetVertexUniqueKey)
        {
            GraphVertex startVertex  = weightedGraph.GetVertexByUniqueKey(startVertexUniqueKey);
            GraphVertex targetVertex = weightedGraph.GetVertexByUniqueKey(targetVertexUniqueKey);

            // initialize the 'prev' data structure that will hold the path
            Dictionary <string, GraphVertex> prev = new Dictionary <string, GraphVertex>();

            // initialize the priority queue
            PriorityQueue remainingVertices = new KevinPriorityQueue();

            foreach (GraphVertex v in weightedGraph.GetAllVertices())
            {
                int totalPathWeightThroughCurrentVertex = v.UniqueKey == startVertex.UniqueKey ?
                                                          0 :
                                                          int.MaxValue;
                remainingVertices.Enqueue(
                    new ShortestPathPriorityQueueNode(data: v, priority: totalPathWeightThroughCurrentVertex));
            }

            while (remainingVertices.Count() > 0)
            {
                PriorityQueueNode currentNode   = remainingVertices.Dequeue();
                GraphVertex       currentVertex = currentNode.Data as GraphVertex;

                foreach (GraphEdge edge in currentVertex.GetIncidentEdges())
                {
                    GraphVertex edgeTarget = weightedGraph.GetVertexByUniqueKey(edge.TargetVertexUniqueKey);

                    if (!remainingVertices.Contains(edgeTarget.UniqueKey))
                    {
                        continue;
                    }

                    int newDist = currentNode.Priority + edge.Weight;
                    PriorityQueueNode targetNode = remainingVertices.Peek(edgeTarget.UniqueKey);
                    if (newDist < targetNode.Priority)
                    {
                        remainingVertices.ChangePriority(targetNode.Data.UniqueKey, newDist);
                        prev[edgeTarget.UniqueKey] = currentVertex;
                    }
                }

                if (currentVertex.UniqueKey == targetVertex.UniqueKey)
                {
                    break;
                }
            }

            return(BuildPath(prev, startVertexUniqueKey, targetVertexUniqueKey));
        }