예제 #1
0
        private static DijkstraResult dijkstra(int startingIndex, List <PointF> points, List <HashSet <int> > connections, PriorityQueueFactory.QueueType type)
        {
            //start timer to see how long dijkstra's takes
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            List <int>    prev = new List <int>();
            List <double> dist = new List <double>();

            //O(|v|)
            foreach (PointF point in points)
            {
                //set all initial values to MaxValue for distances since we can't set it to infinity
                dist.Add(Double.MaxValue);
                //set all initial values to -1 for previous since we can't set it to infinity
                prev.Add(-1);
            }
            dist[startingIndex] = 0;
            //create the queue This factory allows for creating a queue, and initializes the queue with the distances.
            //O depends on type of queue
            IPriorityQueue queue = PriorityQueueFactory.makeQueue(type, dist);

            //while the queue is not empty we still have work to do
            //O depends on type of queue
            while (!queue.isEmpty())
            {
                //we need to pop the minimum off of the queue and process it.
                //O depends on type of queue
                int current = queue.deletemin();
                //iterate through connections and store the distances if shorter than previously recorded
                foreach (int index in connections[current])
                {
                    double distance = dist[current] + distanceBetweenPoints(points[current], points[index]);
                    if (dist[index] > distance)
                    {
                        dist[index] = distance;
                        prev[index] = current;
                        //update the queue
                        //O depends on type of queue
                        queue.decreaseKey(index, distance);
                    }
                }
            }
            stopwatch.Stop();
            //return the list of distances and previous, and the time it took
            return(new DijkstraResult(prev, dist, stopwatch.Elapsed.TotalSeconds));
        }
예제 #2
0
        //returns a list of point indexs to the inputed list of points, representing the path from the endIndex to the startIndex
        public static List<int> run(List<HashSet<int>> adjList, List<PointF> pointList, int startIndex, int endIndex, IPriorityQueue pQueue)
        {
            //            Console.WriteLine("dijkstra::run::start");

            List<int> reversePathIndex = new List<int>();

            double[] dist = new double[pointList.Count];
            int[] prev = new int[pointList.Count];

            //for each point (i) in pointList, set dist[i] equal to infinity, and prev[i] to null
            for (int i = 0; i < pointList.Count; i++)
            {
                dist[i] = double.MaxValue;
                prev[i] = -1;
            }

            //the distance from the starting point to the starting point is 0, duh.
            dist[startIndex] = 0;

            //Build priorityQueue (pQueue), using distance values as keys
            pQueue.makeQueue(dist);

            //while pQueue is not empty
            while (pQueue.getSize() != 0)
            {
            //                Console.Write("PQUEUE.SIZE: " + pQueue.getSize());
                //remove the smallest entry in the pQueue, store in minIndex
                int minIndex = pQueue.deleteMin();
            //                Console.WriteLine(" minIndex: " + minIndex + " dist.length: " + dist.Length + " prev.length: " + prev.Length + " adjList.Count: " + adjList.Count);
                //for each element (adjPoint) in the adjList for index (minIndex)
                foreach (int adjPoint in adjList[minIndex])
                {
                    double newDist = dist[minIndex] + distBetweenPoints(pointList[minIndex], pointList[adjPoint]);
            //                    Console.WriteLine("minIndex: " + minIndex + " - adjIndex: " + adjPoint + " - dist[adjPoint]: " + dist[adjPoint] + " - newDist: " + newDist);
                    //if dist[adjPoint] > dist[minIndex] + length(minIdex, adjPoint)
                    if (dist[adjPoint] > newDist)
                    {
                        dist[adjPoint] = newDist;
                        prev[adjPoint] = minIndex;
                        pQueue.decreaseKey(adjPoint, newDist);
                    }
                }
            //                Console.WriteLine();
            }

            //if the endIndex does not have a previous node
            //            Console.WriteLine("prev.length:" + prev.Length + " - endIndex: " + endIndex);
            if(prev[endIndex] == -1)
            {
                //then there is no path to the endIndex
            //                Console.WriteLine("dijkstra::run::end::null");

            //                for(int i = 0; i < prev.Length; i++)
            //                {
            //                    Console.WriteLine("[" + i + "] - " + dist[i] + " : " + prev[i]);
            //                }

                return null;
            }
            else
            {
            //                Console.WriteLine("dijkstra::run::end::reversePath");
                //back trace from the endIndex to the startIndex, generating a return list in the process
                int currentIndex = endIndex;

                while (currentIndex != startIndex)
                {
            //                    Console.WriteLine("dijkstra::run::end::reversePath::currentIndex: " + currentIndex);
                    reversePathIndex.Add(currentIndex);
                    currentIndex = prev[currentIndex];
                }
                reversePathIndex.Add(startIndex);

            //                Console.WriteLine("dijkstra::run::end::path");
                return reversePathIndex;
            }
        }