MATLAB遗传算法规划机器人路径(栅格)源码

MATLAB遗传算法规划机器人路径(栅格)源码

    • 运行结果如图
    • 代码
    • 修改于2019-4-2
    • 改于2019-4-4-22

#网上路径规划的代码很多,但是简单栅格路径的规划问题,各位大佬都懒得写,小弟为你奉上,敬请食用(此代码是根据大佬的源码改写而成,由于不知大佬链接,所以就不放了,但是大佬是开源的)

主要包括以下几个部分
text1.m主函数
chack.m边界检测函数
calfitvalue.m适用度函数
crossover.m交叉函数
mutation.m变异函数
poppinit.m初始化族群
select.m
best.m

运行结果如图

链接: link.

图片: Alt

带尺寸的图片:
MATLAB遗传算法规划机器人路径(栅格)源码_第1张图片
MATLAB遗传算法规划机器人路径(栅格)源码_第2张图片
Alt

代码

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:主函数text1.m
%%入口参数:无
%%出口参数:无
%%说明:无
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear 
pc=0.7;   %交叉概率
pm=0.006; %变异概率

[x,y]=popinit(500,10);   %产生初始种群
D=calfitvalue(x,y);      %计算种群适应度
for i=1:1:200           %设置进化代数
[newx,newy]=selection(x,y,D);              %选择
[newx,newy]=crossover(newx,newy,pc);       %交叉
[newx,newy]=mutation(newx,newy,pm);        %变异
D=calfitvalue(newx,newy);                  %重新计算适应度
[newx,newy]=selection(newx,newy,D);        %选择     保证交叉变异后的种群都不经过障碍物
D=calfitvalue(newx,newy);                  %重新计算适应度    选择之后的种群适应度也已经发生变化。所以必须重新计算
[bestx,besty,bestfit]=best(newx,newy,D);   %选择最佳个体
bbestx(i,:)=bestx;                         %保存最佳个体
bbesty(i,:)=besty;
bbestfit(i)=bestfit;
x=newx;
y=newy;
end
[bbbestfit,I]=max(bbestfit)                %计算选择出来的最佳个体中 适应度最大的个体,作为最优值输出
bbbestx=bbestx(I,:);
bbbesty=bbesty(I,:);

%根据适应度函数中建立的环境模型,填充障碍物
% fill([8,12,12,8,8],[8,8,12,12,8],[0,0,0])
% hold on
% fill([2,6,6],[2,2,4],[0,0,0])
% hold on
% fill([4,7,2],[6,15,15],[0,0,0])
% hold on
% fill([9,16,16],[16,10,18],[0,0,0])
% hold on
% fill([18,7,12],[1,6,2],[0,0,0])
% hold on

fill([2,4,4,2,2],[0,0,2,2,0],[0,0,0])
hold on
fill([0,2,2,4,4,0,0],[6,6,4,4,8,8,6],[0,0,0])
hold on
fill([2,6,6,2,2],[12,12,14,14,12],[0,0,0])
hold on
fill([0,2,2,0,0],[18,18,20,20,18],[0,0,0])
hold on
fill([6,10,10,6,6],[2,2,6,6,2],[0,0,0])
hold on
fill([8,10,10,8,8],[16,16,18,18,16],[0,0,0])
hold on
fill([10,12,12,10,10],[12,12,14,14,12],[0,0,0])
hold on
fill([12,14,14,12,12],[6,6,8,8,6],[0,0,0])
hold on
fill([12,14,14,12,12],[18,18,20,20,18],[0,0,0])
hold on
fill([14,18,18,16,16,14,14],[12,12,14,14,16,16,12],[0,0,0])
hold on
fill([16,20,20,16,16],[2,2,4,4,2],[0,0,0])
hold on
fill([18,20,20,18,18],[8,8,10,10,8],[0,0,0])
hold on

%%画出最有路径的路线
plot(bbbestx,bbbesty,'r-')




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:边界相角检测函数 chack.m
%%入口参数:两条线段的顶点。例如 判断线段PQ 与 XY 是否相交,其中 P(x1,y1)、Q(x2,y2)、X(x3,y3)、Y(x4,y4)
                            %%则函数参数设置为:chack(x1,y1,x2,y2,x3,y3,x4,y4)
