当前位置:首页 > JavaScript

js实现寻路算法

2026-04-04 18:18:01JavaScript

广度优先搜索(BFS)算法实现

BFS通过队列逐层扩展搜索,适合无权图的最短路径查找。以下为基于网格的BFS实现:

function bfs(grid, start, end) {
  const queue = [[start]];
  const visited = new Set([start.toString()]);
  const directions = [[-1,0], [1,0], [0,-1], [0,1]]; // 上下左右

  while (queue.length) {
    const path = queue.shift();
    const [x, y] = path[path.length-1];

    if (x === end[0] && y === end[1]) return path;

    for (const [dx, dy] of directions) {
      const nx = x + dx, ny = y + dy;
      if (nx >= 0 && ny >= 0 && 
          nx < grid.length && ny < grid[0].length &&
          !grid[nx][ny] && !visited.has([nx,ny].toString())) {
        visited.add([nx,ny].toString());
        queue.push([...path, [nx, ny]]);
      }
    }
  }
  return null; // 无路径
}

A* 算法实现

A*算法结合启发式函数和实际代价,适合带权图的优化搜索:

js实现寻路算法

class PriorityQueue {
  constructor() {
    this.elements = [];
  }
  enqueue(element, priority) {
    this.elements.push({element, priority});
    this.elements.sort((a,b) => a.priority - b.priority);
  }
  dequeue() {
    return this.elements.shift().element;
  }
  isEmpty() {
    return !this.elements.length;
  }
}

function aStar(grid, start, end) {
  const openSet = new PriorityQueue();
  openSet.enqueue(start, 0);
  const cameFrom = {};
  const gScore = {[start]: 0};
  const fScore = {[start]: heuristic(start, end)};

  while (!openSet.isEmpty()) {
    const current = openSet.dequeue();
    if (current[0] === end[0] && current[1] === end[1]) 
      return reconstructPath(cameFrom, current);

    for (const [dx, dy] of [[-1,0], [1,0], [0,-1], [0,1]]) {
      const neighbor = [current[0]+dx, current[1]+dy];
      if (!isValid(grid, neighbor)) continue;

      const tentativeG = gScore[current] + 1;
      if (!(neighbor in gScore) || tentativeG < gScore[neighbor]) {
        cameFrom[neighbor] = current;
        gScore[neighbor] = tentativeG;
        fScore[neighbor] = tentativeG + heuristic(neighbor, end);
        openSet.enqueue(neighbor, fScore[neighbor]);
      }
    }
  }
  return null;
}

function heuristic(a, b) {
  return Math.abs(a[0]-b[0]) + Math.abs(a[1]-b[1]); // 曼哈顿距离
}

可视化实现建议

结合HTML5 Canvas实现路径可视化:

js实现寻路算法

function drawPath(ctx, grid, path, cellSize = 20) {
  // 绘制网格
  grid.forEach((row, x) => {
    row.forEach((cell, y) => {
      ctx.fillStyle = cell ? '#000' : '#fff';
      ctx.fillRect(y*cellSize, x*cellSize, cellSize, cellSize);
    });
  });

  // 绘制路径
  ctx.strokeStyle = 'red';
  ctx.lineWidth = 2;
  ctx.beginPath();
  path.forEach(([x,y], i) => {
    if (i === 0) ctx.moveTo(y*cellSize+cellSize/2, x*cellSize+cellSize/2);
    else ctx.lineTo(y*cellSize+cellSize/2, x*cellSize+cellSize/2);
  });
  ctx.stroke();
}

性能优化技巧

使用TypedArray替代普通数组存储网格数据可提升性能。对于大规模地图,可采用分层路径查找(HPA*)或跳点搜索(JPS)等优化算法。

// 使用Uint8Array表示网格
const grid = new Uint8Array(rows * cols); 
grid[y * cols + x] = 1; // 设置障碍物

动态障碍物处理

实现动态障碍物需要引入重新规划机制:

function dynamicReplan(path, newObstacles) {
  const affected = path.some(([x,y]) => newObstacles.has(`${x},${y}`));
  if (affected) {
    const remainingPath = path.slice(0, path.findIndex(
      ([x,y]) => newObstacles.has(`${x},${y}`)));
    return aStar(grid, remainingPath[remainingPath.length-1], end);
  }
  return path;
}

标签: 算法js
分享给朋友:

相关文章

js实现图片放大缩小

js实现图片放大缩小

实现图片放大缩小的基础方法 使用CSS的transform: scale()属性可以快速实现图片的放大缩小效果。通过JavaScript动态修改该属性值: const img = document.…

js实现类

js实现类

JavaScript 实现类的几种方式 JavaScript 是一种基于原型的语言,但在 ES6 之后引入了 class 语法糖,使得实现类更加直观。以下是几种常见的实现方式: 使用构造函数 传统的…

js实现瀑布流

js实现瀑布流

实现瀑布流布局 瀑布流布局是一种常见的网页布局方式,常用于图片展示、商品列表等场景。以下是使用 JavaScript 实现瀑布流布局的几种方法。 纯 JavaScript 实现 通过计算元素的位置和…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现防洪

js实现防洪

防抖(Debounce)实现 防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口调整等场景。 function debounce(f…

js实现视口

js实现视口

js实现视口检测的方法 使用JavaScript检测元素是否进入视口(viewport)可以通过Intersection Observer API或手动计算元素位置实现。以下是两种常见方法: Int…