/// <summary> /// Makes newChild a child of Node newParent. /// O(1) /// </summary> protected void Link(FibonacciHeapNode <T, TKey> newChild, FibonacciHeapNode <T, TKey> newParent) { // remove newChild from root list of heap newChild.Left.Right = newChild.Right; newChild.Right.Left = newChild.Left; // make newChild a child of newParent newChild.Parent = newParent; if (newParent.Child == null) { newParent.Child = newChild; newChild.Right = newChild; newChild.Left = newChild; } else { newChild.Left = newParent.Child; newChild.Right = newParent.Child.Right; newParent.Child.Right = newChild; newChild.Right.Left = newChild; } // increase degree[newParent] newParent.Degree++; // set mark[newChild] false newChild.Mark = false; }
/// <summary> /// The reverse of the link operation: removes newParent from the child list of newChild. /// This method assumes that min is non-null. /// Running time: O(1) /// </summary> protected void Cut(FibonacciHeapNode <T, TKey> x, FibonacciHeapNode <T, TKey> y) { // remove newParent from childlist of newChild and decrement degree[newChild] x.Left.Right = x.Right; x.Right.Left = x.Left; y.Degree--; // reset newChild.child if necessary if (y.Child == x) { y.Child = x.Right; } if (y.Degree == 0) { y.Child = null; } // add newParent to root list of heap x.Left = _minNode; x.Right = _minNode.Right; _minNode.Right = x; x.Right.Left = x; // set parent[newParent] to nil x.Parent = null; // set mark[newParent] to false x.Mark = false; }
/// <summary> /// Deletes a node from the heap. /// O(log n) /// </summary> public void Delete(FibonacciHeapNode <T, TKey> x) { // make newParent as small as possible DecreaseKey(x, _minKeyValue); // remove the smallest, which decreases n also RemoveMin(); }
/// <summary> /// Removes the smalles node of the heap. /// O(log n) amortized /// </summary> /// <returns></returns> public FibonacciHeapNode <T, TKey> RemoveMin() { FibonacciHeapNode <T, TKey> minNode = _minNode; if (minNode != null) { int numKids = minNode.Degree; FibonacciHeapNode <T, TKey> oldMinChild = minNode.Child; // for each child of minNode do... while (numKids > 0) { FibonacciHeapNode <T, TKey> tempRight = oldMinChild.Right; // remove oldMinChild from child list oldMinChild.Left.Right = oldMinChild.Right; oldMinChild.Right.Left = oldMinChild.Left; // add oldMinChild to root list of heap oldMinChild.Left = _minNode; oldMinChild.Right = _minNode.Right; _minNode.Right = oldMinChild; oldMinChild.Right.Left = oldMinChild; // set parent[oldMinChild] to null oldMinChild.Parent = null; oldMinChild = tempRight; numKids--; } // remove minNode from root list of heap minNode.Left.Right = minNode.Right; minNode.Right.Left = minNode.Left; if (minNode == minNode.Right) { _minNode = null; } else { _minNode = minNode.Right; Consolidate(); } // decrement size of heap _nNodes--; } return(minNode); }
/// <summary> /// Decreses the key of a node. /// O(1) amortized. /// </summary> public void DecreaseKey(FibonacciHeapNode <T, TKey> x, TKey k) { if (k.CompareTo(x.Key) > 0) { throw new ArgumentException("decreaseKey() got larger key value"); } x.Key = k; FibonacciHeapNode <T, TKey> y = x.Parent; if ((y != null) && (x.Key.CompareTo(y.Key) < 0)) { Cut(x, y); CascadingCut(y); } if (x.Key.CompareTo(_minNode.Key) < 0) { _minNode = x; } }
/// <summary> /// Performs a cascading cut operation. This cuts newChild from its parent and then /// does the same for its parent, and so on up the tree. /// </summary> protected void CascadingCut(FibonacciHeapNode <T, TKey> y) { FibonacciHeapNode <T, TKey> z = y.Parent; // if there's a parent... if (z != null) { // if newChild is unmarked, set it marked if (!y.Mark) { y.Mark = true; } else { // it's marked, cut it from parent Cut(y, z); // cut its parent as well CascadingCut(z); } } }
/// <summary> /// Inserts a new node with its key. /// O(1) /// </summary> public void Insert(FibonacciHeapNode <T, TKey> node) { // concatenate node into min list if (_minNode != null) { node.Left = _minNode; node.Right = _minNode.Right; _minNode.Right = node; node.Right.Left = node; if (node.Key.CompareTo(_minNode.Key) < 0) { _minNode = node; } } else { _minNode = node; } _nNodes++; }
/// <summary> /// calculate The shortest time to move from the source to the destination. /// O(E+Vlog(V)) /// </summary> /// <param name="rf"></param> /// <param name="File_name"></param> /// <returns></minimum time ,total distance , walking distance and vechicel distance> public string Dijkstra(read_Write_files rf, string File_name, int src, int dest) { arr_node = new int[rf.num_of_vertices + 1]; arr_directions = new char[rf.num_of_vertices + 1]; path = new List <int>(); directions = new List <char>(); for (int i = 1; i < arr_node.Length; i++) { arr_node[i] = -1; arr_directions[i] = ' '; } Dis_arr_fib = new double[rf.num_of_vertices + 1]; int vert; char dir; FibonacciHeap <KeyValuePair <int, char>, double> fb = new FibonacciHeap <KeyValuePair <int, char>, double>(0); for (long i = 1; i <= rf.num_of_vertices; i++) { if (i == src) { Dis_arr_fib[i] = 0; } else { Dis_arr_fib[i] = double.MaxValue; } } FibonacciHeapNode <KeyValuePair <int, char>, double> x = new FibonacciHeapNode <KeyValuePair <int, char>, double>(new KeyValuePair <int, char>(src, ' '), 0); fb.Insert(x); FibonacciHeapNode <KeyValuePair <int, char>, double> u = new FibonacciHeapNode <KeyValuePair <int, char>, double>(new KeyValuePair <int, char>(0, ' '), 0); bool flag = false; dis = new double[rf.num_of_vertices + 1]; while (!fb.IsEmpty()) { u = fb.Min(); vert = u.Data.Key; dir = u.Data.Value; foreach (Tuple <KeyValuePair <int, char>, double> nep in adj_List[Convert.ToInt32(vert)]) { FibonacciHeapNode <KeyValuePair <int, char>, double> vertex = new FibonacciHeapNode <KeyValuePair <int, char>, double>(new KeyValuePair <int, char>(0, ' '), 0); if (Dis_arr_fib[vert] + nep.Item2 < Dis_arr_fib[nep.Item1.Key]) { Dis_arr_fib[nep.Item1.Key] = Dis_arr_fib[vert] + nep.Item2; vertex.Key = Dis_arr_fib[nep.Item1.Key]; vertex.Data = new KeyValuePair <int, char>(nep.Item1.Key, nep.Item1.Value); //O(1) arr_node[nep.Item1.Key] = vert; dis[nep.Item1.Key] = nep.Item2; arr_directions[vert] = dir; fb.Insert(vertex); } } if (u.Data.Key == dest) { flag = true; } if (flag) { arr_directions[vert] = dir; break; } //O(log(v)) fb.RemoveMin(); } //O(v) int k = dest; path.Add(dest); List <double> path_dis = new List <double>(); path_dis.Add(dis[k]); do { int node = arr_node[k]; double dista = dis[node]; path_dis.Add(dista); path.Add(node); k = node; } while (k != src); for (int i = 0; i < path.Count; i++) { char dire = arr_directions[path[i]]; directions.Add(dire); } Console.WriteLine(); string final_path = rf.Write_output(File_name, Dis_arr_fib[dest], path_dis, directions); return(final_path); }
/// <summary> /// Removes all the elements from the heap. /// </summary> public void Clear() { _minNode = null; _nNodes = 0; }
protected void Consolidate() { int arraySize = ((int)Math.Floor(Math.Log(_nNodes) * OneOverLogPhi)) + 1; var array = new List <FibonacciHeapNode <T, TKey> >(arraySize); // Initialize degree array for (var i = 0; i < arraySize; i++) { array.Add(null); } // Find the number of root nodes. var numRoots = 0; FibonacciHeapNode <T, TKey> x = _minNode; if (x != null) { numRoots++; x = x.Right; while (x != _minNode) { numRoots++; x = x.Right; } } // For each node in root list do... while (numRoots > 0) { // Access this node's degree.. int d = x.Degree; FibonacciHeapNode <T, TKey> next = x.Right; // ..and see if there's another of the same degree. for (; ;) { FibonacciHeapNode <T, TKey> y = array[d]; if (y == null) { // Nope. break; } // There is, make one of the nodes a child of the other. // Do this based on the key value. if (x.Key.CompareTo(y.Key) > 0) { FibonacciHeapNode <T, TKey> temp = y; y = x; x = temp; } // FibonacciHeapNode<T> newChild disappears from root list. Link(y, x); // We've handled this degree, go to next one. array[d] = null; d++; } // Save this node for later when we might encounter another // of the same degree. array[d] = x; // Move forward through list. x = next; numRoots--; } // Set min to null (effectively losing the root list) and // reconstruct the root list from the array entries in array[]. _minNode = null; for (var i = 0; i < arraySize; i++) { FibonacciHeapNode <T, TKey> y = array[i]; if (y == null) { continue; } // We've got a live one, add it to root list. if (_minNode != null) { // First remove node from root list. y.Left.Right = y.Right; y.Right.Left = y.Left; // Now add to root list, again. y.Left = _minNode; y.Right = _minNode.Right; _minNode.Right = y; y.Right.Left = y; // Check if this is a new min. if (y.Key.CompareTo(_minNode.Key) < 0) { _minNode = y; } } else { _minNode = y; } } }