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)); }
//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; } }