Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RoutePlanning/HeuristicLab.Algorithms.GraphRouting/3.3/PriorityQueues/FibonacciHeap.cs @ 11733

Last change on this file since 11733 was 8640, checked in by spimming, 12 years ago

#1894:

  • Included costCalculator in a star search
  • restructured and renamed Dijkstra algorithm
  • Added code comments to FibonacciHeap
File size: 4.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using HeuristicLab.Algorithms.GraphRouting.Interfaces;
4
5namespace HeuristicLab.Algorithms.GraphRouting.PriorityQueues {
6  public sealed class FibonacciHeap<K, V> : IHeap<K, V>
7    where K : IComparable
8    where V : IComparable {
9
10    private HeapNode min;
11    private int size;
12
13    public int Size {
14      get { return size; }
15    }
16
17    public FibonacciHeap() {
18      size = 0;
19      min = null;
20    }
21
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
30    public K PeekMinKey() {
31      if (size == 0) {
32        throw new InvalidOperationException("Heap is empty");
33      }
34      return min.Key;
35    }
36
37    public V PeekMinValue() {
38      if (size == 0) {
39        throw new InvalidOperationException("Heap is empty");
40      }
41      return min.Value;
42    }
43
44    public void Insert(K key, V value) {
45      HeapNode n = new HeapNode(key, value);
46      if (min == null) {
47        min = n;
48      } else {
49        // concateneate the root list (becoming left sibling of root)
50        n.Right = min;
51        n.Left = min.Left;
52        n.Right.Left = n;
53        n.Left.Right = n;
54        // update point of minimum if necessary
55        if (n.Key.CompareTo(min.Key) < 0) {
56          min = n;
57        }
58      }
59      size++;
60    }
61
62    public void DecreaseKey(K key, V value) {
63      throw new NotImplementedException();
64    }
65
66    public void RemoveMin() {
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;
104    }
105
106    private void Link(HeapNode y, HeapNode z) {
107      // remove y from the root list
108      y.Left.Right = y.Right;
109      y.Right.Left = y.Left;
110
111      // make y a child of x, ...
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      }
123
124      // ... incrementing degree[x]
125      z.Degree++;
126      y.Mark = false;
127    }
128
129    private void Consolidate() {
130      int dn = (int)Math.Floor(Math.Log(size) / Math.Log(2)) + 1; // log2size[Heap]
131      HeapNode[] A = new HeapNode[dn];  // consolidation array
132      HeapNode start = min;
133      HeapNode w = min;
134
135      // for each node w in the root list
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
166      // find the new minimum key
167      for (int i = 0; i < dn; i++) {
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    }
202  }
203}
Note: See TracBrowser for help on using the repository browser.