function bidijkstraPathfind(grid, start, end, allowDiag) {
const rows = grid.length;
const cols = grid[0].length;
const distA = Matrix(rows, cols, Infinity);
const distB = Matrix(rows, cols, Infinity);
const prevA = new Map();
const prevB = new Map();
const visitedA = new Set();
const visitedB = new Set();
const heapA = PriorityQueue("priority");
const heapB = PriorityQueue("priority");
distA[start[0]][start[1]] = 0;
distB[end[0]][end[1]] = 0;
priorityQueuePush(heapA, {
priority: 0,
row: start[0],
col: start[1]
});
priorityQueuePush(heapB, {
priority: 0,
row: end[0],
col: end[1]
});
let best = Infinity;
let meet = null;
while (priorityQueueSize(heapA) || priorityQueueSize(heapB)) {
const chooseA = !priorityQueueSize(heapB) || priorityQueueSize(heapA) && priorityQueuePeekValue(heapA, "priority") <= priorityQueuePeekValue(heapB, "priority");
const heap = chooseA ? heapA : heapB;
const dist = chooseA ? distA : distB;
const otherDist = chooseA ? distB : distA;
const visited = chooseA ? visitedA : visitedB;
const otherVisited = chooseA ? visitedB : visitedA;
const prev = chooseA ? prevA : prevB;
const tag = chooseA ? 'visit-a' : 'visit-b';
const node = heap.pop();
const currentKey = key(node.row, node.col);
if (visited.has(currentKey)) continue;
visited.add(currentKey);
chooseA ? visitForwardNode(node.row, node.col) : visitBackwardNode(node.row, node.col);
if (otherVisited.has(currentKey)) {
const total = dist[node.row][node.col] + otherDist[node.row][node.col];
if (total < best) {
best = total;
meet = currentKey;
}
}
if (best < Infinity) {
const minA = priorityQueuePeekValue(heapA, "priority", Infinity);
const minB = priorityQueuePeekValue(heapB, "priority", Infinity);
if (Math.min(minA, minB) >= best) break;
}
for (const [nr, nc] of getNeighbors(grid, node.row, node.col, allowDiag)) {
const nd = dist[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc);
if (nd < dist[nr][nc]) {
dist[nr][nc] = nd;
prev.set(key(nr, nc), [node.row, node.col]);
heap.push({
priority: nd,
row: nr,
col: nc
});
pushFrontier(nr, nc);
}
}
}
if (meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
} def bidijkstraPathfind(grid, start, end, allowDiag):
rows = grid.length
cols = grid[0].length
distA = Matrix(rows, cols, Infinity)
distB = Matrix(rows, cols, Infinity)
prevA = Map()
prevB = Map()
visitedA = Set()
visitedB = Set()
heapA = PriorityQueue("priority")
heapB = PriorityQueue("priority")
distA[start[0]][start[1]] = 0
distB[end[0]][end[1]] = 0
priorityQueuePush(heapA, {priority: 0, row: start[0], col: start[1]})
priorityQueuePush(heapB, {priority: 0, row: end[0], col: end[1]})
best = Infinity
meet = None
while (priorityQueueSize(heapA) or priorityQueueSize(heapB)):
chooseA = (not priorityQueueSize(heapB) or (priorityQueueSize(heapA) and (priorityQueuePeekValue(heapA, "priority") <= priorityQueuePeekValue(heapB, "priority"))))
heap = (heapA if chooseA else heapB)
dist = (distA if chooseA else distB)
otherDist = (distB if chooseA else distA)
visited = (visitedA if chooseA else visitedB)
otherVisited = (visitedB if chooseA else visitedA)
prev = (prevA if chooseA else prevB)
tag = ("visit-a" if chooseA 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 chooseA else visitBackwardNode(node.row, node.col))
if otherVisited.has(currentKey):
total = (dist[node.row][node.col] + otherDist[node.row][node.col])
if (total < best):
best = total
meet = currentKey
if (best < Infinity):
minA = priorityQueuePeekValue(heapA, "priority", Infinity)
minB = priorityQueuePeekValue(heapB, "priority", Infinity)
if (min(minA, minB) >= best):
break
for nr, nc in getNeighbors(grid, node.row, node.col, allowDiag):
nd = (dist[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc))
if (nd < dist[nr][nc]):
dist[nr][nc] = nd
prev.set(key(nr, nc), [node.row, node.col])
heap.push({priority: nd, row: nr, col: nc})
pushFrontier(nr, nc)
if meet:
reconstructBidirectionalPath(prevA, prevB, meet, start, end)
else:
reportNoPath() #include <vector>
#include <algorithm>
void bidijkstraPathfind(int grid, int start, int end, int allowDiag) {
auto rows = grid.length;
auto cols = grid[0].length;
auto distA = Matrix(rows, cols, Infinity);
auto distB = Matrix(rows, cols, Infinity);
auto prevA = Map();
auto prevB = Map();
auto visitedA = Set();
auto visitedB = Set();
auto heapA = PriorityQueue("priority");
auto heapB = PriorityQueue("priority");
distA[start[0]][start[1]] = 0;
distB[end[0]][end[1]] = 0;
priorityQueuePush(heapA, {priority: 0, row: start[0], col: start[1]});
priorityQueuePush(heapB, {priority: 0, row: end[0], col: end[1]});
auto best = Infinity;
auto meet = null;
while((priorityQueueSize(heapA) || priorityQueueSize(heapB))) {
auto chooseA = (!priorityQueueSize(heapB) || (priorityQueueSize(heapA) && (priorityQueuePeekValue(heapA, "priority") <= priorityQueuePeekValue(heapB, "priority"))));
auto heap = ((chooseA) ? (heapA) : (heapB));
auto dist = ((chooseA) ? (distA) : (distB));
auto otherDist = ((chooseA) ? (distB) : (distA));
auto visited = ((chooseA) ? (visitedA) : (visitedB));
auto otherVisited = ((chooseA) ? (visitedB) : (visitedA));
auto prev = ((chooseA) ? (prevA) : (prevB));
auto tag = ((chooseA) ? ("visit-a") : ("visit-b"));
auto node = heap.pop();
auto currentKey = key(node.row, node.col);
if(visited.has(currentKey)) {
continue;
}
visited.add(currentKey);
((chooseA) ? (visitForwardNode(node.row, node.col)) : (visitBackwardNode(node.row, node.col)));
if(otherVisited.has(currentKey)) {
auto total = (dist[node.row][node.col] + otherDist[node.row][node.col]);
if((total < best)) {
best = total;
meet = currentKey;
}
}
if((best < Infinity)) {
auto minA = priorityQueuePeekValue(heapA, "priority", Infinity);
auto minB = priorityQueuePeekValue(heapB, "priority", Infinity);
if((((minA) < (minB) ? (minA) : (minB)) >= best)) {
break;
}
}
for(auto& [nr, nc] : getNeighbors(grid, node.row, node.col, allowDiag)) {
auto nd = (dist[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc));
if((nd < dist[nr][nc])) {
dist[nr][nc] = nd;
prev.set(key(nr, nc), [node.row, node.col]);
heap.push({priority: nd, row: nr, col: nc});
pushFrontier(nr, nc);
}
}
}
if(meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
} public void bidijkstraPathfind(int grid, int start, int end, int allowDiag) {
var rows = grid.length;
var cols = grid[0].length;
var distA = Matrix(rows, cols, Infinity);
var distB = Matrix(rows, cols, Infinity);
var prevA = Map();
var prevB = Map();
var visitedA = Set();
var visitedB = Set();
var heapA = PriorityQueue("priority");
var heapB = PriorityQueue("priority");
distA[start[0]][start[1]] = 0;
distB[end[0]][end[1]] = 0;
priorityQueuePush(heapA, {priority: 0, row: start[0], col: start[1]});
priorityQueuePush(heapB, {priority: 0, row: end[0], col: end[1]});
var best = Infinity;
var meet = null;
while((priorityQueueSize(heapA) || priorityQueueSize(heapB))) {
var chooseA = (!priorityQueueSize(heapB) || (priorityQueueSize(heapA) && (priorityQueuePeekValue(heapA, "priority") <= priorityQueuePeekValue(heapB, "priority"))));
var heap = ((chooseA) ? (heapA) : (heapB));
var dist = ((chooseA) ? (distA) : (distB));
var otherDist = ((chooseA) ? (distB) : (distA));
var visited = ((chooseA) ? (visitedA) : (visitedB));
var otherVisited = ((chooseA) ? (visitedB) : (visitedA));
var prev = ((chooseA) ? (prevA) : (prevB));
var tag = ((chooseA) ? ("visit-a") : ("visit-b"));
var node = heap.pop();
var currentKey = key(node.row, node.col);
if(visited.has(currentKey)) {
continue;
}
visited.add(currentKey);
((chooseA) ? (visitForwardNode(node.row, node.col)) : (visitBackwardNode(node.row, node.col)));
if(otherVisited.has(currentKey)) {
var total = (dist[node.row][node.col] + otherDist[node.row][node.col]);
if((total < best)) {
best = total;
meet = currentKey;
}
}
if((best < Infinity)) {
var minA = priorityQueuePeekValue(heapA, "priority", Infinity);
var minB = priorityQueuePeekValue(heapB, "priority", Infinity);
if((Math.Min(minA, minB) >= best)) {
break;
}
}
foreach(var (nr, nc) in getNeighbors(grid, node.row, node.col, allowDiag)) {
var nd = (dist[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc));
if((nd < dist[nr][nc])) {
dist[nr][nc] = nd;
prev.set(key(nr, nc), [node.row, node.col]);
heap.push({priority: nd, row: nr, col: nc});
pushFrontier(nr, nc);
}
}
}
if(meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
} #include <stdio.h>
void bidijkstraPathfind(int grid, int start, int end, int allowDiag) {
var rows = grid.length;
var cols = grid[0].length;
var distA = Matrix(rows, cols, Infinity);
var distB = Matrix(rows, cols, Infinity);
var prevA = Map();
var prevB = Map();
var visitedA = Set();
var visitedB = Set();
var heapA = PriorityQueue("priority");
var heapB = PriorityQueue("priority");
distA[start[0]][start[1]] = 0;
distB[end[0]][end[1]] = 0;
priorityQueuePush(heapA, {priority: 0, row: start[0], col: start[1]});
priorityQueuePush(heapB, {priority: 0, row: end[0], col: end[1]});
var best = Infinity;
var meet = null;
while((priorityQueueSize(heapA) || priorityQueueSize(heapB))) {
var chooseA = (!priorityQueueSize(heapB) || (priorityQueueSize(heapA) && (priorityQueuePeekValue(heapA, "priority") <= priorityQueuePeekValue(heapB, "priority"))));
var heap = ((chooseA) ? (heapA) : (heapB));
var dist = ((chooseA) ? (distA) : (distB));
var otherDist = ((chooseA) ? (distB) : (distA));
var visited = ((chooseA) ? (visitedA) : (visitedB));
var otherVisited = ((chooseA) ? (visitedB) : (visitedA));
var prev = ((chooseA) ? (prevA) : (prevB));
var tag = ((chooseA) ? ("visit-a") : ("visit-b"));
var node = heap.pop();
var currentKey = key(node.row, node.col);
if(visited.has(currentKey)) {
continue;
}
visited.add(currentKey);
((chooseA) ? (visitForwardNode(node.row, node.col)) : (visitBackwardNode(node.row, node.col)));
if(otherVisited.has(currentKey)) {
var total = (dist[node.row][node.col] + otherDist[node.row][node.col]);
if((total < best)) {
best = total;
meet = currentKey;
}
}
if((best < Infinity)) {
var minA = priorityQueuePeekValue(heapA, "priority", Infinity);
var minB = priorityQueuePeekValue(heapB, "priority", Infinity);
if((((minA) < (minB) ? (minA) : (minB)) >= 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 nd = (dist[node.row][node.col] + stepCost(grid, node.row, node.col, nr, nc));
if((nd < dist[nr][nc])) {
dist[nr][nc] = nd;
prev.set(key(nr, nc), [node.row, node.col]);
heap.push({priority: nd, row: nr, col: nc});
pushFrontier(nr, nc);
}
}
}
if(meet) {
reconstructBidirectionalPath(prevA, prevB, meet, start, end);
} else {
reportNoPath();
}
}