最小步数

时间:2018-06-30 22:44:42

标签: javascript jquery

我试图返回在二维地图上从一个点移动到另一点且步骤被阻塞的最小步骤。


0 – cell is empty, 
1 – cell is blocked, 
5 – from point (A), 
6 – to point (B).

有人可以帮助解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

这是一种广度优先搜索的技术,这是一种用于在未加权图中查找最短距离的标准算法。

您将需要一个队列(先进先出数据结构),我们可以使用一个数组和一个数据结构来实现该队列,以跟踪我们访问过的节点及其父节点(即我们到达的节点) )。我们可以为此使用对象地图。

从开始节点开始,然后将其添加到队列中。然后,当队列不为空时:

  • 将节点移出队列
  • 找到邻居
  • 如果邻居不在父母地图中,请将其添加到队列中,然后邻居地图
  • 重复直到找到目的地

如果找不到目的地,则无法到达。最后,您的父地图将允许您通过遵循节点->父路径来跟踪从目的地到起点的步骤。您可以使用它来获取计数并创建路径。

以下代码使用一些辅助函数来打印图形并在给定节点坐标的情况下查找邻居。为了使它更有趣,我使用了迷宫式解决方案,它比问题中的解决方案更为复杂。

// make a slightly harder maze
var multiArr = [
    ['0','0','0','0','1','5','0'],
    ['1','0','1','0','0','1','0'],
    ['0','0','0','1','0','1','0'],
    ['1','1','0','1','0','1','0'],
    ['0','0','0','1','0','1','0'],
    ['6','1','0','1','0','0','0']
];
/* the coordinates of our start, hard coded for simplicity */
let coord = [0, 5]

/* find the neighbors of a given coordinate
   only return those that are not equal to 1 and
   don't go off the edge of the map */
function getNeighbors(arr, coord) {
    let height = arr.length;
    let width = arr[0].length;
    return [[1,0],[-1, 0], [0,1], [0,-1]].reduce((a, c) => {
       let n = c.map((d, ind) => d + coord[ind])
       if (n[0] >= 0 && n[0] < height && n[1] >= 0 && n[1] < width && arr[n[0]][n[1]] != 1) a.push(n)
       return a
    }, [])
}

/* breadth first search */
function bfs(coord, multiArr) {
    let queue = [coord]
    /* keys for parents will be formed by joining doordinates with _ since we can's use the raw array */
    let parents = new Map([[coord.join('_'), undefined]])

    while (queue.length){
        let curr = queue.shift()
        let neighbors = getNeighbors(multiArr, curr)
        for (node of neighbors) {
            if(parents.has(node.join('_'))) continue
            let cell = multiArr[node[0]][node[1]]
            parents.set(node.join('_'), curr)
            queue.push(node)            
            if (cell == 6 )  return getPath(node, parents)              
        }
    }
    console.log("no path")
}

/* take the parents array from bfs() and print the result */
function getPath(node, parents) {
    let curr = node
    let length = 0
    while(curr = parents.get(curr.join('_'))){
        multiArr[curr[0]][curr[1]] = '*'
        length++
    }
    console.log('min length: ',length)
    console.log('solution:')
    for (row of multiArr){
        console.log(row.join('  '))
    }
}

/* engage */
bfs(coord, multiArr)