一、粒子群算法的概述

    粒子群算法(PSO)属于群智能算法的一种,是通过模拟鸟群捕食行为设计的。假设区域里就只有一块食物(即通常优化问题中所讲的最优解),鸟群的任务是找到这个食物源。鸟群在整个搜寻的过程中,通过相互传递各自的信息,让其他的鸟知道自己的位置,通过这样的协作,来判断自己找到的是不是最优解,同时也将最优解的信息传递给整个鸟群,最终,整个鸟群都能聚集在食物源周围,即我们所说的找到了最优解,即问题收敛。

二、粒子群算法的流程

    粒子群算法通过设计一种无质量的粒子来模拟鸟群中的鸟,粒子仅具有两个属性:速度【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab和位置【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_02,速度代表移动的快慢,位置代表移动的方向。每个粒子在搜索空间中单独的搜寻最优解,并将其记为当前个体极值【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_03,并将个体极值与整个粒子群里的其他粒子共享,找到最优的那个个体极值作为整个粒子群的当前全局最优解【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_04,粒子群中的所有粒子根据自己找到的当前个体极值【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_03和整个粒子群共享的当前全局最优解【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_04来调整自己的速度和位置。粒子群算法的思想相对比较简单,主要分为:1、初始化粒子群;2、评价粒子,即计算适应值;3、寻找个体极值【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_03;4、寻找全局最优解【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_04;5、修改粒子的速度和位置。下面是程序的流程图:

 

【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_09

(PSO流程)

 

下面我们具体解释下流程图里面的每一个步骤:

1、初始化

   首先,我们需要设置最大的速度区间,防止超出最大的区间。位置信息即为整个搜索空间,我们在速度区间和搜索空间上随机初始化速度和位置。设置群体规模【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_10

2、个体极值与全局最优解

   个体极值为每个粒子找到的历史上最优的位置信息,并从这些个体历史最优解中找到一个全局最优解,并与历史最优解比较,选出最佳的作为当前的历史最优解。

3、更新速度和位置的公式

   更新公式为:

【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_11

【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_12

其中,【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_13称为惯性因子,【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_14【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_15称为加速常数,一般取【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_16【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_17表示区间【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_18上的随机数。【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_19表示第【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_20个变量的个体极值的第【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_21维。【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_22表示全局最优解的第【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_21维。

4、终止条件

有两种终止条件可以选择,一是最大代数:【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_24;二是相邻两代之间的偏差在一个指定的范围内即停止。我们在实验中选择第一种。


clc;clear;close all;
Vmax = 1;%速度限制
Vmin = -1;
nodes=50;%节点数目
links=150;%边数目
dims=nodes*(nodes-1)/2;%种群维数
c1 = 1.49445;
c2 = 1.49445;
maxgen = 300;    %进化次数
sizepop = 100;   %种群规模
% 惯性权重
w=1;
% 线性递减惯性权重
w_max=0.9;
w_min=0.4;
pop=zeros(sizepop,dims);%初始化种群
trans_index=zeros(1,dims);%初始化转换索引
%% 产生初始粒子和速度
for iter = 1:sizepop
    %初始化种群
    xx=randperm(nodes);
    yy=randperm(nodes);
    A=zeros(nodes,nodes);%连通阵,AA的迹为0
    linkscount=1;
    while linkscount<links+1
        edge_a=randi([1,nodes],1,1);%随机产生两个数,表示两个点的序号
        edge_b=randi([1,nodes],1,1);
        if edge_a~=edge_b
             if A(edge_a,edge_b)==0   %保证随机生成的边不重复
                 A(edge_a,edge_b)=1;
                 A(edge_b,edge_a)=1;
                 linkscount=linkscount+1;%表示成功的生成一个link
             end
        else
            A(edge_a,edge_b)=0;
%             linkscount=linkscount+1;%表示成功的生成一个link
        end
    end
    %将邻接矩阵转换为粒子向量
    k=1;
    for i=1:nodes
        for j=1:nodes
            if(i>j)
                index=sub2ind(size(A),i,j); %取出对角线以上索引
                pop(iter,k)=A(index);%按照索引展开为向量
                trans_index(1,k)=index;%保存索引在向量转为邻接矩阵时使用
                k=k+1;
            end
        end
    end
    disp(A);
%     % 将粒子向量转换为邻接矩阵,经验证可以正常恢复
%     G=zeros(nodes,nodes);
%     [row col]=ind2sub(size(A),trans_index);
%     for s=1:length(trans_index)
%         G(row(s),col(s))=pop(iter,s);     
%     end
%     G=G+G';
%     sum(A(:))
    V(iter,:) = (Vmax-Vmin)*rand(1,dims)+Vmin;       %初始化速度
    %计算适应度
    fitness(iter) = fitness_fun(A);   %计算适应度
    
end
%% 个体极值和群体极值
[bestfitness bestindex] = max(fitness); %bestindex:全局最优粒子索引
gbest = pop(bestindex,:);   %全局最佳位置
pbest = pop;    %个体最佳
fitnesspbest = fitness;   %个体最佳适应度值
fitnessgbest = bestfitness;   %全局最佳适应度值

%% 迭代寻优
for i = 1:maxgen       %代数更迭
 %    w=-(4/300^2)*i^2+4/300*i+0.4;
    for j = 1:sizepop  %遍历个体
        % 速度更新
        V(j,:) = w*V(j,:) + c1*rand*(pbest(j,:) - pop(j,:)) + c2*rand*(gbest - pop(j,:));
        %速度边界处理
        V(j,find(V(j,:)>Vmax)) = Vmax;
        V(j,find(V(j,:)<Vmin)) = Vmin;
        %统计种群中1的个数
        W=sum(pop(j,:));
        % 种群更新
        pop(j,:) = pop(j,:) + V(j,:);
        %位置边界处理
        pop(j,find(pop(j,:)>=0.5)) = 1;
        pop(j,find(pop(j,:)<0.5)) = 0;
        %比较更新种群与原种群1的个数
        M=sum(pop(j,:));
        if M<W %随机挑选W-M个0变为1
            index0=find(pop(j,:)==0);
            c=1;
            while c<=W-M
                mid=unidrnd(length(index0));
                if pop(j,index0(mid))==0
                    pop(j,index0(mid))=1;
                    c=c+1;
                end
            end
        end
        if M>W %随机挑选M-W个1变为0
            index1=find(pop(j,:)==1);
            k=1;
            while k<=M-W
                mid1=unidrnd(length(index1));
                if pop(j,index1(mid1))==1
                    pop(j,index1(mid1))=0;
                    k=k+1;
                end
            end
        end
        % 将粒子向量转换为邻接矩阵
        G=zeros(nodes,nodes);
        [row col]=ind2sub(size(A),trans_index);
        for s=1:length(trans_index)
            G(row(s),col(s))=pop(j,s);     
        end
        G=G+G';
        % 适应度值更新
        fitness(j) = fitness_fun(G);
    end
    for j = 1:sizepop
        % 个体最优更新
        if fitness(j) > fitnesspbest(j)
            pbest(j,:) = pop(j,:);
            fitnesspbest(j) = fitness(j);
        end
        % 群体最优更新
        if fitness(j) > fitnessgbest
            gbest = pop(j,:);
            fitnessgbest = fitness(j);
        end
    end
    record(1,i)=fitnessgbest;
    fprintf('%d      %f\n',i,fitnessgbest);  %输出结果
%% 适应度值变化绘图
plot(record);
xlabel('gen');
ylabel('fitness');
end

【三维装箱】基于粒子群算法求解三维装箱问题matlab源码_matlab_25