Dijkstra’s 最短路径算法的 Matlab实现

随机生成400个点,再去除其中的120个点作为‘路障’。采用dijkstra算法寻找最短路径。

 

主函数: main.m

clc,clear all

% Define the size of the map
sideLength = 20;
nodes = sideLength*sideLength;
removed_num = 120;

% Generate the map
[routing_value,mapping] = mapGenerator(sideLength,removed_num)

% Calculate the shorest path
[dist,selectedNode] = Mydijkstra(routing_value,1,nodes)

% Draw the line 
drawLine(selectedNode,mapping)

思路:

step1:定义地图大小/内容

step2:把随机生成的‘视觉地图’信息载入‘矩阵地图’

step3:使用dijkstra原理寻找最短路径

step4:连点成线

生成地图函数: mapGenerator.m

function [routing_value, mapping] = mapGenerator(edge,removed_num)
% edge: the side length of the map

nodes = edge * edge;                    % Total elements in the routing table
routing_value = ones(nodes,nodes)*999;  % Set the initial distance to infinity(999)
mapping = zeros(2,nodes);               % The mapping matrix of map position and routing value table 

% updating the routing value from the (1,1) dot.
for y = 1:edge                          % x. Y represents two axes in the map
    y_original = y;
    for x = 1:edge
        y = y_original;
        x_original = x;
        h = x_original+(y_original-1)*edge;
        mapping(1,h)=x_original;
        mapping(2,h)=y_original;

        % right adjacency
        if(x_original<edge)
            x = x+1;
            k = (y-1)*edge + x;     % calculate the neighbor's number which is the column of routing_value table
            routing_value(h,k) = 1;
            routing_value(k,h) = 1; % because it is adjacent, the reverse is also true
            % h,k
        end

        % upper adjacency
        if(y_original<edge)
            x = x_original;
            y = y+1;
            k = (y-1)*edge + x;     % calculate the neighbor's number which is the column of routing_value table
            routing_value(h,k) = 1;
            routing_value(k,h) = 1; % because it is adjacent, the reverse is also true
            % h,k
        end

        % right upper corner
        % condition: not in the right border and not in the upper border.
        if(x_original<edge) && (y_original<edge)
            x = x+1;
            k = (y-1)*edge + x;       % calculate the neighbor's number which is the column of routing_value table
            routing_value(h,k) = 1.4;
            routing_value(k,h) = 1.4; % because it is adjacent, the reverse is also true
            % h,k
        end

        % left upper corner
        % condition: not in the left border and not in the upper border
        if(x_original>1) && (y_original<edge)
            x=x_original-1;
            k = (y-1)*edge + x;         % calculate the neighbor's number which is the column of routing_value table
            routing_value(h,k) = 1.4;
            routing_value(k,h) = 1.4;   % because it is adjacent, the reverse is also true
            % h,k
        end
    end
end

% !!! step2: draw dots on the map
for i = 1:edge
    x = i;
    for j = 1:edge
        y = j;
        scatter(x,y,'green');
        hold on
    end
end

% !!! step3: remove 3/10 dots on the map and re-calculate the routing table
record = zeros(1,size(routing_value,1)); % put the removed dots in record list to prevent removing more than once.
for i = 1:removed_num
    x = randperm(edge,1);                % the x axis of the dot, x<=edge
    y = randperm(edge,1);
    hk = x+(y-1)*edge;

    % can not remove start point and destination point.
    % and can not remove one point twice
    if(hk ~= nodes && hk ~= 1 && record(hk) ~= 1) 
        scatter(x,y,'red');
        record(hk) = 1;

        % set the removing nodes' value routing to infinite(999) 
        routing_value(hk,:)=999;
        routing_value(:,hk)=999;
    else 
        removed_num = removed_num+1;
    end
end

把 ‘视觉地图’ 信息载入矩阵的原理/逻辑:

