Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RoutePlanning/HeuristicLab.Algorithms.GraphRouting/3.3/PriorityQueues/BinomialHeap.cs @ 16100

Last change on this file since 16100 was 8527, checked in by spimming, 12 years ago

#1894:

  • introduced heap interface
  • various heap implementation used as priority queues
  • very simple logger added
  • various versions of Astar algorithm
File size: 6.0 KB
Line 
1
2using System;
3using System.Collections.Generic;
4using HeuristicLab.Algorithms.GraphRouting.Interfaces;
5namespace HeuristicLab.Algorithms.GraphRouting.PriorityQueues {
6  public sealed class BinomialHeap<K, V> : IHeap<K, V>
7    where K : IComparable
8    where V : IComparable {
9    private HeapElement<K, V> head;
10    private int size;
11    private Dictionary<V, HeapElement<K, V>> elems;
12
13    public BinomialHeap() {
14      this.elems = new Dictionary<V, HeapElement<K, V>>();
15    }
16
17    public BinomialHeap(HeapElement<K, V> elem, int size) {
18      this.head = elem;
19      this.size = size;
20      this.elems = new Dictionary<V, HeapElement<K, V>>();
21    }
22
23    public int Size {
24      get { return size; }
25    }
26
27    public void Insert(K key, V value) {
28      HeapElement<K, V> elem = new HeapElement<K, V>(key, value);
29      elems.Add(elem.Value, elem);
30      BinomialHeap<K, V> heap = new BinomialHeap<K, V>(elem, 1);
31      heap = Union(heap, this);
32      head = heap.head;
33      size++;
34    }
35
36    public KeyValuePair<K, V> PeekMin() {
37      if (size == 0) {
38        throw new InvalidOperationException("Heap is empty");
39      }
40      HeapElement<K, V> elem = PeekMinElem();
41      return new KeyValuePair<K, V>(elem.Key, elem.Value);
42    }
43
44    public K PeekMinKey() {
45      if (size == 0) {
46        throw new InvalidOperationException("Heap is empty");
47      }
48      return PeekMinElem().Key;
49    }
50
51    public V PeekMinValue() {
52      if (size == 0) {
53        throw new InvalidOperationException("Heap is empty");
54      }
55      return PeekMinElem().Value;
56    }
57
58    public void DecreaseKey(K key, V value) {
59      HeapElement<K, V> elem = elems[value];
60      elem.Key = key;
61      HeapElement<K, V> y = elem;
62      HeapElement<K, V> z = y.Parent;
63
64      V tempVal;
65      K tempKey;
66      while ((z != null) && (y.Key.CompareTo(z.Key) < 0)) {
67        tempVal = y.Value;
68        tempKey = y.Key;
69
70        y.Value = z.Value;
71        y.Key = z.Key;
72
73        z.Value = tempVal;
74        z.Key = tempKey;
75
76        y = z;
77        z = y.Parent;
78      }
79    }
80
81    public void RemoveMin() {
82      if (size == 0) {
83        throw new InvalidOperationException("Heap is empty");
84      }
85
86      HeapElement<K, V> x = head;
87      HeapElement<K, V> y = x.Sibling;
88      HeapElement<K, V> pred = x;
89      HeapElement<K, V> xPrev = null;
90
91      while (y != null) {
92        if (y.Key.CompareTo(x.Key) < 0) {
93          x = y;
94          xPrev = pred;
95        }
96        pred = y;
97        y = y.Sibling;
98      }
99
100      if (x == head) {
101        head = x.Sibling;
102      } else {
103        xPrev.Sibling = x.Sibling;
104      }
105
106      BinomialHeap<K, V> h = new BinomialHeap<K, V>();
107
108      HeapElement<K, V> z = x.Child;
109      while (z != null) {
110        HeapElement<K, V> next = z.Sibling;
111        z.Sibling = h.head;
112        h.head = z;
113        z = next;
114      }
115
116      BinomialHeap<K, V> newH = Union(this, h);
117      head = newH.head;
118
119      elems.Remove(x.Value);
120      size--;
121    }
122
123    private HeapElement<K, V> Merge(BinomialHeap<K, V> heap1, BinomialHeap<K, V> heap2) {
124      if (heap1.head == null) {
125        return heap2.head;
126      } else if (heap2.head == null) {
127        return heap1.head;
128      }
129
130      HeapElement<K, V> head;
131      HeapElement<K, V> tail;
132      HeapElement<K, V> h1Next = heap1.head;
133      HeapElement<K, V> h2Next = heap2.head;
134
135      if (heap1.head.Degree <= heap2.head.Degree) {
136        head = heap1.head;
137        h1Next = h1Next.Sibling;
138      } else {
139        head = heap2.head;
140        h2Next = h2Next.Sibling;
141      }
142
143      tail = head;
144
145      while (h1Next != null && h2Next != null) {
146        if (h1Next.Degree <= h2Next.Degree) {
147          tail.Sibling = h1Next;
148          h1Next = h1Next.Sibling;
149        } else {
150          tail.Sibling = h2Next;
151          h2Next = h2Next.Sibling;
152        }
153        tail = tail.Sibling;
154      }
155
156      if (h1Next != null) {
157        tail.Sibling = h1Next;
158      } else {
159        tail.Sibling = h2Next;
160      }
161
162      return head;
163    }
164
165    private BinomialHeap<K, V> Union(BinomialHeap<K, V> h1, BinomialHeap<K, V> h2) {
166      HeapElement<K, V> elem = Merge(h1, h2);
167      BinomialHeap<K, V> h = new BinomialHeap<K, V>(elem, 0);
168      if (h.head == null) {
169        return h;
170      }
171      h.size = h1.size + h2.size;
172
173      HeapElement<K, V> xPrev = null;
174      HeapElement<K, V> x = h.head;
175      HeapElement<K, V> xNext = x.Sibling;
176
177      while (xNext != null) {
178        if ((x.Degree != xNext.Degree) || (xNext.Sibling != null && xNext.Sibling.Degree == x.Degree)) {
179          xPrev = x;
180          x = xNext;
181        } else {
182          if (x.Key.CompareTo(xNext.Key) <= 0) {
183            x.Sibling = xNext.Sibling;
184            Link(xNext, x);
185          } else {
186            if (xPrev == null) {
187              h.head = xNext;
188            } else {
189              xPrev.Sibling = xNext;
190            }
191            Link(x, xNext);
192            x = xNext;
193          }
194        }
195        xNext = x.Sibling;
196      }
197      return h;
198    }
199
200    private void Link(HeapElement<K, V> y, HeapElement<K, V> z) {
201      y.Parent = z;
202      y.Sibling = z.Child;
203      z.Child = y;
204      z.Degree = z.Degree + 1;
205    }
206
207    private HeapElement<K, V> PeekMinElem() {
208      HeapElement<K, V> min = head;
209      HeapElement<K, V> next = min.Sibling;
210      while (next != null) {
211        if (min.Key.CompareTo(next.Key) > 0) {
212          min = next;
213        }
214        next = next.Sibling;
215      }
216      return min;
217    }
218
219  }
220  public class HeapElement<K, V> {
221    public K Key;
222    public V Value;
223    public int Degree;
224    public HeapElement<K, V> Parent;
225    public HeapElement<K, V> Child;
226    public HeapElement<K, V> Sibling;
227
228    public HeapElement(K key, V value) {
229      this.Key = key;
230      this.Value = value;
231      this.Parent = null;
232      this.Child = null;
233      this.Sibling = null;
234      this.Degree = 0;
235    }
236  }
237}
Note: See TracBrowser for help on using the repository browser.