matlab 穷举法寻找路径

map=
[0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 1 1 0 1 1 0 1 1 0
0 1 1 0 1 1 0 1 1 0 1 1 0
0 1 1 0 0 0 0 0 0 0 1 1 0
0 1 1 0 1 1 0 1 1 0 1 1 0
0 1 1 0 1 1 0 1 1 0 1 1 0
0 1 1 0 0 0 0 0 0 0 1 1 0
0 1 0 1 1 1 0 1 1 1 0 1 0
0 0 1 1 1 1 0 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0]

imshow(map);

在这里插入图片描述
左下角为起点,右上角为终点,只允许向上,向右,向右上前行。

穷举法寻找所有可通行路径:

function [ALLPATH]=findway(begnning_x,begnning_y,ending_x,ending_y,map)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:穷举法寻找路径 findway.m
%%入口参数:起始点行数 begnning_x 起始点列数 begnning_y  终止点行列数  地图 map
%%续入口参数: x,y为整数,map为二维0/1矩阵,0可通行,1不可通行
%%出口参数:所有的可通行路径 ALLPATH
%%函数功能说明:
    %%地图是二维矩阵,0表示可以通行,1表示不可以通行
    %%前进方向只有三个:右,上,右上。所以,最好把起点放置在map矩阵的左下角,终点放置在右上角
%%by Sebastian Li, Otc.29.2020  At ZZU
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

PATH={[begnning_x,begnning_y]};   % x为行,y为列数
ALLPATH={[]};
while  size(PATH,2)~=0  
   next_path=[];
   for i=1:size(PATH,2) % 对每一条路径
    path=cell2mat(PATH(i));   % path 其中一条路径 两列:第一列为行数 第二列为列数
    if path(end,:)==[ending_x,ending_y]     % 如果是通往终点的路径,保存
        ALLPATH=cat(2,ALLPATH,{path});
    else                                    % 如果不是,继续优化
        path1=[];
        path2=[];   
        path3=[];
        begnning_x=path(end,1);
        begnning_y=path(end,2);    % x,y 当前路径的起点
        
        if begnning_x>1   % 上行
            if map(begnning_x-1,begnning_y)==0   
                path1=path;
                path1=[path1;[begnning_x-1,begnning_y]];
            end    
        end 
        if begnning_y<size(map,2)   % 右行
            if map(begnning_x,begnning_y+1)==0
                path2=path;
                path2=[path2;[begnning_x,begnning_y+1]];
            end    
        end
        if begnning_x>1 && begnning_y<size(map,2)   % 右上行
            if map(begnning_x-1,begnning_y+1)==0
                path3=path;
                path3=[path3;[begnning_x-1,begnning_y+1]];
            end
        end
        cell_path=cat(2,{path1},{path2},{path3}); % 储存新路径
        next_path=cat(2,next_path,cell_path);
        next_path(cellfun(@isempty,next_path))=[];
    end      
   end
   PATH=next_path;
end
ALLPATH(1)=[];

寻找路口的位置:

function [crossroads]=find_crossroads(map)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:寻找路口 find_crossroads.m
%%入口参数:地图 map
%%出口参数:路口坐标 crossroads
%%函数功能说明:
    %%地图是二维矩阵,0表示可以通行,1表示不可以通行
    %%注意:十字交叉路口的上下左右都是路口,拐角也是路口
%%by Sebastian Li, Otc.29.2020  At ZZU
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
crossroads=[];
for i=2:size(map,1)-1   % 除去边框,对主体
    for j=2:size(map,2)-1
        if map(i,j)==0
            m1=map(i-1,j)+map(i,j+1);   % 交点的判定:对于一个像素点,其周围8个邻近像素点,有任意两个距离近的点都为0
            m2=map(i+1,j)+map(i,j-1);
            m3=map(i+1,j)+map(i,j+1);
            m4=map(i-1,j)+map(i,j-1);
            m5=map(i-1,j-1)+map(i-1,j);
            m6=map(i-1,j)+map(i-1,j+1);
            m7=map(i-1,j+1)+map(i,j+1);
            m8=map(i,j+1)+map(i+1,j+1);
            m9=map(i+1,j+1)+map(i+1,j);
            m10=map(i+1,j)+map(i+1,j-1);
            m11=map(i+1,j-1)+map(i,j-1);
            m12=map(i,j-1)+map(i-1,j-1);
            m=[m1;m2;m3;m4;m5;m6;m7;m8;m9;m10;m11;m12];
            if size(find(m==0),1)~=0
                crossroads(end+1,:)=[i,j];
            end
        end
    end