如下表格所示,是 ‘视觉地图’ 中 ‘地点’ 的坐标信息,以中心地点的坐标为(x,y)为例,它与八个邻居坐标关系如下。

(x-1, y+1)(x, y+1)(x+1, y+1)
(x-1, y)(x, y)(x+1, y)
(x-1, y-1)(x, y-1)(x+1, y-1)

所以当我们生成‘ 矩阵地图 (用矩阵记录地图中的路径信息) ’时,可以(对总共400个点)从左往右,由下至上地更新每一个点和它邻居的关系。由于两点间路径值一致 (i.e. A-->B的距离=B-->A的距离),所以避免重复,对于当前‘点’,我们只需要写入‘当前点’ 到 ‘当前点之后/ 没有出现过的邻居’ 的距离值。

以中心地点的坐标为(x,y)为例,它之后的邻居为:

(x-1, y+1)(x, y+1)(x+1, y+1)
(x, y)(x+1, y)

(x+1, y-1)

PS: 我们还需要考虑到‘顶点’,如果当前点为顶点,或在边缘线之上,需要补充限制条件,以防程序报错。

Dijkstra’s 算法函数: Mydijkstra.m


function [dist,selectedNode] = Mydijkstra(routing_value,start,dest)

% setting
routers = size(routing_value,1);        % statistic total number of points(the row number of r_v table)
Selected(1) = dest;          % set of selected points
Unselected = 1:routers;        % set of unselected points
Unselected(dest) = [];         
Distance = zeros(2,routers);  % inisialize all the path length
Distance(1,:) = 1:routers;    % A 2*7 matrix to record the distance from every point to the destination
Distance(2,1:routers) = routing_value(dest,1:routers);  % assign the value
new_Distance = Distance;        % A 2*7 matrix used to compare with the original links distance
min_distance = Distance;            % Initialize minimum distance
min_distance(:,dest) = [];          % deleted the length from destination to destination

% initialize path
path = zeros(2,routers);  
path(1,:) = 1:routers;    
path(2,Distance(2,:)~=999) = dest;  % '999' stand for cannot reach
 
% finding the shorest path
while ~isempty(Unselected)  % until the unselected set is empty
    index = find( min_distance(2,:)==min(min_distance(2,:)),1 );  % find the shorest path among the leftover points
    k = min_distance(1,index); 
    % update the point
    Selected = [Selected,k];     % add k to Selected set
    Unselected(Unselected==k) = [];  % deleted from the set of Unselected  
    %calculate the distance
    new_Distance(2,:) = routing_value(k,1:routers)+Distance(2,k); 
    min_distance = min(Distance,new_Distance);  % compare with the former value and select the min
    % update the path
    path( 2, min_distance(2,:)~=Distance(2,:) ) = k;  % path used to record the former 'jump' of the router 
    Distance = min_distance;  
    min_distance(:,Selected) = [];   
end
dist = Distance(2,start);  
% output
selectedNode=[];
fprintf('the path is:');
while start ~= dest    % end when reach the destination
    selectedNode = [selectedNode,start];
    fprintf('%d-->',start);  
    next = path(2,start);   
    start = next;           
end
fprintf('%d\n',dest); % print out the destination
selectedNode = [selectedNode,dest];
selectedNode
fprintf('The length of the shorest path:%f\n',dist);
end
 

此部分参考:

乐观的lishan最短路径 Dijkstra算法的Matlab代码实现_乐观的lishan的博客-CSDN博客_dijkstra matlab

连点成线函数:drawLine.m



function [] = drawLine(selectedNode,mapping)

% step5: draw the line

pathlength = size(selectedNode,2)

for i=1:pathlength-1
    line([mapping(1,selectedNode(i)),mapping(1,selectedNode(i+1))], ...
        [mapping(2,selectedNode(i)),mapping(2,selectedNode(i+1))], ...
        'linewidth',3,'color','b')
end

设置线段的颜色,粗细。在‘视觉地图’中呈现出最短路径。

  • 10
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值