public void RemoveChild(FibNode node) { if (node.parent != this) { Console.WriteLine("Cannot remove child from a node that is not its parent"); } if (node.IsSingle()) { if (child != node) { Console.WriteLine("Cannot remove a node that is not a child"); } child = null; } else { if (child == node) { child = node.next; } node.Remove(); } node.parent = null; node.mark = false; degree--; }
public FibNode(int key, Node value) { this.key = key; this.value = value; degree = 0; mark = false; parent = child = null; previous = next = this; }
public void Merge(FibonacciHeap heap) { minNode.Insert(heap.minNode); if (minNode == null || heap.minNode != null && heap.minNode.key < minNode.key) { minNode = heap.minNode; } count += heap.count; }
public void Insert(FibNode node) { if (node == null) { return; } next.previous = node.previous; node.previous.next = next; next = node; node.previous = this; }
public void AddChild(FibNode node) { if (child == null) { child = node; } else { child.Insert(node); } node.parent = this; node.mark = false; degree++; }
public void InsertNode(FibNode node) { if (minNode == null) { minNode = node; } else { minNode.Insert(node); if (node.key < minNode.key) { minNode = node; } } }
public void DecreaseKey(FibNode node, int newKey) { if (newKey > node.key) { Console.WriteLine("Cant decrease a key to a greater value"); } else if (newKey == node.key) { return; } node.key = newKey; FibNode parent = node.parent; if (parent == null) { if (newKey < minNode.key) { minNode = node; } return; } if (parent.key <= newKey) { return; } while (true) { parent.RemoveChild(node); InsertNode(node); if (parent.parent == null) { break; } if (parent.mark == false) { break; } node = parent; parent = parent.parent; } }
public List <Node> Solve(Maze maze) { int width = maze.width; int total = maze.width * maze.height; var start = maze.GetStart(); var startPos = start.Position(); var end = maze.GetEnd(); var endPos = end.Position(); bool[] visited = new bool[total]; Node[] prev = new Node[total]; var infinity = float.PositiveInfinity; float[] distances = new float[total]; var unvisited = new FibPQ(); FibNode[] nodeIndex = new FibNode[total]; for (var i = 0; i < total; i++) { visited[i] = false; distances[i] = infinity; } distances[start.Position().Y *width + start.Position().X] = 0; var startNode = new FibNode(0, start); nodeIndex[start.Position().Y *width + start.Position().X] = startNode; unvisited.insert(startNode); completed = false; while (unvisited.len() > 0) { var n = unvisited.RemoveMinimum(); var u = n.value; var uPos = u.Position(); var uPosIndex = uPos.Y * width + uPos.X; if (distances[uPosIndex] == infinity) { break; } if (uPos == endPos) { completed = true; break; } foreach (var v in u.neighbours) { if (v != null) { var vPos = v.Position(); var vPosIndex = vPos.Y * width + vPos.X; if (visited[vPosIndex] == false) { var d = (vPos.Y - uPos.Y) + (vPos.X - uPos.X); var newDistance = distances[uPosIndex] + d; var remaining = (vPos.Y - endPos.Y) + (vPos.X - endPos.X); if (newDistance < distances[vPosIndex]) { var vNode = nodeIndex[vPosIndex]; if (vNode == null) { vNode = new FibNode((int)newDistance + remaining, v); unvisited.insert(vNode); nodeIndex[vPosIndex] = vNode; distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } else { unvisited.decreaseKey(vNode, (int)newDistance + remaining); distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } } } } } visited[uPosIndex] = true; } List <Node> path = new List <Node>(); Node current = end; path.Add(current); while (current != null) { path = DirectionFactory.AppendLeft(path, current); current = prev[current.Position().Y *width + current.Position().X]; } return(path); }
//Removes the Node from the heap and set the previous and next nodes to eachother public void Remove() { previous.next = next; next.previous = previous; next = previous = this; }
public FibNode RemoveMinimum() { if (minNode == null) { Console.WriteLine("Boi I can't remove from an empty heap"); } else { FibNode removeNode = minNode; count--; //Assign all old root children as new roots if (minNode.child != null) { FibNode c = minNode.child; while (true) { c.parent = null; c = c.next; if (c == minNode.child) { break; } } minNode.child = null; minNode.Insert(c); } //Check if the last key has been removed if (minNode.next == minNode) { if (count != 0) { //Expected 0 keys } minNode = null; return(removeNode); } int logsize = 100; FibNode[] degreeRoots = new FibNode[logsize]; maxDegree = 0; FibNode currentPointer = minNode.next; while (true) { int currentDegree = currentPointer.degree; FibNode current = currentPointer; currentPointer = currentPointer.next; while (degreeRoots[currentDegree] != null) { FibNode other = degreeRoots[currentDegree]; if (current.key > other.key) { FibNode temp = other; other = current; current = temp; } other.Remove(); current.AddChild(other); degreeRoots[currentDegree] = null; currentDegree++; } degreeRoots[currentDegree] = current; if (currentPointer == minNode) { break; } } //Remove current root and find new minnode minNode = null; var newMaxDegree = 0; for (int d = 0; d < logsize; d++) { if (degreeRoots[d] != null) { degreeRoots[d].next = degreeRoots[d].previous = degreeRoots[d]; InsertNode(degreeRoots[d]); if (d > newMaxDegree) { newMaxDegree = d; } } } maxDegree = newMaxDegree; return(removeNode); } return(null); }
public void insert(FibNode node) { count++; InsertNode(node); }
public List <Node> Solve() { var width = maze.width; var total = maze.width * maze.height; var start = maze.GetStart(); var end = maze.GetEnd(); var endPos = end.Position(); bool[] visited = new bool[total]; Node[] prev = new Node[total]; var infinity = float.PositiveInfinity; float[] distances = new float[total]; FibNode[] nodeIndex = new FibNode[total]; for (var i = 0; i < total; i++) { visited[i] = false; distances[i] = infinity; } var unvisited = new FibPQ(); distances[start.Position().Y *width + start.Position().X] = 0; FibNode startNode = new FibNode(0, start); nodeIndex[start.Position().Y *width + start.Position().X] = startNode; unvisited.insert(startNode); int count = 0; completed = false; while (unvisited.len() > 0) { count += 1; FibNode n = unvisited.RemoveMinimum(); // Node u = n.value; Point uPos = u.Position(); int uPosIndex = uPos.Y * width + uPos.X; if (distances[uPosIndex] == infinity) { break; } if (uPos == endPos) { completed = true; break; } foreach (var v in u.neighbours) { if (v != null) { Point vPos = v.Position(); int vPosIndex = vPos.Y * width + vPos.X; if (visited[vPosIndex] == false) { int d = (vPos.Y - uPos.Y) + (vPos.X - uPos.X); int newDistance = (int)distances[uPosIndex] + d; if (newDistance < distances[vPosIndex]) { var vNode = nodeIndex[vPosIndex]; //v isn't alread in the queue - add it if (vNode == null) { vNode = new FibNode(newDistance, v); unvisited.insert(vNode); nodeIndex[vPosIndex] = vNode; distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } //v is already in the queue - decrease it's key else { unvisited.decreaseKey(vNode, newDistance); distances[vPosIndex] = newDistance; prev[vPosIndex] = u; } } } } } visited[uPosIndex] = true; } //Recontruct the path. List <Node> path = new List <Node>(); Node current = end; path.Add(current); while (current != null) { path = DirectionFactory.AppendLeft(path, current); current = prev[current.Position().Y *width + current.Position().X]; } return(path); }