end



for i=1   % 对第一行进行判断,除去(11)与终点(1,end)
    for j=2:size(map,2)-1
        if map(i,j)==0
            m2=map(i+1,j)+map(i,j-1);
            m3=map(i+1,j)+map(i,j+1);
            m8=map(i,j+1)+map(i+1,j+1);
            m9=map(i+1,j+1)+map(i+1,j);
            m10=map(i+1,j)+map(i+1,j-1);
            m11=map(i+1,j-1)+map(i,j-1);
            m=[m2;m3;m8;m9;m10;m11];
            if size(find(m==0),1)~=0
                crossroads(end+1,:)=[i,j];
            end
        end
    end
end


i=1;
j=1;
if map(i,j)==0   % 对(11)
    m3=map(i+1,j)+map(i,j+1);
    m8=map(i,j+1)+map(i+1,j+1);
    m9=map(i+1,j+1)+map(i+1,j);
    m=[m3;m8;m9];
    if size(find(m==0),1)~=0
        crossroads(end+1,:)=[i,j];
    end
end


for j=1   % 对第一列,除去首尾
    for i=2:size(map,1)-1
        m1=map(i-1,j)+map(i,j+1);
        m3=map(i+1,j)+map(i,j+1);
        m6=map(i-1,j)+map(i-1,j+1);
        m7=map(i-1,j+1)+map(i,j+1);
        m8=map(i,j+1)+map(i+1,j+1);
        m9=map(i+1,j+1)+map(i+1,j);
        m=[m1;m3;m6;m7;m8;m9];
       if size(find(m==0),1)~=0
            crossroads(end+1,:)=[i,j];
       end
    end
end

i=size(map,1);
j=1;
if map(i,j)==0   % 对第一列的最后一个
    m1=map(i-1,j)+map(i,j+1);
    m6=map(i-1,j)+map(i-1,j+1);
    m7=map(i-1,j+1)+map(i,j+1);
    m=[m1;m6;m7];
    if size(find(m==0),1)~=0
        crossroads(end+1,:)=[i,j];
    end
end

for i=size(map,1)  % 对最后一行,去首尾
    for j=2:size(map,2)-1
        m1=map(i-1,j)+map(i,j+1);
        m4=map(i-1,j)+map(i,j-1);
        m5=map(i-1,j-1)+map(i-1,j);
        m6=map(i-1,j)+map(i-1,j+1);
        m7=map(i-1,j+1)+map(i,j+1);
        m12=map(i,j-1)+map(i-1,j-1);
        m=[m1;m4;m5;m6;m7;m12];
        if size(find(m==0),1)~=0
        crossroads(end+1,:)=[i,j];
        end
    end
end

i=size(map,1);
j=size(map,2);
if map(i,j)==0   % 对最后一列最后一行
   m4=map(i-1,j)+map(i,j-1);
   m5=map(i-1,j-1)+map(i-1,j);
   m12=map(i,j-1)+map(i-1,j-1);
   m=[m4;m5;m12];
   if size(find(m==0),1)~=0
        crossroads(end+1,:)=[i,j];
   end
end

for j=size(map,2)   % 对最后一列
    for i=2:size(map,1)-1
         m2=map(i+1,j)+map(i,j-1);
         m4=map(i-1,j)+map(i,j-1);
         m5=map(i-1,j-1)+map(i-1,j);
         m10=map(i+1,j)+map(i+1,j-1);
         m11=map(i+1,j-1)+map(i,j-1);
         m12=map(i,j-1)+map(i-1,j-1);
         m=[m2;m4;m5;m10;m11;m12];
         if size(find(m==0),1)~=0
             crossroads(end+1,:)=[i,j];
         end
    end
end
end

判断路径的长度及所经的路口数

[ALLPATH]=findway(begnning_x,begnning_y,ending_x,ending_y,map);
[crossroads]=find_crossroads(map);
for i=1:size(ALLPATH,2)
    path=cell2mat(ALLPATH(i));
   [s]=qiutong(crossroads,path);
   length=size(path,1);
   ss(i,:)=[length,s];
end

附:

function [s]=qiutong(s1,s2)

% s1=crossroads;
% s2=path;
a=unique(s2(:,1));
s=0;
for i=1:size(a,1)
    b=a(i);
    a1=find(s1(:,1)==b);
    a11=s1(a1,:);
    a2=find(s2(:,1)==b);
    a22=s2(a2,:);
    for j=1:size(a22,1)
        c1=a22(j,2);
        m=size(find(a11(:,2)==c1),1);
        s=s+m;
    end
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值