【路径规划】基于粒子群栅格地图求解最短路径【Matlab 588期】

一、简介

1 粒子群算法的概念
粒子群优化算法(PSO:Particle swarm optimization) 是一种进化计算技术(evolutionary computation)。源于对鸟群捕食的行为研究。粒子群优化算法的基本思想:是通过群体中个体之间的协作和信息共享来寻找最优解.
PSO的优势:在于简单容易实现并且没有许多参数的调节。目前已被广泛应用于函数优化、神经网络训练、模糊系统控制以及其他遗传算法的应用领域。

2 粒子群算法分析
2.1基本思想
粒子群算法通过设计一种无质量的粒子来模拟鸟群中的鸟,粒子仅具有两个属性:速度和位置,速度代表移动的快慢,位置代表移动的方向。每个粒子在搜索空间中单独的搜寻最优解,并将其记为当前个体极值,并将个体极值与整个粒子群里的其他粒子共享,找到最优的那个个体极值作为整个粒子群的当前全局最优解,粒子群中的所有粒子根据自己找到的当前个体极值和整个粒子群共享的当前全局最优解来调整自己的速度和位置。下面的动图很形象地展示了PSO算法的过程:
在这里插入图片描述
2 更新规则
PSO初始化为一群随机粒子(随机解)。然后通过迭代找到最优解。在每一次的迭代中,粒子通过跟踪两个“极值”(pbest,gbest)来更新自己。在找到这两个最优值后,粒子通过下面的公式来更新自己的速度和位置。
在这里插入图片描述
公式(1)的第一部分称为【记忆项】,表示上次速度大小和方向的影响;公式(1)的第二部分称为【自身认知项】,是从当前点指向粒子自身最好点的一个矢量,表示粒子的动作来源于自己经验的部分;公式(1)的第三部分称为【群体认知项】,是一个从当前点指向种群最好点的矢量,反映了粒子间的协同合作和知识共享。粒子就是通过自己的经验和同伴中最好的经验来决定下一步的运动。以上面两个公式为基础,形成了PSO的标准形式。
在这里插入图片描述
公式(2)和 公式(3)被视为标准PSO算法。
3 PSO算法的流程和伪代码
在这里插入图片描述

二、源代码

clc;
close all
clear
load('data4.mat')
figure(1)%画障碍图
hold on
S=(S_coo(2)-0.5)*num_shange+(S_coo(1)+0.5);%起点对应的编号
E=(E_coo(2)-0.5)*num_shange+(E_coo(1)+0.5);%终点对应的编号
for i=1:num_shange
    for j=1:num_shange
        if sign(i,j)==1
            y=[i-1,i-1,i,i];
            x=[j-1,j,j,j-1];
            h=fill(x,y,'k');
            set(h,'facealpha',0.5)
        end
        s=(num2str((i-1)*num_shange+j));
        %text(j-0.95,i-0.5,s,'fontsize',6) 
    end
end
axis([0 num_shange 0 num_shange])%限制图的边界
plot(S_coo(2),S_coo(1), 'p','markersize', 10,'markerfacecolor','b','MarkerEdgeColor', 'm')%画起点
plot(E_coo(2),E_coo(1),'o','markersize', 10,'markerfacecolor','g','MarkerEdgeColor', 'c')%画终点
set(gca,'YDir','reverse');%图像翻转
for i=1:num_shange
    plot([0 num_shange],[i-1 i-1],'k-');
    plot([i i],[0 num_shange],'k-');%画网格线
end
PopSize=20;%种群大小
OldBestFitness=0;%旧的最优适应度值
gen=0;%迭代次数
maxgen =20;%最大迭代次数

c1=0.5;%认知系数
c2=0.7;%社会学习系数
w=0.96;%惯性系数
%%
%初始化路径
w_min=0.5;
w_max=1;
Group=ones(num_point,PopSize);  %种群初始化
for i=1:PopSize
    p_lin=randperm(num_point)';%随机生成1*400不重复的行向量
    %% 将起点编号放在首位
    index=find(p_lin==S);
    lin=p_lin(1);
    p_lin(1)=p_lin(index);
    p_lin(index)=lin;
    Group(:,i)=p_lin;
    %%将每个个体进行合理化处理
    [Group(:,i),flag]=deal_fun(Group(:,i),num_point,liantong_point,E,num_shange);
    while flag==1%如处理不成功,则初始化个体,重新处理
        p_lin=randperm(num_point)';
        index=find(p_lin==S);
        lin=p_lin(1);
        p_lin(1)=p_lin(index);
        p_lin(index)=lin;
        Group(:,i)=p_lin;
        [Group(:,i),flag]=deal_fun(Group(:,i),num_point,liantong_point,E,num_shange);       
    end
end

%最优解
route=Group(:,end)';
index1=find(route==E);
route_lin=route(1:index1);
for i=2:index1
    Q1=[mod(route_lin(i-1)-1,num_shange)+1-0.5,ceil(route_lin(i-1)/num_shange)-0.5];
    Q2=[mod(route_lin(i)-1,num_shange)+1-0.5,ceil(route_lin(i)/num_shange)-0.5];
    plot([Q1(1),Q2(1)],[Q1(2),Q2(2)],'b-.','LineWidth',3);hold on
    
end
title('粒子群算法-随机路线');

title('粒子群算法-随机路线');
figure(2)
hold on
for i=1:num_shange
    for j=1:num_shange
        if sign(i,j)==1
            y=[i-1,i-1,i,i];
            x=[j-1,j,j,j-1];
            h=fill(x,y,'k');
            set(h,'facealpha',0.5)
        end
        s=(num2str((i-1)*num_shange+j));
        text(j-0.95,i-0.5,s,'fontsize',6) 
    end
end
axis([0 num_shange 0 num_shange])%限制图的边界
plot(S_coo(2),S_coo(1), 'p','markersize', 10,'markerfacecolor','b','MarkerEdgeColor', 'm')%画起点
plot(E_coo(2),E_coo(1),'o','markersize', 10,'markerfacecolor','g','MarkerEdgeColor', 'c')%画终点
set(gca,'YDir','reverse');%图像翻转
for i=1:num_shange
    plot([0 num_shange],[i-1 i-1],'k-');
    plot([i i],[0 num_shange],'k-');%画网格线
end
for i=2:index1
    Q1=[mod(route_lin(i-1)-1,num_shange)+1-0.5,ceil(route_lin(i-1)/num_shange)-0.5];
    Q2=[mod(route_lin(i)-1,num_shange)+1-0.5,ceil(route_lin(i)/num_shange)-0.5];
    plot([Q1(1),Q2(1)],[Q1(2),Q2(2)],'b-.','LineWidth',3)
end
%初始化粒子速度(即交换序)
Velocity =zeros(num_point,PopSize);   
for i=1:PopSize
    Velocity(:,i)=round(rand(1,num_point)'*num_point/10); %round取整
end

%计算每个个体对应路径的距离
for i=1:PopSize   
	EachPathDis(i) = PathDistance(Group(:,i)',E,num_shange);
end

IndivdualBest=Group;%记录各粒子的个体极值点位置,即个体找到的最短路径
IndivdualBestFitness=EachPathDis;%记录最佳适应度值,即个体找到的最短路径的长度
[GlobalBestFitness,index]=min(EachPathDis);%找出全局最优值和相应序号
%寻优
while gen < maxgen
    w=w_max-(w_max-w_min)*gen/maxgen;
    %迭代次数递增
    gen = gen +1
    %更新全局极值点位置,这里指路径
    for i=1:PopSize   
        GlobalBest(:,i) = Group(:,index);
    end
   
    %求pij-xij ,pgj-xij交换序,并以概率c1,c2的保留交换序
    pij_xij=GenerateChangeNums(Group,IndivdualBest);  %根据个体最优解求交换序
    pij_xij=HoldByOdds(pij_xij,c1);%以概率c1保留交换序
    pgj_xij=GenerateChangeNums(Group,GlobalBest);%根据全局最优解求交换序
    pgj_xij=HoldByOdds(pgj_xij,c2);%以概率c2保留交换序
   
    %以概率w保留上一代交换序
    Velocity=HoldByOdds(Velocity,w);
    Group = PathExchange(Group,Velocity); %根据交换序进行路径交换
    Group = PathExchange(Group,pij_xij);
    Group = PathExchange(Group,pgj_xij);
    for i = 1:PopSize    
        [Group(:,i),flag]=deal_fun(Group(:,i),num_point,liantong_point,E,num_shange);
        while flag==1
            p_lin=randperm(num_point)';
            index=find(p_lin==S);
            lin=p_lin(1);
            p_lin(1)=p_lin(index);
            p_lin(index)=lin;
            Group(:,i)=p_lin;
            [Group(:,i),flag]=deal_fun(Group(:,i),num_point,liantong_point,E,num_shange);
        end    
    end 
    for i = 1:PopSize    % 更新各路径总距离
        EachPathDis(i) = PathDistance(Group(:,i)',E,num_shange);
    end
    IsChange = EachPathDis<IndivdualBestFitness;%更新后的距离优于更新前的,记录序号
    IndivdualBest(:, find(IsChange)) = Group(:, find(IsChange));%更新个体最佳路径
    IndivdualBestFitness = IndivdualBestFitness.*( ~IsChange) + EachPathDis.*IsChange;%更新个体最佳路径距离
    [GlobalBestFitness, index] = min(IndivdualBestFitness);%更新全局最佳路径,记录相应的序号

    if GlobalBestFitness~=OldBestFitness %比较更新前和更新后的适应度值;
        OldBestFitness=GlobalBestFitness;%不相等时更新适应度值
        best_route=IndivdualBest(:,index)';
    end   
     BestFitness(gen) =GlobalBestFitness;%每一代的最优适应度
end
%最优解
index1=find(best_route==E);
route_lin=best_route(1:index1);
for i=2:index1
    Q1=[mod(route_lin(i-1)-1,num_shange)+1-0.5,ceil(route_lin(i-1)/num_shange)-0.5];
    Q2=[mod(route_lin(i)-1,num_shange)+1-0.5,ceil(route_lin(i)/num_shange)-0.5];
    plot([Q1(1),Q2(1)],[Q1(2),Q2(2)],'r','LineWidth',3)
end

三、运行结果

在这里插入图片描述

四、备注

完整代码或者代写添加QQ 912100926

猜你喜欢

转载自blog.csdn.net/m0_54742769/article/details/115318235