[8546] | 1 | using System;
|
---|
[8572] | 2 | using System.Collections.Generic;
|
---|
[8546] | 3 | using HeuristicLab.Algorithms.GraphRouting.Interfaces;
|
---|
| 4 |
|
---|
| 5 | namespace HeuristicLab.Algorithms.GraphRouting.PriorityQueues {
|
---|
| 6 | public sealed class FibonacciHeap<K, V> : IHeap<K, V>
|
---|
| 7 | where K : IComparable
|
---|
| 8 | where V : IComparable {
|
---|
| 9 |
|
---|
[8572] | 10 | private HeapNode min;
|
---|
| 11 | private int size;
|
---|
[8546] | 12 |
|
---|
| 13 | public int Size {
|
---|
[8572] | 14 | get { return size; }
|
---|
[8546] | 15 | }
|
---|
| 16 |
|
---|
[8572] | 17 | public FibonacciHeap() {
|
---|
| 18 | size = 0;
|
---|
| 19 | min = null;
|
---|
[8546] | 20 | }
|
---|
| 21 |
|
---|
[8572] | 22 | public KeyValuePair<K, V> PeekMin() {
|
---|
| 23 | if (size == 0) {
|
---|
| 24 | throw new InvalidOperationException("Heap is empty");
|
---|
| 25 | }
|
---|
| 26 | KeyValuePair<K, V> pair = new KeyValuePair<K, V>(min.Key, min.Value);
|
---|
| 27 | return pair;
|
---|
| 28 | }
|
---|
| 29 |
|
---|
[8546] | 30 | public K PeekMinKey() {
|
---|
[8572] | 31 | if (size == 0) {
|
---|
| 32 | throw new InvalidOperationException("Heap is empty");
|
---|
| 33 | }
|
---|
| 34 | return min.Key;
|
---|
[8546] | 35 | }
|
---|
| 36 |
|
---|
| 37 | public V PeekMinValue() {
|
---|
[8572] | 38 | if (size == 0) {
|
---|
| 39 | throw new InvalidOperationException("Heap is empty");
|
---|
| 40 | }
|
---|
| 41 | return min.Value;
|
---|
[8546] | 42 | }
|
---|
| 43 |
|
---|
| 44 | public void Insert(K key, V value) {
|
---|
[8572] | 45 | HeapNode n = new HeapNode(key, value);
|
---|
| 46 | if (min == null) {
|
---|
| 47 | min = n;
|
---|
| 48 | } else {
|
---|
[8640] | 49 | // concateneate the root list (becoming left sibling of root)
|
---|
[8572] | 50 | n.Right = min;
|
---|
| 51 | n.Left = min.Left;
|
---|
| 52 | n.Right.Left = n;
|
---|
| 53 | n.Left.Right = n;
|
---|
[8640] | 54 | // update point of minimum if necessary
|
---|
[8572] | 55 | if (n.Key.CompareTo(min.Key) < 0) {
|
---|
| 56 | min = n;
|
---|
| 57 | }
|
---|
| 58 | }
|
---|
| 59 | size++;
|
---|
[8546] | 60 | }
|
---|
| 61 |
|
---|
| 62 | public void DecreaseKey(K key, V value) {
|
---|
| 63 | throw new NotImplementedException();
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | public void RemoveMin() {
|
---|
[8572] | 67 | if (size == 0) {
|
---|
| 68 | throw new InvalidOperationException("Heap is empty");
|
---|
| 69 | }
|
---|
| 70 | HeapNode z = min;
|
---|
| 71 | if (z.Child != null) {
|
---|
| 72 | // set all z's childs parent to null ...
|
---|
| 73 | z.Child.Parent = null;
|
---|
| 74 | HeapNode x = z.Child.Right;
|
---|
| 75 | while (x != z.Child) {
|
---|
| 76 | x.Parent = null;
|
---|
| 77 | x = x.Right;
|
---|
| 78 | }
|
---|
| 79 | // ... and make all of them roots
|
---|
| 80 | HeapNode minLeft = min.Left;
|
---|
| 81 | min.Left = z.Child.Left;
|
---|
| 82 | min.Left.Right = min;
|
---|
| 83 | z.Child.Left = minLeft;
|
---|
| 84 | minLeft.Right = z.Child;
|
---|
| 85 | }
|
---|
| 86 |
|
---|
| 87 | // remove z frome root list
|
---|
| 88 | z.Left.Right = z.Right;
|
---|
| 89 | z.Right.Left = z.Left;
|
---|
| 90 |
|
---|
| 91 | if (z == z.Right) {
|
---|
| 92 | min = null;
|
---|
| 93 | } else {
|
---|
| 94 | // point min to a node other than z
|
---|
| 95 | // (not necessarily going to be the new minimum)
|
---|
| 96 | min = z.Right;
|
---|
| 97 | Consolidate();
|
---|
| 98 | }
|
---|
| 99 | size--;
|
---|
| 100 |
|
---|
| 101 | //var zNode = new KeyValuePair<K, V>(z.Key, z.Value);
|
---|
| 102 | z = null;
|
---|
| 103 | //return zNode;
|
---|
[8546] | 104 | }
|
---|
[8572] | 105 |
|
---|
| 106 | private void Link(HeapNode y, HeapNode z) {
|
---|
[8640] | 107 | // remove y from the root list
|
---|
[8572] | 108 | y.Left.Right = y.Right;
|
---|
| 109 | y.Right.Left = y.Left;
|
---|
| 110 |
|
---|
[8640] | 111 | // make y a child of x, ...
|
---|
[8572] | 112 | y.Parent = z;
|
---|
| 113 | if (z.Child == null) {
|
---|
| 114 | z.Child = y;
|
---|
| 115 | y.Right = y;
|
---|
| 116 | y.Left = y;
|
---|
| 117 | } else {
|
---|
| 118 | y.Left = z.Child;
|
---|
| 119 | y.Right = z.Child.Right;
|
---|
| 120 | z.Child.Right = y;
|
---|
| 121 | y.Right.Left = y;
|
---|
| 122 | }
|
---|
[8640] | 123 |
|
---|
| 124 | // ... incrementing degree[x]
|
---|
[8572] | 125 | z.Degree++;
|
---|
| 126 | y.Mark = false;
|
---|
| 127 | }
|
---|
| 128 |
|
---|
| 129 | private void Consolidate() {
|
---|
[8640] | 130 | int dn = (int)Math.Floor(Math.Log(size) / Math.Log(2)) + 1; // log2size[Heap]
|
---|
| 131 | HeapNode[] A = new HeapNode[dn]; // consolidation array
|
---|
[8572] | 132 | HeapNode start = min;
|
---|
| 133 | HeapNode w = min;
|
---|
| 134 |
|
---|
[8640] | 135 | // for each node w in the root list
|
---|
[8572] | 136 | do {
|
---|
| 137 | HeapNode x = w;
|
---|
| 138 | HeapNode nextW = w.Right;
|
---|
| 139 | int d = x.Degree;
|
---|
| 140 |
|
---|
| 141 | while (A[d] != null) {
|
---|
| 142 | HeapNode y = A[d]; // another node with the same degree as x
|
---|
| 143 | if (x.Key.CompareTo(y.Key) > 0) {
|
---|
| 144 | // exchange x <-> y
|
---|
| 145 | HeapNode tmp = x;
|
---|
| 146 | x = y;
|
---|
| 147 | y = tmp;
|
---|
| 148 | }
|
---|
| 149 | if (y == start) {
|
---|
| 150 | start = start.Right;
|
---|
| 151 | }
|
---|
| 152 | if (y == nextW) {
|
---|
| 153 | nextW = nextW.Right;
|
---|
| 154 | }
|
---|
| 155 | Link(y, x);
|
---|
| 156 | A[d] = null;
|
---|
| 157 | d++;
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 | A[d] = x;
|
---|
| 161 | w = nextW;
|
---|
| 162 | } while (w != start);
|
---|
| 163 |
|
---|
| 164 | min = null;
|
---|
| 165 |
|
---|
[8640] | 166 | // find the new minimum key
|
---|
| 167 | for (int i = 0; i < dn; i++) {
|
---|
[8572] | 168 | if (A[i] != null) {
|
---|
| 169 | HeapNode n = A[i];
|
---|
| 170 | if (min == null) {
|
---|
| 171 | min = n;
|
---|
| 172 | } else {
|
---|
| 173 | if (n.Key.CompareTo(min.Key) < 0) {
|
---|
| 174 | min = n;
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 | }
|
---|
| 178 | }
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | private class HeapNode {
|
---|
| 182 | public K Key;
|
---|
| 183 | public V Value;
|
---|
| 184 | public int Degree;
|
---|
| 185 | public bool Mark;
|
---|
| 186 | public HeapNode Left;
|
---|
| 187 | public HeapNode Right;
|
---|
| 188 | public HeapNode Parent;
|
---|
| 189 | public HeapNode Child;
|
---|
| 190 |
|
---|
| 191 | public HeapNode(K key, V value) {
|
---|
| 192 | this.Key = key;
|
---|
| 193 | this.Value = value;
|
---|
| 194 | this.Right = this;
|
---|
| 195 | this.Left = this;
|
---|
| 196 | this.Parent = null;
|
---|
| 197 | this.Child = null;
|
---|
| 198 | this.Degree = 0;
|
---|
| 199 | this.Mark = false;
|
---|
| 200 | }
|
---|
| 201 | }
|
---|
[8546] | 202 | }
|
---|
| 203 | }
|
---|