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 % 对第一行进行判断,除去(1,1)与终点(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 % 对(1,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);
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