Graph 主教:找到从A到B的最短路径
我目前正试图找到以下问题的解决方案:给定有一个主教和多个障碍物的8x8棋盘,需要找到从当前主教位置到其他特定位置的最短路径 更新 感谢所有响应者,我已经实现了一个解决方案。这是:Graph 主教:找到从A到B的最短路径,graph,shortest-path,chess,Graph,Shortest Path,Chess,我目前正试图找到以下问题的解决方案:给定有一个主教和多个障碍物的8x8棋盘,需要找到从当前主教位置到其他特定位置的最短路径 更新 感谢所有响应者,我已经实现了一个解决方案。这是: /************************************** 棋盘逻辑函数 ***************************************/ 函数p(x,y){ 返回{ x:x, y:y }; } 函数pos_等于(p1,p2){ if(p1==null | | p2==null)返
/**************************************
棋盘逻辑函数
***************************************/
函数p(x,y){
返回{
x:x,
y:y
};
}
函数pos_等于(p1,p2){
if(p1==null | | p2==null)返回false;
返回p1.x==p2.x&&p1.y==p2.y;
}
功能人机界面(pos){
返回位置2Alpha(位置x、位置y);
}
函数pos2alpha(x,y){
返回alpha[x]+(y+1);
}
函数intpos2alpha(intpos){
y=数学真值(intpos/10);
x=intpos-(y*10);
返回alpha[x]+(y+1);
}
功能pos2int(pos){
返回位置y*10+x;
}
函数int2pos(intpos){
变量y=数学真理(intpos/10);
var x=位置(y*10);
返回p(x,y);
}
功能pos2path(pos、delim){
如果(pos==null)返回“[]”;
var-res=[];
对于(变量i=0;i”
返回res.join(delim);
}
功能单元颜色(位置){
var-color=1;
if(location.x%2==0&&location.y%2==0)
颜色=1;
if(location.x%2!=0&&location.y%2==0)
颜色=0;
if(location.x%2==0&&location.y%2!=0)
颜色=0;
if(location.x%2!=0&&location.y%2!=0)
颜色=1;
返回颜色;
}
功能板_obj(pos){
var-res=0;
如果(位置x<0 | |位置x>7 | |位置y<0 | |位置y>7)
res=“o”;
其他的
res=董事会[7-位置y][位置x];
返回res;
}
/**************************************
主要查找路径函数
***************************************/
var迭代次数=0;
//让我们防止使用特定迭代次数进行扫描
//避免长时间执行
var最大迭代次数=10000;
/*
----------------
|西北|东北|
----------------
|| Bs ||
----------------
|西南| |东南|
----------------
*/
var nw_向量=p(-1,1);
var ne_向量=p(1,1);
var se_向量=p(1,-1);
var sw_向量=p(-1,-1);
函数find_path(){
if(target_pos==null | | bishop_pos==null){
警报(“必须设置主教和目标”);
返回;
}
var路径=[];
var start=new Date().getTime();
if(单元格颜色(bishop位置)=单元格颜色(目标位置)){
路径=搜索位置(主教位置);
}
var end=new Date().getTime();
var dur=结束-开始;
输出结果(路径、dur);
}
函数向量_点(位置、向量、移位){
返回p(位置x+shift*vector.x,位置y+shift*vector.y);
}
功能可能从(pos)移动{
变量向量=[{
主动:对,
向量:se_向量
}, {
主动:对,
向量:sw_向量
}, {
主动:对,
矢量:nw_矢量
}, {
主动:对,
向量:ne_向量
}];
var移位=1;
var-res=[];
而(向量[0]。活动| |向量[1]。活动| |向量[2]。活动| |向量[3]。活动){
对于(var j=0;j7){
pos.x=pos.x%2==0?1:0;
pos.y++;
}
}
//初始化BFS队列(排队位置)
变量队列=[original_pos_int];
//初始化BFS节点集合
风险值=[原始位置];
//初始化父节点映射
var parents={};
while(queue.length>0){
迭代++;
如果(迭代次数>=最大迭代次数){
log(“超过最大迭代次数(“+max\u iterations\u count+”)。停止搜索”);
返回[];
}
var pos_int=queue.pop();
变量y=数学真实值(位置int/10);
var x=位置(y*10);
var pos=p(x,y);
变量可能移动=顶点[pos_int];
如果(可能的_moves==null)继续;
对于(var j=0;j<可能的长度;j++){
var可能移动=可能移动[j];
if(探索。索引of(可能移动)<0){
父母[可能移动]=位置;
/**************************************
Chess board logic functions
***************************************/
function p(x, y) {
return {
x: x,
y: y
};
}
function pos_equals(p1, p2) {
if (p1 == null || p2 == null) return false;
return p1.x == p2.x && p1.y == p2.y;
}
function human_pos(pos) {
return pos2alpha(pos.x, pos.y);
}
function pos2alpha(x, y) {
return alpha[x] + (y + 1);
}
function intpos2alpha(intpos) {
y = Math.trunc(intpos / 10);
x = intpos - (y * 10);
return alpha[x] + (y + 1);
}
function pos2int(pos) {
return pos.y * 10 + pos.x;
}
function int2pos(intpos) {
var y = Math.trunc(intpos / 10);
var x = pos_int - (y * 10);
return p(x, y);
}
function pos2path(pos, delim) {
if (pos == null) return "[]";
var res = [];
for (var i = 0; i < pos.length; i++) {
var p1 = pos[i];
var x = 0,
y = 0;
if (typeof p1 === 'object') {
x = p1.x;
y = p1.y;
} else {
y = Math.trunc(p1 / 10);
x = p1 - (y * 10);
}
res.push(pos2alpha(x, y));
}
if (delim == null) delim = "->"
return res.join(delim);
}
function cell_color(location) {
var color = 1;
if (location.x % 2 == 0 && location.y % 2 == 0)
color = 1;
if (location.x % 2 != 0 && location.y % 2 == 0)
color = 0;
if (location.x % 2 == 0 && location.y % 2 != 0)
color = 0;
if (location.x % 2 != 0 && location.y % 2 != 0)
color = 1;
return color;
}
function board_obj(pos) {
var res = 0;
if (pos.x < 0 || pos.x > 7 || pos.y < 0 || pos.y > 7)
res = "o";
else
res = board[7 - pos.y][pos.x];
return res;
}
/**************************************
Major find path functions
***************************************/
var iterations = 0;
// let's prevent scanning with particular iterations count
// to avoid very long execution
var max_iterations_count = 10000;
/*
----------------
| nw | | ne |
----------------
| | Bs | |
----------------
| sw | | se |
----------------
*/
var nw_vector = p(-1, 1);
var ne_vector = p(1, 1);
var se_vector = p(1, -1);
var sw_vector = p(-1, -1);
function find_path() {
if (target_pos == null || bishop_pos == null) {
alert("bishop and target both must be set");
return;
}
var path = [];
var start = new Date().getTime();
if (cell_color(bishop_pos) == cell_color(target_pos)) {
path = search_bfs(bishop_pos);
}
var end = new Date().getTime();
var dur = end - start;
output_result(path, dur);
}
function vector_point(pos, vector, shift) {
return p(pos.x + shift * vector.x, pos.y + shift * vector.y);
}
function possible_moves_from(pos) {
var vectors = [{
active: true,
vector: se_vector
}, {
active: true,
vector: sw_vector
}, {
active: true,
vector: nw_vector
}, {
active: true,
vector: ne_vector
}];
var shift = 1;
var res = [];
while (vectors[0].active || vectors[1].active || vectors[2].active || vectors[3].active) {
for (var j = 0; j < vectors.length; j++) {
if (vectors[j].active) {
iterations++;
var v_pos = vector_point(pos, vectors[j].vector, shift);
var l_obj = board_obj(v_pos);
if (l_obj == "o" || l_obj == "b") {
vectors[j].active = false;
} else {
res.push(v_pos.y * 10 + v_pos.x);
}
}
}
shift++;
}
return res;
}
function search_bfs(original_pos) {
// reset global iterations counter
iterations = 0;
var original_pos_int = pos2int(original_pos);
// create undirected graphs with all possible bishop positions
var vertices = {};
var pos = p(0, 0);
// if bishop cell color differs from color of left-bottom cell color (A1)
// than start with cell (A2)
if (cell_color(pos) != cell_color(original_pos)) {
pos.x = 1;
}
// let's convert cell positions {x: n, y: m} to integer representation
// int_pos = y+10 + x, e.g. B2 = 1 * 10 + 1 = 11
var target_pos_int = pos2int(target_pos);
for (var i = 0; i < 32; i++) {
var intpos = pos2int(pos);
var l_obj = board_obj(pos);
// if pos doesn't contain obstacle
// get a collection of all moves that bishop can make from pos
if (l_obj != "o") {
var possible_moves = possible_moves_from(pos);
vertices[intpos] = possible_moves;
}
pos.x += 2;
if (pos.x > 7) {
pos.x = pos.x % 2 == 0 ? 1 : 0;
pos.y++;
}
}
// initialize BFS queue (enqueue bishop position)
var queue = [original_pos_int];
// initialize BFS explored nodes collection
var explored = [original_pos_int];
// initialize parent nodes map
var parents = {};
while (queue.length > 0) {
iterations++;
if (iterations >= max_iterations_count) {
console.log("max iterations exceeded (" + max_iterations_count + "). stop searching");
return [];
}
var pos_int = queue.pop();
var y = Math.trunc(pos_int / 10);
var x = pos_int - (y * 10);
var pos = p(x, y);
var possible_moves = vertices[pos_int];
if (possible_moves == null) continue;
for (var j = 0; j < possible_moves.length; j++) {
var possible_move = possible_moves[j];
if (explored.indexOf(possible_move) < 0) {
parents[possible_move] = pos_int;
explored.push(possible_move);
if (target_pos_int == possible_move) {
queue = [];
break;
} else {
queue.splice(0, 0, possible_move);
}
}
}
}
// start backward traverse from target to bishop position
// and compose result path
var path = [];
var current = target_pos_int;
while (current != null) {
path.push(current);
current = parents[current];
}
// if path contains only one element, then path is not found
return path.length > 1 ? path : [];
}
// --- BFS(u, v)-----------------------------
for each vertex w
do flag[w] := false;
pred[w] := -1 ; // predecessor of w
Q := empty queue;
flag[u] := true; // already visited
enqueue(Q, u)
while Q not empty
do w:= dequeue(Q);
for each x adjacent to w
if flag[x] = false
flag[x] := true;
pred[x] := w ;
if x = v
empty Q;
break;
else
enqueue(Q, x);
// --- ReportShortestPath(u, v)---------------
// backward path - v to u:
current := v;
do output current;
current := pred[currrent];
while current != -1