function biastarPathfind(grid, start, end, allowDiag, heuristicFn) {
const h = heuristicFn || HEURISTICS.manhattan;
const rows = grid.length;
const cols = grid[0].length;
const gA = Matrix(rows, cols, Infinity);
const gB = Matrix(rows, cols, Infinity);
const prevA = new Map();
const prevB = new Map();
const visitedA = new Set();
const visitedB = new Set();
const openA = PriorityQueue("f");
const openB = PriorityQueue("f");
gA[start[0]][start[1]] = 0;
gB[end[0]][end[1]] = 0;
priorityQueuePush(openA, {
f: h(start[0], start[1], end[0], end[1]),
row: start[0],
col: start[1]
});
priorityQueuePush(openB, {
f: h(end[0], end[1], start[0], start[1]),
row: end[0],
col: end[1]
});
let best = Infinity;
let meet = null;
while (priorityQueueSize(openA) || priorityQueueSize(openB)) {
const pickA = !priorityQueueSize(openB) || priorityQueueSize(openA) && priorityQueuePeekValue(openA, "f") <= priorityQueuePeekValue(openB, "f");
const heap = pickA ? openA : openB;
const gTable = pickA ? gA : gB;
const otherG = pickA ? gB : gA;
const visited = pickA ? visitedA : visitedB;
const otherVisited = pickA ? visitedB : visitedA;
const prev = pickA ? prevA : prevB;
const dirTag = pickA ? 'visit-a' : 'visit-b';
const node = heap.pop();
const currentKey = key(node.row, node.col);
if (visited.has(currentKey)) continue;
visited.add(currentKey);
pickA ? visitForwardNode(node.row, node.col) : visitBackwardNode(node.row, node.col);
if (otherVisited.has(currentKey)) {
const total = gTable[node.row][node.col] + otherG[node.row][node.col];
if (total < best) {
best = total;
meet = currentKey;
}
}
if (best < Infinity) {
const minOpen = Math.min(priorityQueuePeekValue(openA, "f", Infinity), priorityQueuePeekValue(openB, "f", Infinity));
if (minOpen >= best) break;
}
for (const [nr, nc] of getNeighbors(grid, node.row, node.col, allowDiag)) {
const tentative = gTable[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc);
if (tentative < gTable[nr][nc]) {
gTable[nr][nc] = tentative;
prev.set(key(nr, nc), [node.row, node.col]);
const f = tentative + h(nr, nc, pickA ? end[0] : start[0], pickA ? end[1] : start[1]);
heap.push({
f,
row: nr,
col: nc
});
pushFrontier(nr, nc);
const meetTotal = tentative + otherG[nr][nc];
if (meetTotal < best) {
best = meetTotal;
meet = key(nr, nc);
}
}
}
}
if (meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
} def biastarPathfind(grid, start, end, allowDiag, heuristicFn):
h = (heuristicFn or HEURISTICS.manhattan)
rows = grid.length
cols = grid[0].length
gA = Matrix(rows, cols, Infinity)
gB = Matrix(rows, cols, Infinity)
prevA = Map()
prevB = Map()
visitedA = Set()
visitedB = Set()
openA = PriorityQueue("f")
openB = PriorityQueue("f")
gA[start[0]][start[1]] = 0
gB[end[0]][end[1]] = 0
priorityQueuePush(openA, {f: h(start[0], start[1], end[0], end[1]), row: start[0], col: start[1]})
priorityQueuePush(openB, {f: h(end[0], end[1], start[0], start[1]), row: end[0], col: end[1]})
best = Infinity
meet = None
while (priorityQueueSize(openA) or priorityQueueSize(openB)):
pickA = (not priorityQueueSize(openB) or (priorityQueueSize(openA) and (priorityQueuePeekValue(openA, "f") <= priorityQueuePeekValue(openB, "f"))))
heap = (openA if pickA else openB)
gTable = (gA if pickA else gB)
otherG = (gB if pickA else gA)
visited = (visitedA if pickA else visitedB)
otherVisited = (visitedB if pickA else visitedA)
prev = (prevA if pickA else prevB)
dirTag = ("visit-a" if pickA else "visit-b")
node = heap.pop()
currentKey = key(node.row, node.col)
if visited.has(currentKey):
continue
visited.add(currentKey)
(visitForwardNode(node.row, node.col) if pickA else visitBackwardNode(node.row, node.col))
if otherVisited.has(currentKey):
total = (gTable[node.row][node.col] + otherG[node.row][node.col])
if (total < best):
best = total
meet = currentKey
if (best < Infinity):
minOpen = min(priorityQueuePeekValue(openA, "f", Infinity), priorityQueuePeekValue(openB, "f", Infinity))
if (minOpen >= best):
break
for nr, nc in getNeighbors(grid, node.row, node.col, allowDiag):
tentative = (gTable[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc))
if (tentative < gTable[nr][nc]):
gTable[nr][nc] = tentative
prev.set(key(nr, nc), [node.row, node.col])
f = (tentative + h(nr, nc, (end[0] if pickA else start[0]), (end[1] if pickA else start[1])))
heap.push({f: f, row: nr, col: nc})
pushFrontier(nr, nc)
meetTotal = (tentative + otherG[nr][nc])
if (meetTotal < best):
best = meetTotal
meet = key(nr, nc)
if meet:
reconstructBidirectionalPath(prevA, prevB, meet, start, end)
else:
reportNoPath() #include <vector>
#include <algorithm>
void biastarPathfind(int grid, int start, int end, int allowDiag, int heuristicFn) {
auto h = (heuristicFn || HEURISTICS.manhattan);
auto rows = grid.length;
auto cols = grid[0].length;
auto gA = Matrix(rows, cols, Infinity);
auto gB = Matrix(rows, cols, Infinity);
auto prevA = Map();
auto prevB = Map();
auto visitedA = Set();
auto visitedB = Set();
auto openA = PriorityQueue("f");
auto openB = PriorityQueue("f");
gA[start[0]][start[1]] = 0;
gB[end[0]][end[1]] = 0;
priorityQueuePush(openA, {f: h(start[0], start[1], end[0], end[1]), row: start[0], col: start[1]});
priorityQueuePush(openB, {f: h(end[0], end[1], start[0], start[1]), row: end[0], col: end[1]});
auto best = Infinity;
auto meet = null;
while((priorityQueueSize(openA) || priorityQueueSize(openB))) {
auto pickA = (!priorityQueueSize(openB) || (priorityQueueSize(openA) && (priorityQueuePeekValue(openA, "f") <= priorityQueuePeekValue(openB, "f"))));
auto heap = ((pickA) ? (openA) : (openB));
auto gTable = ((pickA) ? (gA) : (gB));
auto otherG = ((pickA) ? (gB) : (gA));
auto visited = ((pickA) ? (visitedA) : (visitedB));
auto otherVisited = ((pickA) ? (visitedB) : (visitedA));
auto prev = ((pickA) ? (prevA) : (prevB));
auto dirTag = ((pickA) ? ("visit-a") : ("visit-b"));
auto node = heap.pop();
auto currentKey = key(node.row, node.col);
if(visited.has(currentKey)) {
continue;
}
visited.add(currentKey);
((pickA) ? (visitForwardNode(node.row, node.col)) : (visitBackwardNode(node.row, node.col)));
if(otherVisited.has(currentKey)) {
auto total = (gTable[node.row][node.col] + otherG[node.row][node.col]);
if((total < best)) {
best = total;
meet = currentKey;
}
}
if((best < Infinity)) {
auto minOpen = ((priorityQueuePeekValue(openA, "f", Infinity)) < (priorityQueuePeekValue(openB, "f", Infinity)) ? (priorityQueuePeekValue(openA, "f", Infinity)) : (priorityQueuePeekValue(openB, "f", Infinity)));
if((minOpen >= best)) {
break;
}
}
for(auto& [nr, nc] : getNeighbors(grid, node.row, node.col, allowDiag)) {
auto tentative = (gTable[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc));
if((tentative < gTable[nr][nc])) {
gTable[nr][nc] = tentative;
prev.set(key(nr, nc), [node.row, node.col]);
auto f = (tentative + h(nr, nc, ((pickA) ? (end[0]) : (start[0])), ((pickA) ? (end[1]) : (start[1]))));
heap.push({f: f, row: nr, col: nc});
pushFrontier(nr, nc);
auto meetTotal = (tentative + otherG[nr][nc]);
if((meetTotal < best)) {
best = meetTotal;
meet = key(nr, nc);
}
}
}
}
if(meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
} public void biastarPathfind(int grid, int start, int end, int allowDiag, int heuristicFn) {
var h = (heuristicFn || HEURISTICS.manhattan);
var rows = grid.length;
var cols = grid[0].length;
var gA = Matrix(rows, cols, Infinity);
var gB = Matrix(rows, cols, Infinity);
var prevA = Map();
var prevB = Map();
var visitedA = Set();
var visitedB = Set();
var openA = PriorityQueue("f");
var openB = PriorityQueue("f");
gA[start[0]][start[1]] = 0;
gB[end[0]][end[1]] = 0;
priorityQueuePush(openA, {f: h(start[0], start[1], end[0], end[1]), row: start[0], col: start[1]});
priorityQueuePush(openB, {f: h(end[0], end[1], start[0], start[1]), row: end[0], col: end[1]});
var best = Infinity;
var meet = null;
while((priorityQueueSize(openA) || priorityQueueSize(openB))) {
var pickA = (!priorityQueueSize(openB) || (priorityQueueSize(openA) && (priorityQueuePeekValue(openA, "f") <= priorityQueuePeekValue(openB, "f"))));
var heap = ((pickA) ? (openA) : (openB));
var gTable = ((pickA) ? (gA) : (gB));
var otherG = ((pickA) ? (gB) : (gA));
var visited = ((pickA) ? (visitedA) : (visitedB));
var otherVisited = ((pickA) ? (visitedB) : (visitedA));
var prev = ((pickA) ? (prevA) : (prevB));
var dirTag = ((pickA) ? ("visit-a") : ("visit-b"));
var node = heap.pop();
var currentKey = key(node.row, node.col);
if(visited.has(currentKey)) {
continue;
}
visited.add(currentKey);
((pickA) ? (visitForwardNode(node.row, node.col)) : (visitBackwardNode(node.row, node.col)));
if(otherVisited.has(currentKey)) {
var total = (gTable[node.row][node.col] + otherG[node.row][node.col]);
if((total < best)) {
best = total;
meet = currentKey;
}
}
if((best < Infinity)) {
var minOpen = Math.Min(priorityQueuePeekValue(openA, "f", Infinity), priorityQueuePeekValue(openB, "f", Infinity));
if((minOpen >= best)) {
break;
}
}
foreach(var (nr, nc) in getNeighbors(grid, node.row, node.col, allowDiag)) {
var tentative = (gTable[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc));
if((tentative < gTable[nr][nc])) {
gTable[nr][nc] = tentative;
prev.set(key(nr, nc), [node.row, node.col]);
var f = (tentative + h(nr, nc, ((pickA) ? (end[0]) : (start[0])), ((pickA) ? (end[1]) : (start[1]))));
heap.push({f: f, row: nr, col: nc});
pushFrontier(nr, nc);
var meetTotal = (tentative + otherG[nr][nc]);
if((meetTotal < best)) {
best = meetTotal;
meet = key(nr, nc);
}
}
}
}
if(meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
} #include <stdio.h>
void biastarPathfind(int grid, int start, int end, int allowDiag, int heuristicFn) {
var h = (heuristicFn || HEURISTICS.manhattan);
var rows = grid.length;
var cols = grid[0].length;
var gA = Matrix(rows, cols, Infinity);
var gB = Matrix(rows, cols, Infinity);
var prevA = Map();
var prevB = Map();
var visitedA = Set();
var visitedB = Set();
var openA = PriorityQueue("f");
var openB = PriorityQueue("f");
gA[start[0]][start[1]] = 0;
gB[end[0]][end[1]] = 0;
priorityQueuePush(openA, {f: h(start[0], start[1], end[0], end[1]), row: start[0], col: start[1]});
priorityQueuePush(openB, {f: h(end[0], end[1], start[0], start[1]), row: end[0], col: end[1]});
var best = Infinity;
var meet = null;
while((priorityQueueSize(openA) || priorityQueueSize(openB))) {
var pickA = (!priorityQueueSize(openB) || (priorityQueueSize(openA) && (priorityQueuePeekValue(openA, "f") <= priorityQueuePeekValue(openB, "f"))));
var heap = ((pickA) ? (openA) : (openB));
var gTable = ((pickA) ? (gA) : (gB));
var otherG = ((pickA) ? (gB) : (gA));
var visited = ((pickA) ? (visitedA) : (visitedB));
var otherVisited = ((pickA) ? (visitedB) : (visitedA));
var prev = ((pickA) ? (prevA) : (prevB));
var dirTag = ((pickA) ? ("visit-a") : ("visit-b"));
var node = heap.pop();
var currentKey = key(node.row, node.col);
if(visited.has(currentKey)) {
continue;
}
visited.add(currentKey);
((pickA) ? (visitForwardNode(node.row, node.col)) : (visitBackwardNode(node.row, node.col)));
if(otherVisited.has(currentKey)) {
var total = (gTable[node.row][node.col] + otherG[node.row][node.col]);
if((total < best)) {
best = total;
meet = currentKey;
}
}
if((best < Infinity)) {
var minOpen = ((priorityQueuePeekValue(openA, "f", Infinity)) < (priorityQueuePeekValue(openB, "f", Infinity)) ? (priorityQueuePeekValue(openA, "f", Infinity)) : (priorityQueuePeekValue(openB, "f", Infinity)));
if((minOpen >= best)) {
break;
}
}
for(int _fod_i = 0; _fod_i < getNeighbors(grid, node.row, node.col, allowDiag)_len; _fod_i++) {
int nr = getNeighbors(grid, node.row, node.col, allowDiag)[_fod_i][0];
int nc = getNeighbors(grid, node.row, node.col, allowDiag)[_fod_i][1];
var tentative = (gTable[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc));
if((tentative < gTable[nr][nc])) {
gTable[nr][nc] = tentative;
prev.set(key(nr, nc), [node.row, node.col]);
var f = (tentative + h(nr, nc, ((pickA) ? (end[0]) : (start[0])), ((pickA) ? (end[1]) : (start[1]))));
heap.push({f: f, row: nr, col: nc});
pushFrontier(nr, nc);
var meetTotal = (tentative + otherG[nr][nc]);
if((meetTotal < best)) {
best = meetTotal;
meet = key(nr, nc);
}
}
}
}
if(meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
}