21 package org.matsim.core.router.priorityqueue;
23 import java.util.ConcurrentModificationException;
24 import java.util.Iterator;
25 import java.util.NoSuchElementException;
87 static final int defaultFanout = 6;
90 this(maxSize, defaultFanout,
false);
93 public BinaryMinHeap(
int maxSize,
int fanout,
boolean classicalRemove) {
97 this.data = (E[])
new HasIndex[maxSize];
99 this.costs =
new double[maxSize];
100 for (
int i = 0; i < costs.length; i++) {
101 costs[i] = Double.MAX_VALUE;
104 this.indices =
new int[maxSize];
105 for (
int i = 0; i < indices.length; i++) {
122 if (heapSize < indices.length / 10) {
123 for (
int i = 0; i <
heapSize; i++) {
124 indices[this.
getIndex(data[i])] = -1;
127 for (
int i = 0; i < indices.length; i++) {
132 for (
int i = 0; i <
heapSize; i++) {
133 costs[i] = Double.MAX_VALUE;
163 if (classicalRemove) {
164 data[0] = data[heapSize - 1];
165 costs[0] = costs[heapSize - 1];
166 indices[this.
getIndex(data[0])] = 0;
167 indices[this.
getIndex(minValue)] = -1;
174 indices[this.
getIndex(minValue)] = -1;
187 siftUp(index, data[heapSize], costs[heapSize]);
200 if (leftChildIndex >= heapSize)
break;
202 double leftCosts = costs[leftChildIndex];
204 int limitChildIndex = Math.min(leftChildIndex + fanout, heapSize);
206 for (
int rightChildIndex = leftChildIndex + 1; rightChildIndex < limitChildIndex; rightChildIndex++) {
211 double rightCosts = costs[rightChildIndex];
212 if (leftCosts >= rightCosts &&
213 (leftCosts > rightCosts || this.
getIndex(data[leftChildIndex]) > this.
getIndex(data[rightChildIndex]))) {
214 leftChildIndex = rightChildIndex;
215 leftCosts = rightCosts;
219 copyData(nodeIndex, leftChildIndex);
220 nodeIndex = leftChildIndex;
243 return (heapSize == 0);
255 public boolean add(E value,
double priority) {
258 throw new NullPointerException(
"null values are not supported!");
262 if (indices[this.
getIndex(value)] >= 0) {
265 if (heapSize == data.length)
throw new RuntimeException(
"Heap's underlying storage is overflow!");
268 siftUp(heapSize, value, priority);
282 public boolean remove(E value) {
284 if (value == null)
return false;
290 int index = indices[this.
getIndex(value)];
294 if (classicalRemove) {
296 boolean decreasedKey =
decreaseKey(value, Double.NEGATIVE_INFINITY);
297 if (decreasedKey && data[0] == value) {
323 int index = indices[this.
getIndex(value)];
325 return this.
add(value, cost);
332 double oldCost = costs[index];
333 if (oldCost < cost)
return false;
336 siftUp(index, value, cost);
350 return new ArrayIterator(data, heapSize);
353 private void copyData(
int indexTarget,
int indexSource) {
355 E entry = data[indexSource];
356 data[indexTarget] = entry;
359 costs[indexTarget] = costs[indexSource];
362 indices[this.
getIndex(entry)] = indexTarget;
366 return fanout * nodeIndex + 1;
370 return (nodeIndex - 1) /
fanout;
373 private void siftUp(
int index, E newEntry,
double newCost) {
376 double parentCost = costs[parentIndex];
377 if (newCost > parentCost)
break;
378 if (newCost == parentCost && this.
getIndex(newEntry) > this.
getIndex(data[parentIndex]))
break;
385 data[index] = newEntry;
386 costs[index] = newCost;
387 indices[this.
getIndex(newEntry)] = index;
393 if (leftChildIndex >= heapSize)
return;
396 double minCosts = Double.POSITIVE_INFINITY;
398 int limitChildIndex = Math.min(leftChildIndex + fanout, heapSize + 1);
400 for (
int childIndex = leftChildIndex; childIndex < limitChildIndex; childIndex++) {
405 double childCosts = costs[childIndex];
406 if (childCosts <= minCosts) {
407 if (childCosts < minCosts || this.
getIndex(data[childIndex]) < this.
getIndex(data[minIndex])) {
408 minIndex = childIndex;
409 minCosts = childCosts;
423 E entry1 = data[index1];
424 E entry2 = data[index2];
425 data[index1] = entry2;
426 data[index2] = entry1;
429 double tmpCost = costs[index1];
430 costs[index1] = costs[index2];
431 costs[index2] = tmpCost;
434 indices[this.
getIndex(entry1)] = index2;
435 indices[this.
getIndex(entry2)] = index1;
457 return (heapSize > index);
463 if (!
hasNext())
throw new NoSuchElementException();
464 final E value = array[
index];
470 public void remove() {
471 throw new UnsupportedOperationException(
"Not supported operation!");
475 if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int getLeftChildIndex(int nodeIndex)
void swapData(int index1, int index2)
ArrayIterator(final E[] array, int heapSize)
boolean add(E value, double priority)
BinaryMinHeap(int maxSize)
int getParentIndex(int nodeIndex)
final int expectedModCount
void checkForComodification()
void siftDown(int nodeIndex)
int removeSiftDown(int nodeIndex)
boolean decreaseKey(E value, double cost)
void copyData(int indexTarget, int indexSource)
void siftDownUp(int index)
final boolean classicalRemove
int getIndex(HasIndex value)
void siftUp(int index, E newEntry, double newCost)
BinaryMinHeap(int maxSize, int fanout, boolean classicalRemove)