Javascript 利用遗传算法求矩阵中的最短路径travesal

Javascript 利用遗传算法求矩阵中的最短路径travesal,javascript,algorithm,Javascript,Algorithm,如果startnode为a1,endnode为b6,则需要在此矩阵中为ex找到最短路径 o/p应该是这样的 [0,0]、[1,0]、[1,1]、[1,2]、[1,3]、[1,4]、[1,5]] 我的矩阵 const matrix = [ ["A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"], ["B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8"], ["C1", "C

如果startnode为a1,endnode为b6,则需要在此矩阵中为ex找到最短路径 o/p应该是这样的

[0,0]、[1,0]、[1,1]、[1,2]、[1,3]、[1,4]、[1,5]]

我的矩阵

    const matrix = [
      ["A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"],
      ["B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8"],
      ["C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8"],
      ["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8"],
      ["E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8"],
      ["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8"],
      ["G1", "G2", "G3", "G4", "G5", "G6", "G7", "G8"],
      ["H1", "H2", "H3", "H4", "H5", "H6", "H7", "H8"]
    ];


    function findNode(node, nodeName) {
       let childNodeIdx = -1;
       const foundNode = matrix.find(fr => {
        const foundChildNode = fr.find(fc => {
         return fc.toLowerCase() === node.toLowerCase();
        });
        childNodeIdx = fr.indexOf(foundChildNode);
        return fr.includes(foundChildNode);
      });
    return { [nodeName]: [matrix.indexOf(foundNode), childNodeIdx] };
}
函数findWay

function findWay(position, end) {
  let queue = [];

  matrix[position[0]][position[1]] = 1;
  queue.push([position]);

  while (queue.length > 0) {
    const path = queue.shift();
    const pos = path[path.length - 1];

    const direction = [
      [pos[0] - 1, pos[1]],
      [pos[0], pos[1] - 1],
      [pos[0] + 1, pos[1]],
      [pos[0], pos[1] + 1]
    ];

    for (let i = 0; i < direction.length; i++) {
      // Perform this check first:      
      if (direction[i][0] == end[0] && direction[i][1] == end[1]) {
        return path.concat([end]);
      }

      if (
         direction[i][0] >= matrix[0].length ||
         direction[i][1] >= matrix[0].length
      ) {
        continue;
      }
      if (direction[i][0] >= 0 && [direction[i][1]] >= 0) {
        matrix[direction[i][0]][direction[i][1]] = 1;
        // extend and push the path on the queue
        queue.push(path.concat([direction[i]]));
      }
    }
  }
}

const start = findNode("a1", "startNode").startNode;
const end = findNode("b6", "endNode").endNode;

const path = findWay(start, end);
console.log(JSON.stringify(path));
函数findWay(位置,结束){
让队列=[];
矩阵[位置[0]][位置[1]]=1;
queue.push([position]);
while(queue.length>0){
const path=queue.shift();
const pos=路径[path.length-1];
常数方向=[
[pos[0]-1,pos[1]],
[pos[0],pos[1]-1],
[pos[0]+1,pos[1]],
[位置[0],位置[1]+1]
];
for(设i=0;i=矩阵[0]。长度||
方向[i][1]>=矩阵[0]。长度
) {
继续;
}
如果(方向[i][0]>=0&&[方向[i][1]]>=0){
矩阵[方向[i][0]][方向[i][1]]=1;
//扩展并推送队列上的路径
queue.push(path.concat([direction[i]]);
}
}
}
}
const start=findNode(“a1”,“startNode”)。startNode;
const end=findNode(“b6”,“endNode”).endNode;
常量路径=findWay(开始、结束);
log(JSON.stringify(path));
此代码适用于较短的开始和结束节点(如a1和b6),但当开始节点a1和结束节点为e8时,打印o/p需要较长的时间。 我需要知道如何解决问题中的时间复杂性

规则是垂直和水平移动,但不是对角移动
任何帮助都将不胜感激

不确定我是否正确理解您的问题。请检查此代码段:

const矩阵=[
[“A1”、“A2”、“A3”、“A4”、“A5”、“A6”、“A7”、“A8”],
[“B1”、“B2”、“B3”、“B4”、“B5”、“B6”、“B7”、“B8”],
[“C1”、“C2”、“C3”、“C4”、“C5”、“C6”、“C7”、“C8”],
[“D1”、“D2”、“D3”、“D4”、“D5”、“D6”、“D7”、“D8”],
[“E1”、“E2”、“E3”、“E4”、“E5”、“E6”、“E7”、“E8”],
[“F1”、“F2”、“F3”、“F4”、“F5”、“F6”、“F7”、“F8”],
[“G1”、“G2”、“G3”、“G4”、“G5”、“G6”、“G7”、“G8”],
[“H1”、“H2”、“H3”、“H4”、“H5”、“H6”、“H7”、“H8”]
];
函数findNode(节点,节点名){
让childNodeIdx=-1;
const foundNode=matrix.find(fr=>{
const foundChildNode=fr.find(fc=>{
返回fc.toLowerCase()==node.toLowerCase();
});
ChildNodeId=fr.indexOf(foundChildNode);
返回fr.includes(foundChildNode);
});
返回{[nodeName]:[matrix.indexOf(foundNode),ChildNodeId]};
}
函数findPath(起始值、结束值){
让输出=[];
设startNodeX=findNode(startValue,startNode)。startNode[0];
设startNode=findNode(startValue,startNode)).startNode[1];
设endNodeX=findNode(endValue,“endNode”).endNode[0];
设endNodeY=findNode(endValue,“endNode”).endNode[1];
而(Math.abs(startNodeX-endNodeX)>0){
while(Math.abs(startNodeY-endNodeY)>0){
push([startNodeX,startNodeY]);
startNodeY>endNodeY?startNodeY--:startNodeY++;
}
push([startNodeX,startNodeY]);
startNodeX>endNodeX?startNodeX--:startNodeX++;
}
push([endNodeX,endNodeY]);
返回输出;
};
常数t1=findPath(“a1”、“b6”);
常数t2=findPath(“f1”、“a1”);
常数t3=findPath(“f6”、“b2”);

