Switch from sorted array to minheap

This commit is contained in:
Ian Gulliver
2019-07-07 22:28:38 +00:00
parent 39a3d20e73
commit 975f40b1c4
3 changed files with 74 additions and 10 deletions

View File

@@ -31,7 +31,6 @@ class LayoutLink {
bfs() {
// TODO: give more thought to birdirectional search
// TODO: give more thought to minheap instead of queue
// TODO: make diagonals cost more
// TODO: remove getDirect() once bidirectional + minheap are done
@@ -43,17 +42,15 @@ class LayoutLink {
this.path = direct[1];
// BFS work queue
let queue = [
{
path: [Array.from(this.from_.pos)],
cost: 0,
},
];
let queue = new MinHeap((a) => a.cost);
queue.push({
path: [Array.from(this.from_.pos)],
cost: 0,
});
let iter = 0;
while (queue.length) {
for (let next = queue.pop(); next; next = queue.pop()) {
++iter;
let next = queue.shift();
let pos = next.path[next.path.length - 1];
if (cheapestCostToGoal && next.cost >= cheapestCostToGoal) {
@@ -113,7 +110,6 @@ class LayoutLink {
});
}
}
queue.sort((a, b) => (a.cost - b.cost));
}
for (let hop of this.path) {

67
MinHeap.js Normal file
View File

@@ -0,0 +1,67 @@
class MinHeap {
constructor(valueFunc=(a) => a) {
this.valueFunc_ = valueFunc;
this.data_ = [];
}
push(...vals) {
for (let val of vals) {
this.data_.push(val);
this.bubbleUp_();
}
}
pop() {
let min = this.data_[0];
if (this.data_.length > 1) {
this.data_[0] = this.data_.pop();
this.bubbleDown_();
} else {
this.data_.length = 0;
}
return min;
}
bubbleUp_() {
for (let idx = this.data_.length - 1; idx > 0;) {
let parent = Math.floor((idx + 1) / 2) - 1;
if (this.valueFunc_(this.data_[parent]) >
this.valueFunc_(this.data_[idx])) {
[this.data_[parent], this.data_[idx]] =
[this.data_[idx], this.data_[parent]];
}
idx = parent;
}
}
bubbleDown_() {
for (let idx = 0;;) {
let children = [
(idx + 1) * 2,
(idx + 1) * 2 - 1,
];
let toSwap = idx;
// Find the minimum value of the current node and its two children
for (let child of children) {
if (this.data_[child] != undefined &&
this.valueFunc_(this.data_[child]) <
this.valueFunc_(this.data_[toSwap])) {
toSwap = child;
}
}
if (toSwap == idx) {
// Current node is smaller than both children; tree is correct
break;
}
[this.data_[toSwap], this.data_[idx]] =
[this.data_[idx], this.data_[toSwap]];
idx = toSwap;
}
}
};

View File

@@ -25,4 +25,5 @@ function intersects(set1, set2) {
return false;
}
<!--# include file="MinHeap.js" -->
<!--# include file="StringMap.js" -->