遗传算法(GA)_详解笔记(2)(多个坐标点的路径规划)

首先将坐标数据放入一个矩阵中

Coornidate=[103.73 36.03;
103.73 36.03;
101.74 36.56;
104.06 30.67;
114.48 38.03;
102.73 25.04;
106.71 26.57;
114.31 30.52;
113.65 34.76;
117.00 36.65;
118.78 32.04;
117.27 31.86;
120.19 30.26;
115.89 28.68;
119.30 26.08;
113.23 23.16;
113.00 28.21;
110.35 20.02;
123.38 41.80;
125.35 43.88;
126.63 45.75;
112.53 37.87;
108.95 34.27;
121.30 25.03;
116.46 39.92;
121.48 31.22;
106.54 29.59;
117.20 39.13;
111.65 40.82;
108.33 22.84;
91.11 29.97;
106.27 38.47;
87.68 43.77;
114.17 22.28;
113.54 22.19]   %网上搜到的35个城市保留两位小数的位置坐标

上面的坐标数据可以直接进行替换 

N=size(Coordinate,1);    %输出Coordinate坐标矩阵的行数,有35行,也就是矩阵里包含的城市个数
D=zeros(N);    %生成35X35的全零数组,目的是为了存储各个城市间的距离数据

下面计算各城市之间的距离

%%%%%%%%%%%%%%计算任意两个城市距离,并将其存储到D矩阵当中%%%%%%%%%%%%%%
for i=1:N
    for j=1:N
        D(i,j)=((Coordinate(i,1)-Coordinate(j,1))^2+(Coordinate(i,2)-Coordinate(j,2))^2)^0.5;
    end
end
%D(i,j)=((第一个城市的横坐标-第j个城市的横坐标)^2+(第i个城市的纵坐标-第j个城市的纵坐标)^2)^0.5

 

step1:这里少部分代码的功能不能直接理解,因为这是初始化-参数预设,一些后面更新的东西都会统一放在前面,所以感觉很无厘头是吧,请慢慢往后看就知道了。。。。。。


Np=200;   %设置初始种群数量
G=1500;   %设置最大进化代数
f=zeros(Np,N);   %生成一个用于储存种群的200*35的全零数组
F=[];     %种群更新中间存储

for i=1:Np
    f(i,:)=randperm(N)   ;%随机生成初始种群, randperm(N) 返回行向量,其中包含从1到N没有重复元素的整数随机排列
end

R=f(1,:);    %将f矩阵的第一行存入R中
len=zeros(Np,1);  %储存路径长度
fitvalue=zeros(Np,1);  %储存归一化适应度值
gen=0;


step2:本章最重要的部分,以一条循环语句贯穿始终


while gen<G    
    %%%%%%%%%%%%%%%%%%%%%计算路径长度%%%%%%%%%%%%%%
    for i=1:Np
        len(i,1)=D(f(i,N),f(i,1));
        for j=1:(N-1)
            len(i,1)=len(i,1)+D(f(i,j),f(i,j+1));
        end
    end
    lenmax=max(len);
    lenmin=min(len);    %len=min(A) 是包含每一列的最小值的行向量
    %%%%%%%%%%%%%%%更新最短路径%%%%%%%%%%%%%%%%%%%%%%%
    rr=find(len==lenmin);   %找出len矩阵当中数值等于minlen的元素下标并赋值给rr
    R=f(rr(1,1),:);
    
f=5    23    14    31    11     6    13     3    28    25     2    27    22    19     4    24    21    15     8    29     7    10    20    26     9    17    12    16    30   18     1
   


在执行step2的%%%%%计算路径长度%%%%%之前在f=zeros(Np,N)的作用下生成的一组数据,这里把他当成一个在杂乱无章的个体,模拟的实际情况是一种从某个城市遍历所有城市的距离加和,这是混乱的加和,也是一种随意的枚举,这里就是只枚举了Np个随意的路径规划方案。

step3:适应度的计算:非常普通的归一化

%%%%%%%%%%%%%%%%计算归一化适应度值%%%%%%%%%%%%%%%%%
    for i =1:length(len)
        fitvalue(i,1)=1-(len(i,1)-lenmin)/(lenmax-lenmin+0.001);
    end