控制台日志(t1);控制台日志(t2);控制台日志(t3)不确定我是否正确理解您的问题。请检查此代码段:

const矩阵=[
[“A1”、“A2”、“A3”、“A4”、“A5”、“A6”、“A7”、“A8”],
[“B1”、“B2”、“B3”、“B4”、“B5”、“B6”、“B7”、“B8”],
[“C1”、“C2”、“C3”、“C4”、“C5”、“C6”、“C7”、“C8”],
[“D1”、“D2”、“D3”、“D4”、“D5”、“D6”、“D7”、“D8”],
[“E1”、“E2”、“E3”、“E4”、“E5”、“E6”、“E7”、“E8”],
[“F1”、“F2”、“F3”、“F4”、“F5”、“F6”、“F7”、“F8”],
[“G1”、“G2”、“G3”、“G4”、“G5”、“G6”、“G7”、“G8”],
[“H1”、“H2”、“H3”、“H4”、“H5”、“H6”、“H7”、“H8”]
];
函数findNode(节点,节点名){
让childNodeIdx=-1;
const foundNode=matrix.find(fr=>{
const foundChildNode=fr.find(fc=>{
返回fc.toLowerCase()==node.toLowerCase();
});
ChildNodeId=fr.indexOf(foundChildNode);
返回fr.includes(foundChildNode);
});
返回{[nodeName]:[matrix.indexOf(foundNode),ChildNodeId]};
}
函数findPath(起始值、结束值){
让输出=[];
设startNodeX=findNode(startValue,startNode)。startNode[0];
设startNode=findNode(startValue,startNode)).startNode[1];
设endNodeX=findNode(endValue,“endNode”).endNode[0];
设endNodeY=findNode(endValue,“endNode”).endNode[1];
而(Math.abs(startNodeX-endNodeX)>0){
while(Math.abs(startNodeY-endNodeY)>0){
push([startNodeX,startNodeY]);
startNodeY>endNodeY?startNodeY--:startNodeY++;
}
push([startNodeX,startNodeY]);
startNodeX>endNodeX?startNodeX--:startNodeX++;
}
push([endNodeX,endNodeY]);
返回输出;
};
常数t1=findPath(“a1”、“b6”);
常数t2=findPath(“f1”、“a1”);
常数t3=findPath(“f6”、“b2”);

控制台日志(t1);控制台日志(t2);控制台日志(t3)对于长路径,您的算法速度慢的原因是您没有标记您访问过的单元格。当队列中有一个单元格时,即使已经访问了它的邻居,也会将其添加到队列中

我不太熟悉javascript,但在Java或Python等其他语言中,您可以在将单元格添加到队列之前使用哈希集来检查是否以恒定的时间复杂度访问了单元格


添加此项将导致全局时间复杂度为
O(N)
,其中
N
是矩阵的大小,因为您没有两次访问单元格。

对于长路径,您的算法速度慢的原因是