2018-08-05 03:19:32 +00:00
|
|
|
package baritone.bot.pathing.calc.openset;
|
2018-08-03 20:31:33 +00:00
|
|
|
|
|
|
|
import baritone.bot.pathing.calc.PathNode;
|
2018-08-03 15:45:11 +00:00
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
|
|
|
public class BinaryHeapOpenSet implements IOpenSet {
|
2018-08-03 20:31:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The initial capacity of the heap (2^10)
|
|
|
|
*/
|
2018-08-03 15:45:11 +00:00
|
|
|
private static final int INITIAL_CAPACITY = 1024;
|
2018-08-03 20:31:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The array backing the heap
|
|
|
|
*/
|
2018-08-03 15:45:11 +00:00
|
|
|
private PathNode[] array;
|
2018-08-03 20:31:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The size of the heap
|
|
|
|
*/
|
2018-08-03 15:45:11 +00:00
|
|
|
private int size;
|
|
|
|
|
|
|
|
public BinaryHeapOpenSet() {
|
|
|
|
this(INITIAL_CAPACITY);
|
|
|
|
}
|
|
|
|
|
|
|
|
public BinaryHeapOpenSet(int size) {
|
|
|
|
this.size = 0;
|
|
|
|
this.array = new PathNode[size];
|
|
|
|
}
|
|
|
|
|
2018-08-03 20:31:33 +00:00
|
|
|
@Override
|
2018-08-03 15:45:11 +00:00
|
|
|
public void insert(PathNode value) {
|
|
|
|
if (size >= array.length - 1) {
|
|
|
|
array = Arrays.copyOf(array, array.length * 2);
|
|
|
|
}
|
|
|
|
size++;
|
|
|
|
int index = size;
|
2018-08-05 15:30:50 +00:00
|
|
|
value.heapPosition = index;
|
2018-08-03 15:45:11 +00:00
|
|
|
array[index] = value;
|
2018-08-05 15:30:50 +00:00
|
|
|
upHeap(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void update(PathNode node) {
|
|
|
|
upHeap(node.heapPosition);
|
2018-08-03 15:45:11 +00:00
|
|
|
}
|
|
|
|
|
2018-08-03 20:31:33 +00:00
|
|
|
@Override
|
2018-08-03 15:45:11 +00:00
|
|
|
public boolean isEmpty() {
|
|
|
|
return size == 0;
|
|
|
|
}
|
|
|
|
|
2018-08-03 20:31:33 +00:00
|
|
|
@Override
|
2018-08-03 15:45:11 +00:00
|
|
|
public PathNode removeLowest() {
|
|
|
|
if (size == 0) {
|
|
|
|
throw new IllegalStateException();
|
|
|
|
}
|
|
|
|
PathNode result = array[1];
|
|
|
|
array[1] = array[size];
|
2018-08-05 15:30:50 +00:00
|
|
|
array[1].heapPosition = 1;
|
2018-08-03 15:45:11 +00:00
|
|
|
array[size] = null;
|
|
|
|
size--;
|
2018-08-05 15:30:50 +00:00
|
|
|
downHeap(1);
|
|
|
|
result.heapPosition = -1;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void upHeap(int index) {
|
|
|
|
int parent = index >>> 1;
|
|
|
|
while (index > 1 && array[parent].combinedCost > array[index].combinedCost) {
|
|
|
|
swap(index, parent);
|
|
|
|
index = parent;
|
|
|
|
parent = index >>> 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void downHeap(int index) {
|
2018-08-03 15:45:11 +00:00
|
|
|
int smallerChild = 2;
|
|
|
|
while (smallerChild <= size) {
|
|
|
|
int right = smallerChild + 1;
|
|
|
|
if (right <= size && array[smallerChild].combinedCost > array[right].combinedCost) {
|
|
|
|
smallerChild = right;
|
|
|
|
}
|
2018-08-05 15:30:50 +00:00
|
|
|
if (array[index].combinedCost <= array[smallerChild].combinedCost) {
|
2018-08-03 15:45:11 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-08-05 15:30:50 +00:00
|
|
|
swap(index, smallerChild);
|
2018-08-03 15:45:11 +00:00
|
|
|
index = smallerChild;
|
|
|
|
smallerChild = index << 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-03 20:31:33 +00:00
|
|
|
/**
|
|
|
|
* Swaps the elements at the specified indices.
|
|
|
|
*
|
|
|
|
* @param index1 The first index
|
|
|
|
* @param index2 The second index
|
|
|
|
*/
|
2018-08-03 15:45:11 +00:00
|
|
|
protected void swap(int index1, int index2) {
|
2018-08-05 15:30:50 +00:00
|
|
|
//sanity checks, disabled because of performance hit
|
|
|
|
//if (array[index1].heapPosition != index1) throw new IllegalStateException();
|
|
|
|
//if (array[index2].heapPosition != index2) throw new IllegalStateException();
|
2018-08-03 15:45:11 +00:00
|
|
|
PathNode tmp = array[index1];
|
|
|
|
array[index1] = array[index2];
|
|
|
|
array[index2] = tmp;
|
2018-08-05 15:30:50 +00:00
|
|
|
tmp.heapPosition = index2;
|
|
|
|
array[index1].heapPosition = index1;
|
2018-08-03 15:45:11 +00:00
|
|
|
}
|
2018-08-05 15:30:50 +00:00
|
|
|
|
2018-08-03 15:45:11 +00:00
|
|
|
}
|