step4:选择操作

 %%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%
    nn=0;
    for i=1:Np
        if fitvalue(i,1)>=rand
            nn=nn+1;
            F(nn,:)=f(i,:);
        end
    end    %rand函数返回一个在区间 (0,1) 内均匀分布的随机数。随机数会决定200个体中哪些可以参与进化的并将其存储进F矩阵当中
    [aa,bb]=size(F);   %返回矩阵的维度mXn,例如,如果A是一个3×4矩阵,则size(A)返回向量[3 4]。
    while aa<Np
        nnper=randperm(nn);   %从1到nn的一个随机排列,nnper就成为了一个行向量
        A=F(nnper(1),:);   %选中nnper中第一个元素数值在F矩阵中的行数赋给A,A成为了F矩阵当中存储的某个个体
        B=F(nnper(2),:);   %选中nnper中第二个元素数值在F矩阵中的行数赋给B,B成为了F矩阵当中存储的某个个体


这部分最终的结果就是随机选出了A、B两个随机个体,为下面的交叉操作做好准备

step5:交叉操作

 %%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%
        W=ceil(N/10);   %ceil函数将X的每个元素四舍五入到大于或等于该元素的最接近整数。这里W=4
        p=unidrnd(N-W+1);   %unidrnd,产生一组离散均匀随机整数。这里p=unidrnd(32)产生一个随机数
        for i =1:W
            x=find(A==B(p+i-1));   %find查找的是索引,是A中和B()相同元素的下标,赋给x
            y=find(B==A(p+i-1));   %find查找的是索引,是B中和A()相同元素的下标,赋给y
            temp=A(p+i-1);
            A(p+i-1)=B(p+i-1);
            B(p+i-1)=temp;
            temp=A(x);
            A(x)=B(y);
            B(y)=temp;   
        end

 进行了2次三步交换,就是将A()和B()两个进行交换,交换第一次后会出现重复,所以再进行一次交换,最终实现不重复。但这种交换不是等位基因的交换,比较草率

step6:变异操作

 %%%%%%%%%%%%%%%%%%%%%变异操作%%%%%%%%%%%%%%%%%%%%
        p1=floor(1+N*rand());  %floor(X)将X的每个元素四舍五入到小于或等于该元素的最接近整数
        p2=floor(1+N*rand());
        while p1==p2
            p1=floor(1+N*rand());
            p2=floor(1+N*rand());
        end
        tmp=A(p1);
        A(p1)=A(p2);
        A(p2)=tmp;
        tmp=B(p1);
        B(p1)=B(p2);
        B(p2)=tmp;
        F=[F;A;B];
        [aa,bb]=size(F);
    end   %因为淘汰,所以F的行数小于200个,所以将变异后A、B加入进去,组成新种群,只要F的行数小于Np,就循环进化过程,直到种群数满足200,此一代的选择、交叉、变异等遗传进化操作暂停
    if aa>Np
        F=F(1:Np,:);
    end
    f=F;   %将新种群200个个体赋给矩阵f,f是种群矩阵
    f(1,:)=R;    %之前的R是最优个体,这里把种群矩阵f中的第一个个体换成最优个体
    clear F;
    gen=gen+1;
    Rlength(gen)=lenmin;    %记录每代的最优个体,就是每一波200个路径规划方案的中的最优方案
end

step7:绘图等后续操作

figure     %%%%这里画出各城市坐标和路径规划线路图
for i=1:N-1
    
    plot([Coordinate(R(i),1),Coordinate(R(i+1),1)],[Coordinate(R(i),2),Coordinate(R(i+1),2)],'bo-');  %依次连接最优方案中的线路各点,用蓝色线连接
    
    hold on;   %hold-添加新绘图时保留当前绘图
end

plot([Coordinate(R(N),1),Coordinate(R(1),1)],[Coordinate(R(N),2),Coordinate(R(1),2)],'ro-');   %收尾点连接,用红色线

title(['优化最短距离:',num2str(lenmin)]);  %num2str将数字转换为字符数组,为了标题输出

figure    %%%%%这里画迭代次数,即进化过程图
plot(Rlength)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度函数进化曲线')


%%tips:这里bo-,ro-的-是连线功能

Result!!!!!!!

977a610ff1cb49af88bd5a3d27cdffa0.png

4ecb6e3759d444f0b8b0881ccfd78617.png 175.228这个可能是目前最好的结果,完美的一圈TSP。

 

值得注意的是,此GA非常基础、常规,没有在任何重要算子和步骤上进行优化,虽然看不出来。同时,GA在大规模求解TSP\VRP问题上鲁棒优化是重要方向,相信多RUN几次就能感觉到,太抖了哈哈哈哈哈 

