示例#1
0
        //
        // Performs Dijkstra's shortest path algorithm on the the constructed PathGraph object
        //
        // @param path -- Returns the actual shortest path in the List parameter
        // @return the length of the shortest path via the return value
        //
        public int Dijkstra(List <int> path)
        {
            // Initialize all shortest paths to a node to be large and the shortest path to a start node to be 0
            InitializeSingleSource(int.MaxValue - 100000); // -100000 prevents issues with arithmetic overflow

            //
            // Create the min-Fibonacci Heap by pushing all vertices onto the Heap
            //
            int numV = graph.NumVertices();
            //FibonacciHeap<int> vertices = new FibonacciHeap<int>();
            MinHeap vertices = new MinHeap(numV);

            for (int i = 0; i < numV; i++) // VertexValues node : shortPathEst)
            {
                // Insert the weight, d, which is the short path to node i
                HeapNode <int> node = new HeapNode <int>(i);
                vertices.Insert(node, shortPathEst[i].d);
                shortPathEst[i].heapNode = node; // maintain a pointer to the object for DecreaseKey
            }

            //
            // Visit all vertices in the PathGraph (always visiting the shortest distance from the start node first)
            // Do so by using a Fibonacci Heap
            //
            while (!vertices.IsEmpty())
            {
                //
                // Acquire the minimum: min will contain a pair <shortest distance to node n, node n>
                //
                HeapNode <int> min = vertices.ExtractMin();    // Now, extract the node

                //
                // For each adjacent vertex, relax
                //
                int        nodeIndex = min.data;
                List <int> adjNodes  = graph.AdjacentNodes(nodeIndex);
                foreach (int neighbor in adjNodes)
                {
                    Relax(nodeIndex, neighbor, graph.GetWeight(nodeIndex, neighbor), vertices);
                }
            }

            //
            // Look at predecessors to acquire the actual shortest path
            //
            path.Add(goalNode); // Add the last node

            // Predecessor node
            int predNode = shortPathEst[goalNode].pi;

            // Loop while we have not yet reached the start node
            // If we hit a NIL, a path does not exist
            while (predNode != startNode && predNode != NIL)
            {
                path.Insert(0, predNode); // Insert at the beginning of the List; index 0
                predNode = shortPathEst[predNode].pi;
            }

            // Check if the goal node was even reachable
            if (predNode == NIL)
            {
                path.Clear();
                return(NIL);
            }

            // Insert the first node at the beginning
            path.Insert(0, predNode);

            return(shortPathEst[goalNode].d); // recall .d contains the shortest path length to the goalNode
        }