matlab改进A*算法 JPS算法 jps算法 跳点搜索算法 路径规划 超详细注释 可自定义...
·
matlab改进A*算法 JPS算法 jps算法 跳点搜索算法 路径规划 超详细注释 可自定义地图/障碍物 路径颜色 可显示扩展范围 修改代价函数 图为JPS算法和A*算法的对比
路径规划领域有两个经典算法:A和它的魔改版JPS。咱们今天用Matlab整点好玩的,手把手教你怎么实现这两个算法,再对比它们的效率差异。先看效果:同一张地图下,JPS扩展的节点数量只有A的1/3,路径却同样最优,这货到底是怎么做到的?
先上A*算法核心代码片段:
function [path, openList] = AStar(grid, start, goal)
% 初始化优先队列,格式:[f_cost, g_cost, x, y]
openList = priorityQueue([0 0 start]);
closedList = zeros(size(grid));
% 父节点记录矩阵(用于回溯路径)
cameFrom = cell(size(grid));
while ~openList.isEmpty()
current = openList.pop(); % 取出f值最小的节点
if isequal(current(3:4), goal)
path = reconstructPath(cameFrom, goal);
return;
end
% 获取8邻域坐标(允许对角移动)
neighbors = getNeighbors(grid, current(3:4));
for i = 1:size(neighbors,1)
next_node = neighbors(i,:);
% 关键点1:路径代价计算(可修改处!)
new_g = current(2) + movementCost(current(3:4), next_node);
new_h = heuristic(next_node, goal);
new_f = new_g + new_h;
if ~closedList(next_node(2), next_node(1))
openList.push([new_f, new_g, next_node]);
cameFrom{next_node(2), next_node(1)} = current(3:4);
end
end
closedList(current(3), current(4)) = 1;
end
path = []; % 未找到路径
end
这里有个骚操作:把movementCost函数里的对角移动代价从默认的√2改成1.414,路径会更贴合理论值。想显示扩展范围?在push节点时记录坐标,最后用scatter画出来即可。

重点来了——JPS算法的跳跃式搜索。相比A*的广撒网,JPS通过识别"跳点"大幅减少计算量。看这段跳跃检测代码:
function jump_point = jump(x, y, dx, dy, grid, goal)
% 沿着(dx, dy)方向跳跃检测
[nx, ny] = move(x, y, dx, dy); % 移动一格
if ~isFree(nx, ny, grid) % 撞墙了
return;
elseif isEndNode(nx, ny, goal) % 到达终点
jump_point = [nx, ny];
return;
end
% 关键点2:检测强制邻居(墙角有障碍时)
if hasForcedNeighbor(nx, ny, dx, dy, grid)
jump_point = [nx, ny];
return;
end
% 继续递归跳跃
if (dx ~= 0 && dy ~= 0) % 对角线移动时
% 横向和纵向都要检测
if ~isempty(jump(nx, ny, dx, 0, grid, goal)) || ...
~isempty(jump(nx, ny, 0, dy, grid, goal))
jump_point = [nx, ny];
return;
end
end
jump_point = jump(nx, ny, dx, dy, grid, goal);
end
举个栗子,当机器人向右上方移动时,如果右侧突然出现障碍物,则当前点成为跳点。这种策略直接跳过无岔路的直线区域,相当于给搜索过程开了个快进。
想要修改路径颜色?在绘图代码里加一行set参数:
plot(path(:,1), path(:,2), 'LineWidth',2, 'Color',[0.9 0.2 0.5]); % 玫红色路径
自定义地图就更简单了,直接修改grid矩阵。1是障碍,0是可通行区域。比如创建一个中间带空心十字的地图:
grid = zeros(20);
grid(8:12, 8:12) = 1; % 十字中心
grid([1:5,16:20], 10) = 1; % 纵向障碍
grid(10, [1:5,16:20]) = 1; % 横向障碍
最后放对比结果镇楼:在20x20地图中,A扩展了158个节点,JPS仅扩展了49个。但两者的路径长度都是28.28(对角移动)。JPS的节点扩展模式呈现明显的"跳跃"特征,而A的扩展区域则像涟漪般均匀扩散。需要完整代码的老铁可以在Github搜JPS-Matlab,记得star项目哦~

(图片示意:左侧A*的扩展节点密密麻麻,右侧JPS的节点呈线条状分布)
更多推荐



所有评论(0)