最后发个全文,方便CV~·~~~~~~~~~

Coordinate=[103.73 36.03;
103.73 36.03;
101.74 36.56;
104.06 30.67;
114.48 38.03;
102.73 25.04;
106.71 26.57;
114.31 30.52;
113.65 34.76;
117.00 36.65;
118.78 32.04;
117.27 31.86;
120.19 30.26;
115.89 28.68;
119.30 26.08;
113.23 23.16;
113.00 28.21;
110.35 20.02;
123.38 41.80;
125.35 43.88;
126.63 45.75;
112.53 37.87;
108.95 34.27;
121.30 25.03;
116.46 39.92;
121.48 31.22;
106.54 29.59;
117.20 39.13;
111.65 40.82;
108.33 22.84;
91.11 29.97;
106.27 38.47;
87.68 43.77;
114.17 22.28;
113.54 22.19]   %网上搜到的35个城市保留两位小数的位置坐标
N=size(Coordinate,1);    %输出Coordinate坐标矩阵的行数,有35行,也就是矩阵里包含的城市个数
D=zeros(N);    %生成35X35的全零数组,目的是为了存储各个城市间的距离数据
%%%%%%%%%%%%%%计算任意两个城市距离,并将其存储到D矩阵当中%%%%%%%%%%%%%%
for i=1:N
    for j=1:N
        D(i,j)=((Coordinate(i,1)-Coordinate(j,1))^2+(Coordinate(i,2)-Coordinate(j,2))^2)^0.5;
    end
end
%D(i,j)=((第一个城市的横坐标-第j个城市的横坐标)^2+(第i个城市的纵坐标-第j个城市的纵坐标)^2)^0.5
Np=200;   %设置初始种群数量
G=1500;   %设置最大进化代数
f=zeros(Np,N);   %生成一个用于储存种群的200*35的全零数组
F=[];     %种群更新中间存储

for i=1:Np
    f(i,:)=randperm(N)   ;%随机生成初始种群, randperm(N) 返回行向量,其中包含从1到N没有重复元素的整数随机排列
end

R=f(1,:);    %将f矩阵的第一行存入R中
len=zeros(Np,1);  %储存路径长度
fitvalue=zeros(Np,1);  %储存归一化适应度值
gen=0;

while gen<G    
    %%%%%%%%%%%%%%%%%%%%%计算路径长度%%%%%%%%%%%%%%
    for i=1:Np
        len(i,1)=D(f(i,N),f(i,1));
        for j=1:(N-1)
            len(i,1)=len(i,1)+D(f(i,j),f(i,j+1));
        end
    end
    lenmax=max(len);
    lenmin=min(len);    %len=min(A) 是包含每一列的最小值的行向量
    %%%%%%%%%%%%%%%更新最短路径%%%%%%%%%%%%%%%%%%%%%%%
    rr=find(len==lenmin);   %找出len矩阵当中数值等于minlen的元素下标并赋值给rr
    R=f(rr(1,1),:);
    %%%%%%%%%%%%%%%%计算归一化适应度值%%%%%%%%%%%%%%%%%
    for i =1:length(len)
        fitvalue(i,1)=1-(len(i,1)-lenmin)/(lenmax-lenmin+0.001);
    end