%%出口参数: 是否相交 0:不相交  1:相交
%%说明:
    %%该函数可以检测两条线断是否相交,当入口参数是向量的时候,可以同时检测多条线段是否相交。
    %%该函数入口参数可以为向量,向量可以是列向量也可以是行向量,但必须保证所有入口参数的维度相同。
    %%检测方式采用相互跨立实验实现。当两条线段相互跨立时,则两线段在二维平面中相交。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [pop]=chack(x1,y1,x2,y2,x3,y3,x4,y4)
    [px,py]=size(x1);
    p=max(px,py);      %实现行向量列向量都可以进行检测
    [px,py]=size(x3);
    q=max(px,py);
    for j=1:1:q    %检测线段相交的次数
    for i=1:1:p    %检测所有种群相邻点连成的线段是否与当前障碍物边界相交
        pabx=x4(j)-x3(j);
        paby=y4(j)-y3(j);
        pacx=x2(i)-x3(j);
        pacy=y2(i)-y3(j);
        padx=x1(i)-x3(j);
        pady=y1(i)-y3(j);
        m=pabx*pacy-paby*pacx;
        n=pabx*pady-paby*padx;
        
        pcdx=x1(i)-x2(i);
        pcdy=y1(i)-y2(i);
        pcax=x3(j)-x2(i);
        pcay=y3(j)-y2(i);
        pcbx=x4(j)-x2(i);
        pcby=y4(j)-y2(i);
        mm=pcdx*pcay-pcdy*pcax;
        nn=pcdx*pcby-pcdy*pcbx;
        if m*n<=0 && mm*nn<=0     %相交
            pop(j,i)=1;           %将结果存到矩阵[pop]中。
        else                      %显然矩阵[pop]是一个q行p列的矩阵。
            pop(j,i)=0;
        end
    end
    end
end




