MATLAB迷宫算法 自动生成迷宫并可视化寻找出路

迷宫程序是新手常用的练习算法之一,迷宫生成与循迹的快慢取决于所建立的模型的好坏。本文介绍一种数学模型,用以自动生成(任意规模)的迷宫并可视化寻找最优出路。
废话不多说,都在代码里,原理很简单,可以仔细阅读代码
效果图如下:(迷宫大小可自行设置)
在这里插入图片描述

本文代码在MATLAB2016码出来的,若有问题请检查函数的使用

%%%%%***************迷宫程序*************************
%%%****(包括自动生成迷宫以及可视化寻找出路)************
clc
close all
clear all
%%%迷宫规模ak X ak,并规定寻迹时行走速度
ssss=0.02;%%速度
ak=60;%%迷宫规模(ak*ak)
CS12=1;%%是否展示循迹过程(1:是,其他:否)
%%%*****************主程序***************************
C=[1,ak];%%出口
R=[ak,1];%%入口
x0=[0 ak ak 0 0];
y0=[0 0 ak ak 0];
plot(x0,y0)%%画出基本画框
hold on
C1=[C(1)-1,C(1),C(1),C(1)-1,C(1)-1
    C(2)-1,C(2)-1,C(2),C(2),C(2)-1];
fill(C1(1,:),C1(2,:),'g')
hold on
R1=[R(1)-1,R(1),R(1),R(1)-1,R(1)-1
    R(2)-1,R(2)-1,R(2),R(2),R(2)-1];