%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%
    nn=0;
    for i=1:Np
        if fitvalue(i,1)>=rand
            nn=nn+1;
            F(nn,:)=f(i,:);
        end
    end    %rand函数返回一个在区间 (0,1) 内均匀分布的随机数。随机数会决定200个体中哪些可以参与进化的并将其存储进F矩阵当中
    [aa,bb]=size(F);   %返回矩阵的维度mXn,例如,如果A是一个3×4矩阵,则size(A)返回向量[3 4]。
    while aa<Np
        nnper=randperm(nn);   %从1到nn的一个随机排列,nnper就成为了一个行向量
        A=F(nnper(1),:);   %选中nnper中第一个元素数值在F矩阵中的行数赋给A,A成为了F矩阵当中存储的某个个体
        B=F(nnper(2),:);   %选中nnper中第二个元素数值在F矩阵中的行数赋给B,B成为了F矩阵当中存储的某个个体


 %%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%
        W=ceil(N/10);   %ceil函数将X的每个元素四舍五入到大于或等于该元素的最接近整数。这里W=4
        p=unidrnd(N-W+1);   %unidrnd,产生一组离散均匀随机整数。这里p=unidrnd(32)产生一个随机数
        for i =1:W
            x=find(A==B(p+i-1));   %find查找的是索引,是A中和B()相同元素的下标,赋给x
            y=find(B==A(p+i-1));   %find查找的是索引,是B中和A()相同元素的下标,赋给y
            temp=A(p+i-1);
            A(p+i-1)=B(p+i-1);
            B(p+i-1)=temp;
            temp=A(x);
            A(x)=B(y);
            B(y)=temp;   
        end
         %%%%%%%%%%%%%%%%%%%%%变异操作%%%%%%%%%%%%%%%%%%%%
        p1=floor(1+N*rand());  %floor(X)将X的每个元素四舍五入到小于或等于该元素的最接近整数
        p2=floor(1+N*rand());
        while p1==p2
            p1=floor(1+N*rand());
            p2=floor(1+N*rand());
        end
        tmp=A(p1);
        A(p1)=A(p2);
        A(p2)=tmp;
        tmp=B(p1);
        B(p1)=B(p2);
        B(p2)=tmp;
        F=[F;A;B];
        [aa,bb]=size(F);
    end   %因为淘汰,所以F的行数小于200个,所以将变异后A、B加入进去,组成新种群,只要F的行数小于Np,就循环进化过程,直到种群数满足200,此一代的选择、交叉、变异等遗传进化操作暂停
    if aa>Np
        F=F(1:Np,:);
    end
    f=F;   %将新种群200个个体赋给矩阵f,f是种群矩阵
    f(1,:)=R;    %之前的R是最优个体,这里把种群矩阵f中的第一个个体换成最优个体
    clear F;
    gen=gen+1;
    Rlength(gen)=lenmin;    %记录每代的最优个体,就是每一波200个路径规划方案的中的最优方案
end
figure     %%%%这里画出各城市坐标和路径规划线路图
for i=1:N-1
    
    plot([Coordinate(R(i),1),Coordinate(R(i+1),1)],[Coordinate(R(i),2),Coordinate(R(i+1),2)],'bo-');  %依次连接最优方案中的线路各点,用蓝色线连接
    
    hold on;   %hold-添加新绘图时保留当前绘图
end

plot([Coordinate(R(N),1),Coordinate(R(1),1)],[Coordinate(R(N),2),Coordinate(R(1),2)],'ro-');   %收尾点连接,用红色线

title(['优化最短距离:',num2str(lenmin)]);  %num2str将数字转换为字符数组,为了标题输出

figure    %%%%%这里画迭代次数,即进化过程图
plot(Rlength)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度函数进化曲线')


%%tips:这里bo-,ro-的-是连线功能

 

 

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
遗传算法 (Genetic Algorithm, GA) 是一种基于模拟自然界生物进化过程的优化算法。该算法通过模拟遗传、变异、选择和交叉等操作,从而搜索问题的最优解。GA_LQR程序是将遗传算法应用于线性二次调节器 (Linear Quadratic Regulator, LQR) 问题的程序。 LQR问题是控制理论中的一种经典问题,目标是设计一个最优的状态反馈控制器,使得系统的性能指标最小化。GA_LQR程序通过遗传算法的优化过程,寻找到最佳的控制器参数,以达到LQR问题的最优化。 该程序的实现大致包括以下步骤: 1. 初始化种群:将一定数量的个体(控制器参数)随机生成,构成初始种群。 2. 适应度评估:使用LQR问题的性能指标,计算每个个体的适应度值,即个体在问题中的优劣程度。 3. 选择:根据个体适应度值,采用选择操作,选择出一部分较优秀的个体作为父代。 4. 交叉:对父代个体进行交叉操作,生成新的后代个体。 5. 变异:对后代个体进行一定概率的变异操作,增加种群的多样性。 6. 重复2-5步骤,直到达到指定的停止条件(例如达到最大迭代次数)。 7. 输出结果:选择适应度最好的个体作为最优解,即最佳的控制器参数。 通过遗传算法的迭代优化过程,GA_LQR程序可以找到满足LQR问题最优化的控制器参数。它的优是可以在复杂的非线性问题中进行优化,并且具有并行处理能力和适应性等特。然而,由于遗传算法是一种启发式算法,没有保证找到全局最优解的能力,解的质量依赖于初始化种群和算法参数的设置。因此,在实际应用中需要综合考虑算法的收敛性和计算效率等方面的因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值