`%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:适应度函数 calfitvalue.m
%%入口参数:初始种群
%%出口参数:种群适应度值    一维列向量
%%说明:
    %%种群适应度以种群路径大小作为主要参考标准,路径越短,适应度越大。以一个较大的数减去种群路径长度作为种群的适应度。
    %%有障碍物的情况下的环境建模,在此处进行。向量x3、y3、x4、y4即为障碍物边界,并对所有种群的相邻点进行干涉测试,如果有交点则直接将其适应度设为0。
    %%函数in=inpolygon(x(j,:),y(j,:),xv,yv);
    %%为检测种群点是否在障碍物内部,其实有了上面的干涉检测,该部分程序不用也可以。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function fitvalue=calfitvalue(x,y)
yv=[10,12,12,10,10];
xv=[12,12,14,14,12];
[px,py]=size(x);
% x3=[8 8 12 12 2 6 6 4 7 2 9 16 16 18 7 12];         %设置环境模型
% y3=[8 12 12 8 2 2 4 6 15 15 16 10 18 1 6 2];        %x3、y3、x4、y4 为所有障碍物边界的相邻顶点组成的线段。
% x4=[8 12 12 8 6 6 2 7 2 4 16 16 9 7 12 18];
% y4=[12 12 8 8 2 4 2 15 15 6 10 18 16 6 2 1];
x3=[2,4,4,2,2,4,4,0,0,2,2,6,6,2,0,2,2,0,6,10,10,6,8,10,10,8,12,14,14,12,10,12,12,10,12,14,14,12,14,18,18,16,16,14,16,20,20,16,18,20,20,18];
y3=[0,0,2,2,4,4,8,8,6,6,12,12,14,14,18,18,20,20,2,2,6,6,16,16,18,18,6,6,8,8,12,12,14,14,18,18,20,20,12,12,14,14,16,16,2,2,4,4,8,8,10,10];
x4=[4,4,2,2,4,4,0,0,2,2,6,6,2,2,2,2,0,0,10,10,6,6,10,10,8,8,14,14,12,12,12,12,10,10,14,14,12,12,18,18,16,16,14,14,20,20,16,16,20,20,18,18,];
y4=[0,2,2,0,4,8,8,6,6,4,12,14,14,12,18,20,20,18,2,6,6,2,16,18,18,16,6,8,8,6,12,14,14,12,18,20,20,18,12,14,14,16,16,12,2,4,4,2,8,10,10,8];

% fill([8,12,12,8,8],[8,8,12,12,8],[0,0,0])
% hold on
% fill([2,6,6],[2,2,4],[0,0,0])
% hold on
% fill([4,7,2],[6,15,15],[0,0,0])
% hold on
% fill([9,16,16],[16,10,18],[0,0,0])
% hold on
% fill([18,7,12],[1,6,2],[0,0,0])
% hold on

for j=1:1:px
    in=inpolygon(x(j,:),y(j,:),xv,yv);   %判断 点 是否在障碍物内
    for i=1:1:py-1
        x1(i)=x(j,i);
        y1(i)=y(j,i);
    end
    for i=2:1:py
        x2(i-1)=x(j,i);
        y2(i-1)=y(j,i);
    end
    ch=chack(x1,y1,x2,y2,x3,y3,x4,y4);   %判断种群相邻点连成的线段是否与所有障碍物边界相交
    if sum(in)>0 ||sum(sum(ch))>0        %如果矩阵 [ch] 所有元素的和不等于0,则说明存在某一条线段经过障碍物边界。
        dd(j)=0;
    else
        for i=1:1:py-1
            d(i)=sqrt((x(j,i+1)-x(j,i)).^2+(y(j,i+1)-y(j,i)).^2);     %如果不经过障碍物,则求取该个体的路径长度,最为适应度计算依据
        end
        dd(j)=200-sum(d);       %计算个体适应度
    end
end
fitvalue=dd';      %返回列向量
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:交叉函数 crossover.m
%%入口参数:初始种群    交叉概率
%%出口参数:新种群
%%说明:
    %%通过随机数的方式决定某一种族是否交叉。 rand

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:变异函数 mutation.m
%%入口参数:初始种群 变异概率
%%出口参数:新种群
%%说明:
%%通过随机数的方式决定某一种族是否变异。 rand %%变异方式,随机产生一个在基因数量范围内的整数,作为变异点,随机产生一个新的点替换原来的点。。
%%变异完成之后的种群还必须进行从大到小的排序。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [newx,newy]=mutation(x,y,pm)

[px,py]=size(x);
newx=x;
newy=y;
for i=1:1:px
if(rand

之前程序并不完整,需要添加后面两段程序

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:选择函数 selection.m
%%说明:
function [newx,newy]=selection(x,y,fitvalue)

totalfit=sum(fitvalue); %求适应值之和
fitvalue1=fitvalue/totalfit; %单个个体被选择的概率
fitvalue=cumsum(fitvalue1); %如 fitvalue=[1 2 3 4],则 cumsum(fitvalue)=[1 3 6 10] 
[px,py]=size(fitvalue);
ms=sort(rand(px,1)); %从小到大排列       生成一个 px行 1列 的随机矩阵,然后从小到大排列
fitin=1;
newin=1;
while newin<=px
if (ms(newin))0  %fitvalue1(fitin)>0 保证适应度为0的个体不被选中
newx(newin,:)=x(fitin,:);
newy(newin,:)=y(fitin,:);
newin=newin+1;
else
fitin=fitin+1;
end

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:最有个体选择函数 best.m
%%入口参数:初始种群    种群适应度
%%出口参数:最佳个体  最佳个体适应度
%%说明:
    %%按照适应度大小进行选择最佳个体。适应度最大的个体将被选出,作为函数返回值返回。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [bestx,besty,bestfit]=best(x,y,fitvalue)
    [px,py]=size(x);
    bestx=x(1,:);
    besty=y(1,:);
    bestfit=fitvalue(1);
    for i=2:px
        if fitvalue(i)>bestfit
            bestx=x(i,:);
            besty=y(i,:);
            bestfit=fitvalue(i);
        end
    end
end

修改于2019-4-2

在之前mutatioin.m末尾添加了
for i=1:1:px
newx(i,:)=sort(newx(i,:));
newy(i,:)=sort(newy(i,:));
end
end
且将原来popinit.m的最后一句话
function [newx,newy]=selection(x,y,fitvalue)删除
再次运行,可以成功

改于2019-4-4-22

目前本人主要在学习点云处理相关方面的东西,由于作者菜鸡,并非MATLAB大神,所以对于遗传算法相关问题确实难以解答,各位可以查阅其他资料。另:此代码只是为了交一次作业而改写,抱歉各位不能回答你们的具体问题。

你可能感兴趣的:(MATLAB)