Dijkstra算法代码示例
主程序
% 基于栅格地图的机器人路径规划算法 % 第2节:Dijkstra算法 clc clear close all %% 栅格界面、场景定义 % 行数和列数 rows = 10; cols = 20; [field,cmap] = defColorMap(rows, cols); % 起点、终点、障碍物区域 startPos = 2; goalPos = rows*cols-2; field(startPos) = 4; field(goalPos) = 5; %% 算法初始化 % S/U的第一列表示栅格节点-线性索引编号 % 对于S,第二列表示从源节点到本节点已求得的最小距离,不再变更; % 对于U,第二列表示从源节点到本节点暂时求得的最小距离,可能会变更 U(:,1) = (1: rows*cols)'; U(:,2) = inf; S = [startPos, 0]; U(startPos,:) = []; % 更新起点的邻节点及代价 neighborNodes = getNeighborNodes(rows, cols, startPos, field); for i = 1:8 childNode = neighborNodes(i,1); % 判断该子节点是否存在 if ~isinf(childNode) idx = find(U(:,1) == childNode); U(idx,2) = neighborNodes(i,2); end end % U集合的最优路径集合 for i = 1:rows*cols path{i,1} = i; end for i = 1:8 childNode = neighborNodes(i,1); if ~isinf(neighborNodes(i,2)) path{childNode,2} = [startPos,neighborNodes(i,1)]; end end %% 循环遍历 while ~isempty(U) % 在U集合找出当前最小距离值的节点,视为父节点,并移除该节点至S集合中 [dist_min, idx] = min(U(:,2)); parentNode = U(idx, 1); S(end+1,:) = [parentNode, dist_min]; U(idx,:) = []; % 获得当前节点的临近子节点 neighborNodes = getNeighborNodes(rows, cols, parentNode, field); % 依次遍历邻近子节点,判断是否在U集合中更新邻节点的距离值 for i = 1:8 % 需要判断的子节点 childNode = neighborNodes(i,1); cost = neighborNodes(i,2); if ~isinf(childNode) && ~ismember(childNode, S) % 找出U集合中节点childNode的索引值 idx_U = find(childNode == U(:,1)); % 判断是否更新 if dist_min + cost < U(idx_U, 2) U(idx_U, 2) = dist_min + cost; % 更新最优路径 path{childNode, 2} = [path{parentNode, 2}, childNode]; end end end end %% 画栅格界面 % 找出目标最优路径 path_opt = path{goalPos,2}; field(path_opt(2:end-1)) = 6; % 画栅格图 image(1.5,1.5,field); grid on; set(gca,'gridline','-','gridcolor','k','linewidth',2,'GridAlpha',0.5); set(gca,'xtick',1:cols+1,'ytick',1:rows+1); axis image;
defColorMap()函数
function [field,cmap] = defColorMap(rows, cols) cmap = [1 1 1; ... % 1-白色-空地 0 0 0; ... % 2-黑色-静态障碍 1 0 0; ... % 3-红色-动态障碍 1 1 0;... % 4-黄色-起始点 1 0 1;... % 5-品红-目标点 0 1 0; ... % 6-绿色-到目标点的规划路径 0 1 1]; % 7-青色-动态规划的路径 % 构建颜色MAP图 colormap(cmap); % 定义栅格地图全域,并初始化空白区域 field = ones(rows, cols); % 障碍物区域 obsRate = 0.3; obsNum = floor(rows*cols*obsRate); obsIndex = randi([1,rows*cols],obsNum,1); field(obsIndex) = 2;
getNeighborNodes()函数
function neighborNodes = getNeighborNodes(rows, cols, lineIndex, field) [row, col] = ind2sub([rows,cols], lineIndex); neighborNodes = inf(8,2); %% 查找当前父节点临近的周围8个子节点 % 1.左上节点 % neighborNodes有两列,第一列保存邻接点线性索引值,第二列保存到邻接点的花费 if row-1 > 0 && col-1 > 0 child_node_sub = [row-1, col-1]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); % 将child_node_sub = [row-1, col-1];变成线性索引值 neighborNodes(1,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 % 判断邻接点是不是障碍物节点 cost = norm(child_node_sub - [row, col]); % 计算到邻接点的花费(非障碍物邻接点) neighborNodes(1,2) = cost; end end % 2.上节点 if row-1 > 0 child_node_sub = [row-1, col]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); neighborNodes(2,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 cost = norm(child_node_sub - [row, col]); neighborNodes(2,2) = cost; end end % 3.右上节点 if row-1 > 0 && col+1 <= cols child_node_sub = [row-1, col+1]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); neighborNodes(3,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 cost = norm(child_node_sub - [row, col]); neighborNodes(3,2) = cost; end end % 4.左节点 if col-1 > 0 child_node_sub = [row, col-1]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); neighborNodes(4,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 cost = norm(child_node_sub - [row, col]); neighborNodes(4,2) = cost; end end % 5.右节点 if col+1 <= cols child_node_sub = [row, col+1]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); neighborNodes(5,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 cost = norm(child_node_sub - [row, col]); neighborNodes(5,2) = cost; end end % 6.左下节点 if row+1 <= rows && col-1 > 0 child_node_sub = [row+1, col-1]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); neighborNodes(6,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 cost = norm(child_node_sub - [row, col]); neighborNodes(6,2) = cost; end end % 7.下节点 if row+1 <= rows child_node_sub = [row+1, col]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); neighborNodes(7,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 cost = norm(child_node_sub - [row, col]); neighborNodes(7,2) = cost; end end % 8.右下节点 if row+1 <= rows && col+1 <= cols child_node_sub = [row+1, col+1]; child_node_line = sub2ind([rows,cols], child_node_sub(1), child_node_sub(2)); neighborNodes(8,1) = child_node_line; if field(child_node_sub(1), child_node_sub(2)) ~= 2 cost = norm(child_node_sub - [row, col]); neighborNodes(8,2) = cost; end end
图像显示: