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;
            }
        }
示例#8
0
        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;
 }
示例#10
0
        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);
        }
示例#11
0
 public void insert(FibNode node)
 {
     count++;
     InsertNode(node);
 }
示例#12
0
        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);
        }