Esempio n. 1
0
 public void removechild(HeapNode node)
 {
     if (node.parent != this)
     {
         throw new Exception("Cannot remove child from node that is not it's parent");
     }
     if (node.issingle())
     {
         if (child != node)
         {
             throw new Exception("Cannot remove node that is not a child");
         }
         child = null;
     }
     else
     {
         if (child == node)
         {
             child = node.next;
         }
         node.remove();
     }
     node.parent = null;
     node.mark   = false;
     degree--;
 }
Esempio n. 2
0
 public void merge(FibHeap heap)
 {
     this.minnode.insert(heap.minnode);
     if (minnode == null || (heap.minnode != null && heap.minnode.key < minnode.key))
     {
         minnode = heap.minnode;
     }
     count += heap.count;
 }
Esempio n. 3
0
 public void insert(HeapNode node)
 {
     if (node != null)
     {
         next.previous      = node.previous;
         node.previous.next = next;
         next          = node;
         node.previous = this;
     }
 }
Esempio n. 4
0
 public void addchild(HeapNode node)
 {
     if (child == null)
     {
         child = node;
     }
     else
     {
         child.insert(node);
     }
     node.parent = this;
     node.mark   = false;
     degree++;
 }
Esempio n. 5
0
 public void _insertnode(HeapNode node)
 {
     if (minnode == null)
     {
         minnode = node;
     }
     else
     {
         minnode.insert(node);
         if (node.key < minnode.key)
         {
             minnode = node;
         }
     }
 }
Esempio n. 6
0
        public void decreasekey(HeapNode node, int newkey)
        {
            if (newkey > node.key)
            {
                throw new Exception("Cannot decrease key to a greater value");
            }
            else if (newkey == node.key)
            {
                return;
            }
            node.key = newkey;
            HeapNode parent = node.parent;

            if (parent == null)
            {
                if (newkey < minnode.key)
                {
                    minnode = node;
                }
                return;
            }
            else if (parent.key <= newkey)
            {
                return;
            }
            while (true)
            {
                parent.removechild(node);
                _insertnode(node);
                if (parent.parent == null)
                {
                    break;
                }
                else if (parent.mark == false)
                {
                    parent.mark = true;
                    break;
                }
                else
                {
                    node   = parent;
                    parent = parent.parent;
                    continue;
                }
            }
        }
Esempio n. 7
0
 public void remove()
 {
     previous.next = next;
     next.previous = previous;
     next          = previous = this;
 }
Esempio n. 8
0
 public HeapNode(int key, Node value)
 {
     this.key   = key;
     this.value = value;
     previous   = next = this;
 }
Esempio n. 9
0
        public void removeminimum()
        {
            if (minnode == null)
            {
                throw new Exception("Cannot remove from empty heap");
            }
            count--;
            if (minnode.child != null)
            {
                HeapNode c = minnode.child;
                while (true)
                {
                    c.parent = null;
                    c        = c.next;
                    if (c == minnode.child)
                    {
                        break;
                    }
                }
                minnode.child = null;
                minnode.insert(c);
            }
            if (minnode.next == minnode)
            {
                if (count != 0)
                {
                    throw new Exception("Heap error: Expected 0 keys. Count is " + count);
                }
                minnode = null;
                return;
            }
            int logsize = 100;

            HeapNode[] degreeroots = new HeapNode[logsize];
            maxdegree = 0;
            HeapNode currentpointer = minnode.next;

            while (true)
            {
                int      currentdegree = currentpointer.degree;
                HeapNode current       = currentpointer;
                currentpointer = currentpointer.next;
                while (degreeroots[currentdegree] != null)
                {
                    HeapNode other = degreeroots[currentdegree];
                    if (current.key > other.key)
                    {
                        HeapNode temp = other;
                        other   = current;
                        current = temp;
                    }
                    other.remove();
                    current.addchild(other);
                    degreeroots[currentdegree] = null;
                    currentdegree++;
                }
                degreeroots[currentdegree] = current;
                if (currentpointer == minnode)
                {
                    break;
                }
            }
            minnode = null;
            int newmaxdegree = 0;

            for (int i = 0; i < logsize; i++)
            {
                if (degreeroots[i] != null)
                {
                    degreeroots[i].next = degreeroots[i].previous = degreeroots[i];
                    this._insertnode(degreeroots[i]);
                    if (i > newmaxdegree)
                    {
                        newmaxdegree = i;
                    }
                }
            }
            maxdegree = newmaxdegree;
        }
Esempio n. 10
0
 public void insert(HeapNode node)
 {
     count++;
     this._insertnode(node);
 }
Esempio n. 11
0
        public void solve()
        {
            int total = width * height;

            Node[,] prev = new Node[width, height];
            int infinity = int.MaxValue - 1;

            int[,] distances = new int[width, height];
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    distances[x, y] = infinity;
                }
            }
            FibHeap unvisited = new FibHeap();

            HeapNode[,] nodeindex       = new HeapNode[width, height];
            distances[Start.X, Start.Y] = 0;
            HeapNode startnode = new HeapNode(0, Start);

            nodeindex[Start.X, Start.Y] = startnode;
            unvisited.insert(startnode);
            count = 0;
            while (unvisited.count > 0)
            {
                count++;
                HeapNode n = unvisited.minimum();
                unvisited.removeminimum();
                Node u = n.value;
                if (distances[u.X, u.Y] == infinity)
                {
                    break;
                }
                if (u.X == End.X && u.Y == End.Y)
                {
                    break;
                }
                foreach (Node v in u.neighbors)
                {
                    if (v.X != 0)
                    {
                        if (!visited[v.X, v.Y])
                        {
                            int d           = MathExt.abs(v.X - u.X) + MathExt.abs(v.Y - u.Y);
                            int newdistance = distances[u.X, u.Y] + d;
                            int remaining   = MathExt.abs(v.X - End.X) + MathExt.abs(v.Y - End.Y);
                            if (newdistance < distances[v.X, v.Y])
                            {
                                HeapNode vnode = nodeindex[v.X, v.Y];
                                if (vnode == null)
                                {
                                    vnode = new HeapNode(newdistance + remaining, v);
                                    unvisited.insert(vnode);
                                    nodeindex[v.X, v.Y] = vnode;
                                    distances[v.X, v.Y] = newdistance;
                                    prev[v.X, v.Y]      = u;
                                }
                                else
                                {
                                    unvisited.decreasekey(vnode, newdistance + remaining);
                                    distances[v.X, v.Y] = newdistance;
                                    prev[v.X, v.Y]      = u;
                                }
                            }
                        }
                    }
                }
                visited[u.X, u.Y] = true;
            }
            result = new List <Node>();
            Node current = End;

            while (current.X != 0)
            {
                result.Insert(0, current);
                current = prev[current.X, current.Y];
            }
        }