当前位置:首页 > 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*算法结合启发式函数和实际代价,适合带权图的优化搜索:

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实现路径可视化:

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; // 设置障碍物

动态障碍物处理

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

js实现寻路算法

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实现跳转

使用 window.location 跳转 通过修改 window.location.href 或直接使用 window.location 实现页面跳转,适用于普通跳转或带参数的 URL。 // 方…

js实现选项卡

js实现选项卡

实现选项卡的基本思路 选项卡通常由一组标签和对应的内容面板组成。点击标签时,显示对应的内容面板,隐藏其他面板。实现这一效果需要结合HTML结构、CSS样式和JavaScript交互逻辑。 HTML结…

js实现类

js实现类

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

js实现图表

js实现图表

在JavaScript中实现图表通常使用流行的图表库,以下是几种常见的方法和工具: 使用Chart.js Chart.js是一个简单灵活的库,适合快速生成响应式图表。安装方式包括CDN引入或npm安…

js jquery

js jquery

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够…

js实现选题

js实现选题

实现选题功能的JavaScript方法 基础实现方案 使用数组存储选项,通过随机索引选取: const options = ['选项A', '选项B', '选项C', '选项D']; const r…