粒子群算法介绍03:附Matlab、python代码(PSO)

八:

惯性权重w体现的是粒子继承先前速度的能力,Shi Y最先将惯性权重w引入PSO算法中,并分析指出一个较大的惯性权重值有利于全局搜索,而一个较小的惯性权重值则更有利于局部搜索。为了平衡两者,后又提出了线性递减惯性权重(LDIW)。

式(13-4)错误,分母只是k,去掉Tmax-

粒子群算法解决vrptw问题python 粒子群算法pid_粒子群算法

粒子群算法解决vrptw问题python 粒子群算法pid_pso_02


无惯性权重的情况下,让程序运行100次平均值作为最优结果。在前面代码的基础上改进:函数代码与上一节相同。

%% 双清空+关闭图形
clc,clear,close all;

%% 对程序执行100次运算
for k = 1:100   
    %% PSO参数标定。 ***注意:这里少了惯性权重w和维度D***
    c1 = 1.49445;     %个体学习因子
    c2 = 1.49445;     %社会学习因子
    maxgen = 300;     %迭代次数
    sizepop = 20;     %种群大小
    Vmax = 0.5;       %速度上下限
    Vmin = -0.5;
    popmax = 2;       %位置上下限
    popmin = -2;

    %% 初始化粒子群中每个粒子的位置和速度,并计算适应度值
    for j = 1:sizepop               %自行参考for循环
        pop(j,:) = 2*rands(1,2);    %自行参考rands
        V(j,:) = 0.5*rands(1,2);
    
        fitness(j) = fun(pop(j,:)); %自行参考函数   
    end

    %% 寻找初始个体极值和群体极值  
    %{
    ***注意:pop是一个20行2列矩阵其中第一列为X1,第二列为X2;V也是
    fitness有看懂的大神请评论区解释一下,我理解的是一个20行1列的矩阵这样才能找到群体极值的位置,
    但是程序给出的确是1行20列矩阵***
    --------------------------------------------------------------------------------------------
    这里需要注意许多matlab中的max参考博客没讲这一点
    通过实验发现当矩阵A是一个行向量时,[maxnumber maxindex] = max(A)中maxindex返回的是最大值所在列
    这样就解释了刚才的疑问!
    A=[1,2,3,4,8,6,75,9,243,25]
    A =
         1     2     3     4     8     6    75     9   243    25
    [maxnumber maxindex] = max(A)
    maxnumber =
         243
    maxindex =
         9
    --------------------------------------------------------------------------------------------
    %}
    [bestfitness bestindex] = max(fitness);  %自行参考max函数用法
    zbest = pop(bestindex,:);                %群体极值位置       
    gbest = pop;                             %个体极值位置  因为初始化所以每个粒子个体极值位置就是它本身随机的位置
    fitnessgbest = fitness;                  %个体极值适应度值
    fitnesszbest = bestfitness;              %群体极值适应度值



    %% 寻优迭代
    for i = 1:maxgen
        %速度更新
        for j = 1:sizepop
            V(j,:)=V(j,:)+c1*rand*(gbest(j,:)-pop(j,:))+c2*rand*(zbest-pop(j,:)); %没有添加惯性权重
            V(j,find(V(j,:)>Vmax)) = Vmax; %find函数这里返回的是索引可以是三种情况1;2;1 2;
            V(j,find(V(j,:)<Vmin)) = Vmin;
         %位置更新   
            pop(j,:)=pop(j,:)+V(j,:);
            pop(j,find(pop(j,:)>popmax)) = popmax;
            pop(j,find(pop(j,:)<popmin)) = popmin;
          %更新适应度值  
            fitness(j)=fun(pop(j,:));
        end
          %个体极值更新
        for j = 1:sizepop
            if fitness(j)>fitnessgbest(j)
                gbest(j,:)=pop(j,:);
                fitnessgbest(j)=fitness(j);
            end
          %群体极值更新 
            if fitness(j)>fitnesszbest
                zbest=pop(j,:);
                fitnesszbest=fitness(j);
            end
        end
        %每代最优极值记录到result中
        result(i)=fitnesszbest;
    end
    G(k) = max(result);
end

GB = max(G);   %一百次运行后所有最优解中最大的最优解
Average = sum(G)/100; %所有最优解平均值
Fnumber =length(find(G>1.0054-0.01&G<1.0054+0.01));%在误差范围内最优解的个数
FSnumber =length(find(G>1.0054+0.01|G<1.0054-0.01));%在误差范围外最优解的个数
precision = Fnumber/100  %求解精度

可以发现对最优解的求值很不稳定:

粒子群算法解决vrptw问题python 粒子群算法pid_粒子群算法_03

只有79次找到最优解剩下21次都没有。由此可见惯性权重十分重要。这里直接放结论:

粒子群算法解决vrptw问题python 粒子群算法pid_算法_04


可以看见第二种惯性权重效果最佳,即式(13-5),这里我后期试验了一下发现不管那种惯性权重都得不出上述结论。

参考文献:matlab智能算法30个案例分析(第二版)


本人实验结论如下:

粒子群算法解决vrptw问题python 粒子群算法pid_算法_05


粒子群算法解决vrptw问题python 粒子群算法pid_算法_06


总体来看采用4式最好,但是多次实验你会发现每个w其精确度(出现最优解的实验次数/实验次数)变化范围很大,

因此这里惯性权重并没有最好的选择,针对具体问题,对于具体实验可以增加代码运行次数,最后取运行最好的值。

代码分为两部分,一部分参考文献的原始代码,其惯性权重那里有错误,缺少w

另一部分为本人修改代码