// O(|v|+|E|) space to hold all of the nodes for the graph, // plus 2*|v| for the previous and distances lists required. // For the heapQ we have O(2*|v|) and for the ArrayQ we have O(|v|), // as explained in their class descriptions. In the end we also return // the path which could worst-case cost O(|v|). // Overall we have O(6*|v| + |E|) in the worst-case. public static Tuple <List <int>, List <double> > run( List <PointF> points, List <HashSet <int> > adjacencyList, int startNode, int stopNode, bool useArray) { List <double> distances = new List <double>(); List <int> prev = new List <int>(); for (int i = 0; i < points.Count; i++) { distances.Add(int.MaxValue); prev.Add(-1); } distances[startNode] = 0; IQueue Q; if (useArray) { Q = new ArrayQ(distances); } else { Q = new HeapQ(distances); } int cur; double dis; HashSet <int> adjs; // this is O(|v| * |v|) for the array and O(|v| * 2log(|v|)) for the heap. // the O(|v|) is common to both because this while loop runs |v| times. // The O(|v|) for the array is due to the Deletemin, and the O(2log(|v|)) // for the heap is because it has two operations that are O(log(|v|)). while ((cur = Q.Deletemin(distances)) != -1) { adjs = adjacencyList[cur]; foreach (int end in adjs) // runs 3 times { dis = distances[cur] + Distance(points[cur], points[end]); if (dis < distances[end]) { distances[end] = dis; prev[end] = cur; Q.Decreasekey(end, distances); // O(1) for ArrayQ and O(log|v|) for HeapQ } } } return(new Tuple <List <int>, List <double> >(PathToEnd(startNode, stopNode, prev), distances)); } // end of run()
public static List <int> run( List <PointF> points, List <HashSet <int> > adjacencyList, int startNode, int stopNode, bool useArray) { List <double> distances = new List <double>(); List <int> prev = new List <int>(); for (int i = 0; i < points.Count; i++) { distances.Add(int.MaxValue); prev.Add(-1); } distances[startNode] = 0; IQueue Q; if (useArray) { Q = new ArrayQ(distances); } else { Q = new HeapQ(distances); } int cur; double dis; HashSet <int> adjs; while ((cur = Q.Deletemin(distances)) != -1) { adjs = adjacencyList[cur]; foreach (int end in adjs) { dis = distances[cur] + Distance(points[cur], points[end]); if (dis < distances[end]) { distances[end] = dis; prev[end] = cur; Q.Decreasekey(end, distances); } } } return(PathToEnd(startNode, stopNode, prev)); } // end of run()
//O(|V|) * (O(OnKeyDecreased) + O(Deletemin)) private void solveButton_Clicked(bool useArray) { //***************** Dijkstra's algorithm: *****************// double[] dist = new double[points.Count]; int[] prev = new int[points.Count]; //O(|V|) for (int i = 0; i < adjacencyList.Count; i++) { dist[i] = Int32.MaxValue; prev[i] = -1; } dist[startNodeIndex] = 0; IPriorityQ pq; if (useArray) { pq = new ArrayQ(); } else { pq = new HeapQ(); } pq.Makequeue(dist); //O(|V|) * (O(OnKeyDecreased) + O(Deletemin)) while (pq.NotEmpty()) { int u = pq.Deletemin(); //O(3) * O(OnKeyDecreased) foreach (int v in adjacencyList.ElementAt(u)) { if (dist[v] > dist[u] + EuclDist(points.ElementAt(u), points.ElementAt(v))) { dist[v] = dist[u] + EuclDist(points.ElementAt(u), points.ElementAt(v)); prev[v] = u; pq.OnKeyDecreased(v); } } } //****************** End Dijkstra's **********************// //Get shortest path from prev. Draw it to screen if (prev[stopNodeIndex] == -1) { displayNoPath(); return; } List <PointF> path = new List <PointF>(); int curr = stopNodeIndex; //O(|V|) while (curr != -1) { path.Add(points.ElementAt(curr)); curr = prev[curr]; } drawPath(path); labelPath(path); }