Free cookie consent management tool by TermsFeed Policy Generator

source: branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/PriorityQueue.cs @ 14414

Last change on this file since 14414 was 14414, checked in by bwerth, 7 years ago

#2700 forgot to add files

File size: 6.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25
26namespace HeuristicLab.Algorithms.DataAnalysis {
27
28  // Code Taken from branch: RoutePlanning, Heap4
29  // implementation based on C++ version from Peter Sanders
30  // http://www.mpi-inf.mpg.de/~sanders/programs/spq/
31  public sealed class PriorityQueue<TK, TV> : IHeap<TK, TV> where TK : IComparable {
32    private class KNElement {
33      public TK Key { get; set; }
34      public TV Value { get; set; }
35    }
36
37    private int capacity;
38    private int size; // index of last used element
39    private int finalLayerSize; // size of first layer with free space
40    private int finalLayerDist; // distance to end of layer
41                                //private KNElement[] rawData;
42    private KNElement[] data;    // alligned version of rawData
43
44    public PriorityQueue(TK supremum, TK infimum, int cap) {
45      capacity = cap;
46      data = Enumerable.Range(0, capacity + 4).Select(x => new KNElement()).ToArray();
47
48      data[0].Key = infimum; // sentinel
49      data[capacity + 1].Key = supremum;
50      data[capacity + 2].Key = supremum;
51      data[capacity + 3].Key = supremum;
52      Reset();
53    }
54
55    public int Size
56    {
57      get { return size; }
58    }
59
60    public TK Supremum
61    {
62      get { return data[capacity + 1].Key; }
63    }
64
65    public KeyValuePair<TK, TV> PeekMin() {
66      if (size == 0) {
67        throw new InvalidOperationException("Heap is empty");
68      }
69      return new KeyValuePair<TK, TV>(data[1].Key, data[1].Value);
70    }
71
72    public TK PeekMinKey() {
73      return data[1].Key;
74    }
75
76    public TV PeekMinValue() {
77      return data[1].Value;
78    }
79
80    public void RemoveMin() {
81      // first move up elements on a min-path
82      var hole = 1;
83      var succ = 2;
84      var layerSize = 4;
85      var layerPos = 0;
86      var sz = size;
87      size = sz - 1;
88      finalLayerDist++;
89      if (finalLayerDist == finalLayerSize) {
90        finalLayerSize >>= 2;
91        finalLayerDist = 0;
92      }
93
94      while (succ < sz) {
95        var minKey = data[succ].Key;
96        var delta = 0;
97
98        var otherKey = data[succ + 1].Key;
99        if (otherKey.CompareTo(minKey) < 0) {
100          minKey = otherKey;
101          delta = 1;
102        }
103        otherKey = data[succ + 2].Key;
104        if (otherKey.CompareTo(minKey) < 0) {
105          minKey = otherKey;
106          delta = 2;
107        }
108        otherKey = data[succ + 3].Key;
109        if (otherKey.CompareTo(minKey) < 0) {
110          minKey = otherKey;
111          delta = 3;
112        }
113        succ += delta;
114        layerPos += delta;
115
116        // move min successor up
117        data[hole].Key = minKey;
118        data[hole].Value = data[succ].Value;
119
120        // step to next layer
121        hole = succ;
122        succ = succ - layerPos + layerSize; // beginning of next layer
123        layerPos <<= 2;
124        succ += layerPos; // now correct value
125        layerSize <<= 2;
126      }
127
128      // bubble up rightmost element
129      var bubble = data[sz].Key;
130      layerSize >>= 2; // now size of hole's layer
131      layerPos >>= 2; // now pos of hole within its layer
132
133      var layerDist = layerSize - layerPos - 1; // hole's dist to end of layer
134      var pred = hole + layerDist - layerSize; // end of pred's layer for now
135      layerSize >>= 2; // now size of pred's layer
136      layerDist >>= 2; // now pred's pos in layer
137      pred = pred - layerDist; // finally preds index
138
139      while (data[pred].Key.CompareTo(bubble) > 0) {  // must terminate since inf at root
140        data[hole].Key = data[pred].Key;
141        data[hole].Value = data[pred].Value;
142        hole = pred;
143        pred = hole + layerDist - layerSize; // end of hole's layer for now
144        layerSize >>= 2;
145        layerDist >>= 2;
146        pred = pred - layerDist; // finally preds index
147      }
148
149      // finally move data to hole
150      data[hole].Key = bubble;
151      data[hole].Value = data[sz].Value;
152
153      data[sz].Key = Supremum; // mark as deleted
154    }
155
156    public void Insert(TK key, TV value) {
157      var layerSize = finalLayerSize;
158      var layerDist = finalLayerDist;
159      finalLayerDist--;
160
161      if (finalLayerDist == -1) { // layer full
162                                  // start next layer
163        finalLayerSize <<= 2;
164        finalLayerDist = finalLayerSize - 1;
165      }
166
167      size++;
168
169      var hole = size;
170      var pred = hole + layerDist - layerSize; // end of pred's layer for now
171      layerSize >>= 2; // now size of pred's layer
172      layerDist >>= 2;
173      pred = pred - layerDist; // finally preds index
174      var predKey = data[pred].Key;
175      while (predKey.CompareTo(key) > 0) {
176        data[hole].Key = predKey;
177        data[hole].Value = data[pred].Value;
178        hole = pred;
179        pred = hole + layerDist - layerSize; // end of pred's layer for now
180        layerSize >>= 2; // now isze of pred's layer
181        layerDist >>= 2;
182        pred = pred - layerDist; // finally preds index
183        predKey = data[pred].Key;
184      }
185
186      // finally move data to hole
187      data[hole].Key = key;
188      data[hole].Value = value;
189    }
190
191    // reset size to 0 and fill data array with sentinels
192    private void Reset() {
193      size = 0;
194      finalLayerSize = 1;
195      finalLayerDist = 0;
196      var sup = Supremum;
197      var cap = capacity;
198      for (var i = 1; i <= cap; i++) {
199        data[i].Key = sup;
200      }
201    }
202  }
203}
Note: See TracBrowser for help on using the repository browser.