fill(R1(1,:),R1(2,:),'R')%%填充出入口
set(gcf,'Unit','normalized','Position',[0,0,0.6,1])
hold on
axis([0,ak,0,ak]);%%发图大小
ok=1;
% for mmm=1:1
% % while ok~=0
aaaa=fix(rand(ak,ak)*4);%%随机生成墙体矩阵
bbbb=tril(aaaa,-1)+triu(aaaa',0);
x1=bbbb;
%%%强行约束出入口,主要是保证能够进出 出入口
x1(R(1),R(2))=3;
x1(R(1),R(2)+1)=3;
x1(R(1)-1,R(2))=2;
x1(R(1)-1,R(2)+1)=x1(R(1)-1,R(2)+2);

x1(C(1),C(2))=0;
x1(C(1),C(2)-1)=1;
x1(C(1)+1,C(2))=0;
x1(C(1)+1,C(2)-1)=x1(C(1)+2,C(2)-1);
%%%for循环内部的作用为:提高迷宫的可解性,但是会缺少灵魂
% for i=3:length(x1)-2
% %     x1(i,length(x1)-i+1)=2;
% %     x1(i-1,length(x1)-i)=1;
% %     x1(i-1,length(x1)-i+2)=0;
%     x1(i,length(x1)-i+2)=x1(i-1,length(x1)-i+1)+2;
% %     x1(i,length(x1)-i)=x1(i+1,length(x1)-i+1)+1;
%     x1(i+1,length(x1)-i+1)=x1(i-2,length(x1)-i+1)+0;
% %     x1(i-1,length(x1)-i+1)=x1(i+2,length(x1)-i+1)+1;
% end

k=length(x1(1,:));
%%%画隔板******并记录每面墙的数据LJ ****最终将墙体的全局信息存入矩阵SD****
for i=1:k
    for j=1:k
        switch x1(i,j)+1
        case 1
            plot([i,i-1],[j,j],'color','b','linewidth',1)
            LJ(2*i,2*j+1)=1;
        case 2
            plot([i-1,i-1],[j,j-1],'color','b','linewidth',1)
            LJ(2*i-1,2*j)=1;
        case 3
            plot([i,i-1],[j-1,j-1],'color','b','linewidth',1)  
            LJ(2*i,2*j-1)=1;
        case 4
            plot([i,i],[j,j-1],'color','b','linewidth',1)
            LJ(2*i+1,2*j)=1;
        end
    end
end
LJ(1,:)=ones;
LJ(:,1)=ones;
LJ(2*k+1,:)=ones;
LJ(:,2*k+1)=ones;
SD=LJ;
SD(R)=SD(R)+1;
SD(C)=SD(C)+1;
xx=R(1);
yy=R(2);
h1=plot(xx,yy,'color','g','linewidth',3);
hold on
%%寻找出路部分*********上下左右的循迹方向具有不同优先级
aac=0;
GJ=zeros(2,1e3);
while xx~=C(1)||yy~=C(2)
    az=[SD(2*xx,2*yy+1),SD(2*xx-1,2*yy),SD(2*xx,2*yy-1),SD(2*xx+1,2*yy)];
    if min(az)<1
        wz=min(find(az==min(az)));
    else
        wz=[];
    end
    if isempty(wz)==1
        error('抱歉,已无路可走') 
        close all
        clear
    else
%%%选择移动方向(优先级依次为上,左,下,右)**
    switch wz
    case 1
        xx1=xx;yy1=yy+1;
    case 2
        xx1=xx-1;yy1=yy;
        case 3
        xx1=xx;yy1=yy-1;
        case 4
        xx1=xx+1;yy1=yy;
    end
    aac=aac+1;
    GJ(:,aac)=[xx1
        yy1];%%%记录轨迹
%%%方向已选定为xx1,yy1*************
    end
    %以下的一个set和四个plot以及pause作用均是体现内部循迹原理的作用
    if CS12==1
    set(h1,'Xdata',[xx-0.5,xx1-0.5],'Ydata',[yy-0.5,yy1-0.5])
    hold on
    km=1/3;
        switch wz
        case 1
            plot([xx,xx-1],[yy,yy],'-.','color','r','linewidth',1)
            SD(2*xx,2*yy+1)=SD(2*xx,2*yy+1)+km;
        case 2
            plot([xx-1,xx-1],[yy,yy-1],'-.','color','r','linewidth',1)
            SD(2*xx-1,2*yy)=SD(2*xx-1,2*yy)+km;
        case 3
            plot([xx,xx-1],[yy-1,yy-1],'-.','color','r','linewidth',1)  
            SD(2*xx,2*yy-1)=SD(2*xx,2*yy-1)+km;
        case 4
            plot([xx,xx],[yy,yy-1],'-.','color','r','linewidth',1)
            SD(2*xx+1,2*yy)=SD(2*xx+1,2*yy)+km;
        end
    xx=xx1;
    yy=yy1;
    pause(0.01)
    else
    km=1/3;
        switch wz
        case 1
            SD(2*xx,2*yy+1)=SD(2*xx,2*yy+1)+km;
        case 2
            SD(2*xx-1,2*yy)=SD(2*xx-1,2*yy)+km;
        case 3
            SD(2*xx,2*yy-1)=SD(2*xx,2*yy-1)+km;
        case 4
            SD(2*xx+1,2*yy)=SD(2*xx+1,2*yy)+km;
        end
    xx=xx1;
    yy=yy1;
    end
%     pause(ssss/100)
end
%%**************寻迹之后规划最优路径***********
sl=min(find(GJ(1,:)==0))-1;
GJ(:,sl+1:end)=[];
% GG=GJ;
% [b,location] = unique(GG.','rows','first');
%     res = sortrows([location,b]);
%     GJ=res(:,2:size(res,2)).'%%%此上三句是消除重复行走的位置
% hold off
for mmk=1:length(GJ(1,:))-1
    for mk1=mmk+1:length(GJ(1,:))
        if GJ(:,mmk)==GJ(:,mk1)
            GJ(:,mmk:mk1-1)=zeros(2,mk1-mmk);
        end
    end
end
GJ(:,find(GJ(1,:)==0))=[];
GJ=[R.',GJ];
for mk=1:length(GJ(1,:))-1
    plot([GJ(1,mk)-0.5,GJ(1,mk+1)-0.5],[GJ(2,mk)-0.5,GJ(2,mk+1)-0.5],'color','g')
    hold on
    if CS12==1
    pause(ssss)
    else
        pause(ssss/2)
    end
end





评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值