forked from RepoMirrors/baritone
Compare commits
1 Commits
master
...
binary-hea
Author | SHA1 | Date |
---|---|---|
Leijurv | 59e0d6406e |
|
@ -72,6 +72,7 @@ public final class BinaryHeapOpenSet implements IOpenSet {
|
||||||
int index = val.heapPosition;
|
int index = val.heapPosition;
|
||||||
int parentInd = index >>> 1;
|
int parentInd = index >>> 1;
|
||||||
double cost = val.combinedCost;
|
double cost = val.combinedCost;
|
||||||
|
PathNode[] array = this.array;
|
||||||
PathNode parentNode = array[parentInd];
|
PathNode parentNode = array[parentInd];
|
||||||
while (index > 1 && parentNode.combinedCost > cost) {
|
while (index > 1 && parentNode.combinedCost > cost) {
|
||||||
array[index] = parentNode;
|
array[index] = parentNode;
|
||||||
|
@ -94,40 +95,50 @@ public final class BinaryHeapOpenSet implements IOpenSet {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
PathNode[] array = this.array;
|
||||||
PathNode result = array[1];
|
PathNode result = array[1];
|
||||||
PathNode val = array[size];
|
PathNode val = array[size];
|
||||||
array[1] = val;
|
array[1] = val;
|
||||||
val.heapPosition = 1;
|
val.heapPosition = 1;
|
||||||
array[size] = null;
|
array[size] = null;
|
||||||
size--;
|
int size = --this.size;
|
||||||
result.heapPosition = -1;
|
result.heapPosition = -1;
|
||||||
if (size < 2) {
|
if (size < 2) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
int index = 1;
|
int index = 1;
|
||||||
int smallerChild = 2;
|
int smallerChild = 1;
|
||||||
double cost = val.combinedCost;
|
double cost = val.combinedCost;
|
||||||
do {
|
while ((smallerChild <<= 1) < size) {
|
||||||
PathNode smallerChildNode = array[smallerChild];
|
PathNode smallerChildNode = array[smallerChild];
|
||||||
|
PathNode otherChildNode = array[smallerChild + 1];
|
||||||
double smallerChildCost = smallerChildNode.combinedCost;
|
double smallerChildCost = smallerChildNode.combinedCost;
|
||||||
if (smallerChild < size) {
|
double rightChildCost = otherChildNode.combinedCost;
|
||||||
PathNode rightChildNode = array[smallerChild + 1];
|
if (smallerChildCost > rightChildCost) {
|
||||||
double rightChildCost = rightChildNode.combinedCost;
|
smallerChild++;
|
||||||
if (smallerChildCost > rightChildCost) {
|
smallerChildCost = rightChildCost;
|
||||||
smallerChild++;
|
smallerChildNode = otherChildNode;
|
||||||
smallerChildCost = rightChildCost;
|
|
||||||
smallerChildNode = rightChildNode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (cost <= smallerChildCost) {
|
if (cost <= smallerChildCost) {
|
||||||
break;
|
return result;
|
||||||
}
|
}
|
||||||
array[index] = smallerChildNode;
|
array[index] = smallerChildNode;
|
||||||
array[smallerChild] = val;
|
array[smallerChild] = val;
|
||||||
val.heapPosition = smallerChild;
|
val.heapPosition = smallerChild;
|
||||||
smallerChildNode.heapPosition = index;
|
smallerChildNode.heapPosition = index;
|
||||||
index = smallerChild;
|
index = smallerChild;
|
||||||
} while ((smallerChild <<= 1) <= size);
|
}
|
||||||
|
// if we get here, then smallerChild >= size
|
||||||
|
// one last swap to check
|
||||||
|
if (smallerChild == size) {
|
||||||
|
PathNode onlyChildNode = array[smallerChild];
|
||||||
|
if (cost > onlyChildNode.combinedCost) {
|
||||||
|
array[index] = onlyChildNode;
|
||||||
|
array[smallerChild] = val;
|
||||||
|
val.heapPosition = smallerChild;
|
||||||
|
onlyChildNode.heapPosition = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,24 +36,39 @@ public class OpenSetsTest {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final ArrayList<Long> insertions = new ArrayList<>();
|
||||||
|
private static final ArrayList<Long> removal1 = new ArrayList<>();
|
||||||
|
private static final ArrayList<Long> removal2 = new ArrayList<>();
|
||||||
|
|
||||||
@Parameterized.Parameters
|
@Parameterized.Parameters
|
||||||
public static Collection<Object[]> data() {
|
public static Collection<Object[]> data() {
|
||||||
ArrayList<Object[]> testSizes = new ArrayList<>();
|
ArrayList<Object[]> testSizes = new ArrayList<>();
|
||||||
for (int size = 1; size < 20; size++) {
|
/*for (int size = 1; size < 20; size++) {
|
||||||
testSizes.add(new Object[]{size});
|
testSizes.add(new Object[]{size});
|
||||||
}
|
}
|
||||||
for (int size = 100; size <= 1000; size += 100) {
|
for (int size = 100; size <= 1000; size += 100) {
|
||||||
testSizes.add(new Object[]{size});
|
testSizes.add(new Object[]{size});
|
||||||
}
|
}
|
||||||
testSizes.add(new Object[]{5000});
|
testSizes.add(new Object[]{5000});
|
||||||
testSizes.add(new Object[]{10000});
|
testSizes.add(new Object[]{10000});*/
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
|
testSizes.add(new Object[]{100000});
|
||||||
return testSizes;
|
return testSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void removeAndTest(int amount, IOpenSet[] test, Optional<Collection<PathNode>> mustContain) {
|
private static void removeAndTest(int amount, IOpenSet[] test, Optional<Collection<PathNode>> mustContain) {
|
||||||
double[][] results = new double[test.length][amount];
|
double[][] results = new double[test.length][amount];
|
||||||
for (int i = 0; i < test.length; i++) {
|
for (int i = 0; i < test.length; i++) {
|
||||||
long before = System.nanoTime() / 1000000L;
|
long before = System.nanoTime();
|
||||||
for (int j = 0; j < amount; j++) {
|
for (int j = 0; j < amount; j++) {
|
||||||
PathNode pn = test[i].removeLowest();
|
PathNode pn = test[i].removeLowest();
|
||||||
if (mustContain.isPresent() && !mustContain.get().contains(pn)) {
|
if (mustContain.isPresent() && !mustContain.get().contains(pn)) {
|
||||||
|
@ -61,7 +76,13 @@ public class OpenSetsTest {
|
||||||
}
|
}
|
||||||
results[i][j] = pn.combinedCost;
|
results[i][j] = pn.combinedCost;
|
||||||
}
|
}
|
||||||
System.out.println(test[i].getClass() + " " + (System.nanoTime() / 1000000L - before));
|
long time = System.nanoTime() - before;
|
||||||
|
System.out.println(test[i].getClass() + " " + (time));
|
||||||
|
if (mustContain.isPresent()) {
|
||||||
|
removal1.add(time);
|
||||||
|
} else {
|
||||||
|
removal2.add(time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int j = 0; j < amount; j++) {
|
for (int j = 0; j < amount; j++) {
|
||||||
for (int i = 1; i < test.length; i++) {
|
for (int i = 1; i < test.length; i++) {
|
||||||
|
@ -75,10 +96,16 @@ public class OpenSetsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSize() {
|
public void testSize() {
|
||||||
|
try {
|
||||||
|
System.gc();
|
||||||
|
Thread.sleep(1000L);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
System.out.println("Testing size " + size);
|
System.out.println("Testing size " + size);
|
||||||
// Include LinkedListOpenSet even though it's not performant because I absolutely trust that it behaves properly
|
// Include LinkedListOpenSet even though it's not performant because I absolutely trust that it behaves properly
|
||||||
// I'm really testing the heap implementations against it as the ground truth
|
// I'm really testing the heap implementations against it as the ground truth
|
||||||
IOpenSet[] test = new IOpenSet[]{new BinaryHeapOpenSet(), new LinkedListOpenSet()};
|
IOpenSet[] test = new IOpenSet[]{new BinaryHeapOpenSet()/*, new LinkedListOpenSet()*/};
|
||||||
for (IOpenSet set : test) {
|
for (IOpenSet set : test) {
|
||||||
assertTrue(set.isEmpty());
|
assertTrue(set.isEmpty());
|
||||||
}
|
}
|
||||||
|
@ -116,10 +143,12 @@ public class OpenSetsTest {
|
||||||
|
|
||||||
System.out.println("Insertion");
|
System.out.println("Insertion");
|
||||||
for (IOpenSet set : test) {
|
for (IOpenSet set : test) {
|
||||||
long before = System.nanoTime() / 1000000L;
|
long before = System.nanoTime();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
set.insert(toInsert[i]);
|
set.insert(toInsert[i]);
|
||||||
System.out.println(set.getClass() + " " + (System.nanoTime() / 1000000L - before));
|
long time = System.nanoTime() - before;
|
||||||
|
System.out.println(set.getClass() + " " + (time));
|
||||||
|
insertions.add(time);
|
||||||
//all three take either 0 or 1ms to insert up to 10,000 nodes
|
//all three take either 0 or 1ms to insert up to 10,000 nodes
|
||||||
//linkedlist takes 0ms most often (because there's no array resizing or allocation there, just pointer shuffling)
|
//linkedlist takes 0ms most often (because there's no array resizing or allocation there, just pointer shuffling)
|
||||||
}
|
}
|
||||||
|
@ -166,5 +195,18 @@ public class OpenSetsTest {
|
||||||
for (IOpenSet set : test) {
|
for (IOpenSet set : test) {
|
||||||
assertTrue(set.isEmpty());
|
assertTrue(set.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printo(insertions);
|
||||||
|
printo(removal1);
|
||||||
|
printo(removal2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printo(ArrayList<Long> data) {
|
||||||
|
if (data.size() < 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
System.out.println(data.subList(2, data.size()).stream().mapToLong(x -> x).average().getAsDouble() / 1000000D);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue