粒子群算法

           设计八:粒子群算法优化求解

旅行商(TSP)问题,是数学领域中著名问题之一,被证明具有NPC计算复杂性。该问题假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。从TSP问题测试数据集中选择一组测试数据,选择一种改进的粒子群算法,编写Python程序,求解最优路径问题。设计能够进行人机交互的可视化界面,使用图形方式表达求解过程,统计并分析实验数据,给出相应的数据表格和图形。学生也可以选择其他复杂问题进行求解。

1、算法参考学习

https://finthon.com/python-pso/
https://www.omegaxyz.com/2018/01/12/python_pso/
https://blog.csdn.net/wang454592297/article/details/80367158

2、算法生物学背景

  粒子群算法属于群智能算法的一种,使用过模拟鸟群捕食行为设计的。假设区域里只有一块食物,鸟群的任务是找到这块食物。鸟群在整个搜寻过程中,通过相互传递各自的信息,让其他的鸟知道自己的位置,通过这样的协作,来判断自己找到的是不是最优解,同时,也将最优解的信息传递给整个鸟群。

  最终,整个鸟群都能聚集在食物源周围,即找到了问题的最优解,即问题收敛。

3、PSO算法基本原理概述:
  从鸟群的视角:假设一个区域,所有的鸟都不知道食物的位置,但是它们知道当前位置离食物还有多远。

  从PSO算法的视角:每个解看作一只鸟,称为“粒子(particle)”,所有的粒子都有一个适应值,每个粒子都有一个速度决定它们的飞翔方向和距离,粒子们追随当前最优粒子在解空间中搜索。初始化一群随机粒子,通过迭代找到最优。每次迭代中,粒子通过跟踪“个体极值(pbest)”和“全局极值(gbest)”来更新自己的位置。

4、算法基本步骤:

1)初始化
	初始化粒子群(粒子群共有n个粒子):给每个粒子赋予随机的初始位置和速度。

2)计算适应值
	根据适应度函数,计算每个粒子的适应值。

3)求个体最佳适应值
	对每一个粒子,将其当前位置的适应值与其历史最佳位置(pbest)对应的适应值比较,
	如果当前位置的适应值更高,则用当前位置更新历史最佳位置。

4)求群体最佳适应值
	对每一个粒子,将其当前位置的适应值与其全局最佳位置(gbest)对应的适应值比较,
	如果当前位置的适应值更高,则用当前位置更新全局最佳位置。

5)更新粒子位置和速度
	根据公式更新每个粒子的速度与位置。

6)判断算法是否结束
	若未满足结束条件,则返回步骤2,若满足结束条件则算法结束,全局最佳位置(gbest)
	即全局最优解。

5、算法matlab代码

%TSPPSO.m
%% 1.清空环境变量
close all;
clear all;
clc;
tic;
%% 2.导入数据
% %%load citys_data.mat;          %数据集的变量名为citys
 citys=[1304 2312;3639 1315;4177 2244;3712 1399;3488 1535;3326 1556;...
     2328 1229;4196 1044;4312 790;4386 570;3007 1970;2562 1756;...
     2788 1491;2381 1676;1332 695;3715 1678;3918 2179;4061 2370;...
     3780 2212;3676 2578;4029 2838;4263 2931;3429 1908;3507 2376;...
     3394 2643;3439 3201;2935 3240;3140 3550;2545 2357;2778 2826;...
     2370 2975];

%citys=[1304 2312;3639 1315;4177 2244;3712 1399;3488 1535];
%% 3.计算城市间相互距离
n=size(citys,1);
D=zeros(n,n);

for i=1:n
    for j=i+1:n
        D(i,j)=sqrt(sum((citys(i,:)-citys(j,:)).^2));
        D(j,i)=D(i,j);
    end
end

%% 4.初始化参数
c1=0.1;                         %个体学习因子
c2=0.075;                       %社会学习因子
w=1;                            %惯性因子
m=500;                          %粒子数量
pop=zeros(m,n);                 %粒子位置
v=zeros(m,n);                   %粒子速度
gen=1;                          %迭代计数器
genmax=2000;                    %迭代次数
fitness=zeros(m,1);             %适应度函数值
Pbest=zeros(m,n);               %个体极值路径
Pbest_fitness=zeros(m,1);       %个体极值
Gbest=zeros(genmax,n);          %群体极值路径
Gbest_fitness=zeros(genmax,1);  %群体极值
Length_ave=zeros(genmax,1);     %各代路径的平均长度
ws=1;                           %惯性因子最大值
we=0.8;                         %惯性因子最小值
NC=1;
%% 5.产生初始粒子
% 5.1随机产生粒子初始位置和速度
for i=1:m
    pop(i,:)=randperm(n);
    v(i,:)=randperm(n);
end

% 5.2计算粒子适应度函数值
for i=1:m
    for j=1:n-1
        fitness(i)=fitness(i) + D(pop(i,j),pop(i,j+1));
    end
    fitness(i)=fitness(i) + D(pop(i,end),pop(i,1));
end

% 5.3计算个体极值和群体极值
Pbest_fitness=fitness;
Pbest=pop;
[Gbest_fitness(1),min_index]=min(fitness);
Gbest(1,:)=pop(min_index,:);
Length_ave(1)=mean(fitness);

%% 6.迭代寻优
% figure(1);
while gen<genmax
    % 6.1更新迭代次数与惯性因子
    gen=gen+1;
    w = ws - (ws-we)*(gen/genmax)^2;
    % 6.2更新速度
    %个体极值修正部分
    change1=position_minus_position(Pbest,pop);
    change1=constant_times_velocity(c1,change1);
    %群体极值修正部分
    change2=position_minus_position(repmat(Gbest(gen-1,:),m,1),pop);
    change2=constant_times_velocity(c2,change2);
    %原速度部分
    v=constant_times_velocity(w,v);
    %修正速度
    for i=1:m
        for j=1:n
            if change1(i,j)~=0
                v(i,j)=change1(i,j);
            end
            if change2(i,j)~=0
                v(i,j)=change2(i,j);
            end
        end
    end

    % 6.3更新位置
    pop=position_plus_velocity(pop,v);

    % 6.4适应度函数值更新
    fitness=zeros(m,1);
    for i=1:m
        for j=1:n-1
            fitness(i)=fitness(i) + D(pop(i,j),pop(i,j+1));
        end
        fitness(i)=fitness(i) + D(pop(i,end),pop(i,1));
    end

    % 6.5个体极值与群体极值更新
    for i=1:m
        if fitness(i)<Pbest_fitness(i)
            Pbest_fitness(i)=fitness(i);
            Pbest(i,:)=pop(i,:);
        end
    end

    [minvalue,min_index]=min(fitness);
    if minvalue<Gbest_fitness(gen-1)
        Gbest_fitness(gen)=minvalue;
        Gbest(gen,:)=pop(min_index,:);
    else
        Gbest_fitness(gen)=Gbest_fitness(gen-1);
        Gbest(gen,:)=Gbest(gen-1,:);
    end
    Length_ave(gen)=mean(fitness);
end

%% 7.结果显示
[Shortest_Length,index] = min(Gbest_fitness);
Shortest_Route = Gbest(index,:);
disp(['最短距离:' num2str(Shortest_Length)]);
disp(['最短路径:' num2str([Shortest_Route Shortest_Route(1)])]);
toc;
%% 8.绘制历史最优图
   for b=1:2000
     if   (b == 1   || b == 5 || b==20 || b == 100 || b == 500||b==2000) %改b的值保存图片就是对应的迭代次数结果
%      figure;
     a=Gbest(b,:);
     plot([citys(a,1);citys(a(1),1)],[citys(a,2);citys(a(1),2)],'o-');
     xlabel('城市位置横坐标x');
     ylabel('城市位置纵坐标y');
     title(['迭代次数:',num2str(b),' 优化最短距离:',num2str(Gbest_fitness(b))]);
        filename=num2str(b);
        fileformat='png';
        saveas(gcf,filename,fileformat);
     end
    end
    plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
     [citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
 title(['迭代次数:',int2str(gen),' 优化最短距离:',num2str(Shortest_Length)]);
%  title(['粒子群算法优化路径(最短距离:' num2str(Shortest_Length) ')'])
grid on
pause(0.005);

for i = 1:size(citys,1)
   text(citys(i,1),citys(i,2),['   ' num2str(i)]);
end
text(citys(Shortest_Route(1),1),citys(Shortest_Route(1),2),'       起点');
text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),'       终点');
xlabel('城市位置横坐标');
ylabel('城市位置纵坐标');


figure;
plot(1:genmax,Gbest_fitness,'b',1:genmax,Length_ave,'r:');
legend('最短距离','平均距离');
xlabel('迭代次数');
ylabel('距离');
title('各代最短距离与平均距离对比');
%position_minus_position.m
function change=position_minus_position(best,pop)
%记录将pop变成best的交换序列
for i=1:size(best,1)
    for j=1:size(best,2)
        change(i,j)=find(pop(i,:)==best(i,j));
        temp=pop(i,j);
        pop(i,j)=pop(i,change(i,j));
        pop(i,change(i,j))=temp;
    end
end
end
%position_plus_velocity.m
function pop = position_plus_velocity(pop,v)
%利用速度记录的交换序列进行位置修正
for i=1:size(pop,1)
    for j=1:size(pop,2)
        if v(i,j)~=0
            temp=pop(i,j);
            pop(i,j)=pop(i,v(i,j));
            pop(i,v(i,j))=temp;
        end
    end
end
end
%constant_times_velocity.m
function change = constant_times_velocity(constant,change)
% 以一定概率保留交换序列
for i=1:size(change,1)
    for j=1:size(change,2)
        if rand>constant
            change(i,j)=0;
        end
    end
end
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小嵌同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值