public List <PointF> solve() { // This is the solving function. // Over all we have O(|V|log|V|+|V|log|V|+|E|log|V|) which // reduces to O((E+V)log|V|). List <PointF> shortest = new List <PointF>(); List <data> queue = new List <data>(); List <double> distances = new List <double>(); List <int> possible = new List <int>(); data[] match = new data[points.Count]; // Make queue step. Takes O(|V|log(|V|)) because insert takes // O(log|V|) and we are inserting |V| nodes. for (int i = 0; i < points.Count; i++) // O(|V|) { possible.Add(i); if (i == startNodeIndex) { distances.Add(0); data temp = new data(points[i], 0, i, i); match[i] = temp; insert(ref queue, ref temp); // O(log|V|) } else { distances.Add(double.MaxValue); data temp = new data(points[i], double.MaxValue, i, i); match[i] = temp; insert(ref queue, ref temp); // O(log|V|) } } while (queue.Count > 0) { // This while loop takes O(|V|) because we pop one node off // the queue at a time. data u = deletemin(ref queue); // O(log|V|) possible[u.original] = -1; foreach (int v in adjacencyList[u.original]) { // This step can take at worst O(|E|). if (possible[v] == -1) { continue; } double e_dist = eucl_dist(points[v], u.point); if (distances[v] > u.dist + e_dist) { int i_v = match[v].location; if (i_v < 0) { continue; } queue[i_v].dist = u.dist + e_dist; distances[v] = u.dist + e_dist; if (final.ContainsKey(queue[i_v].point)) { final[queue[i_v].point] = u.point; } else { final.Add(queue[i_v].point, u.point); } decrease_key(ref queue, i_v); // O(log|V|) } } } try { PointF start = points[stopNodeIndex]; PointF end = final[points[stopNodeIndex]]; shortest.Add(start); shortest.Add(end); while (end.X != points[startNodeIndex].X && end.Y != points[startNodeIndex].Y) { start = end; end = final[start]; shortest.Add(end); } } catch (KeyNotFoundException e) { return(new List <PointF>()); } return(shortest); }
public data deletemin(ref List <data> queue) { // This function allows user to delete minimum from dinary heap. // Time complecity is a order of O(log|V|). // This is proven by the fact that a binary heap bubbles down // a value from a heap which is only log|V| deap. if (queue.Count <= 1) { data temp = queue[0]; queue.RemoveAt(0); return(temp); } data min = queue[0]; data last = queue[queue.Count - 1]; queue.RemoveAt(queue.Count - 1); queue[0] = last; queue[0].location = 0; int index = 1; int index_n; while (true) { if ((2 * index) - 1 >= queue.Count) { break; } data child; data left = queue[(2 * index) - 1]; if ((2 * index + 1) - 1 >= queue.Count) { child = left; index_n = 2 * index; } else { data right = queue[(2 * index + 1) - 1]; if (left.dist <= right.dist) { child = left; index_n = 2 * index; } else { child = right; index_n = 2 * index + 1; } } if (child.dist < queue[index - 1].dist) { data temp = queue[index_n - 1]; queue[index_n - 1] = queue[index - 1]; queue[index - 1] = temp; queue[index - 1].location = index - 1; queue[index_n - 1].location = index_n - 1; index = index_n; } else { break; } } return(min); }