粒子群算法的matlab实现(含源码)

思想

对于个体的鸟儿来说,最快获取食物的第一选择通常是:看看其他的鸟在什么位置,它们相信聚集效应存在,会先去大部分鸟儿去的地方,如果没有,就去其他的地方去寻找

核心思想
利用群体中的个体对信息的共享从而使得整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得问题的最优解。

粒子群优化算法来源于对鸟类、鱼群的捕食行为,进而抽象成的一种算法,那么,我将介绍一个鸟类如何捕食的粒子来讲解粒子群优化算法。

举例
已知条件在一片区域中,有一群鸟,而且在这一片区域中的某处或者多处存在一些食物,鸟类就是鸟类,他们是不知道食物具体的位置,也不知道哪个位置食物最多,但是他们遇到食物的时候,是知道这是食物的-_-,而且能够区分食物量的多少。自然界中一切生物都是在不停的寻找食物,这也是能够得以生存的原因。

求解——找食物最多的地方

解:这一个流程:已知条件,求解。

那么,鸟群如何找到食物呢?如何找到这篇区域中食物最多的地方呢?

1、鸟群之间信息共享,朝着群体已知食物最多的地方飞行
2、根据自己的经验,朝着自己已知食物最多的地方飞行

通过这两种行为,鸟群之间相互分享信息,随着不断的寻找就能够找到食物最多的位置。

通过以上的分析,鸟类有两种行为:1、社会行为;2、个体行为;
社会行为:鸟会根据鸟群中最好的鸟学习,即朝着目前已知食物最多的地方移动。
个体行为:根据自己搜索的情况,向自己已知食物最多的地方移动。
然后,根据鸟群的这种寻找食物的方法进行抽象,每一个鸟抽象成一个粒子,每个粒子都有上述的两种行为,就产生了粒子群优化算法(particle swarm optimization,PSO)。

公式

求解下一次速度:
个体在所有的行进路径中——最优值与当前位置的差值(个体极值和当前位置的关系)
群体在所有的行进路径中——最优值与当前位置的差值(群体极值和当前位置的关系)

求解下一次位置:
相邻的两次间隔,默认时间是1,所以速度和位置可以直接相加
在这里插入图片描述

程序

fun.m

function y = fun(x)
% 函数用于计算粒子适应度值,也就是公式
%x           input           输入粒子 
%y           output          粒子适应度值 
y = sin(10 * pi * x) / x;

main.m

 %% I. 清空环境
clc
clear all

%% II. 绘制目标函数曲线图
x = 1:0.01:2;  %1-2 
y = sin(10*pi*x) ./ x;%实际要优化的函数  矩阵的对应相除——点除  sin(10*π*x)
figure%单独执行可以出现表格,和前几行一起执行也是表格,必须和第四行一起执行才可以出现表格
plot(x, y)
hold on%添加新绘图时,保存当前figure

%% III.初始化参数
c1 = 1.49445;
c2 = 1.49445;

maxgen = 50;   % 进化次数  
sizepop = 10;   %种群规模

Vmax = 0.5;
Vmin = -0.5;
popmax = 2; %个体变化范围,与pop范围对应相同
popmin = 1;

%加入权重(1)
ws = 0.9;%start
we = 0.4;%end

%% IV. 产生初始粒子(种群) 速度 适应度函数
for i = 1:sizepop%10
    % 随机产生一个种群population=10,同时定义pop()
    %pop(i,:)——10*1double,不是1*10
    %因为右侧没有i,只是左侧的pop(i,:)
    %初始种群 rands(1)函数是随机产生[-1,1],经过运算后,变化范围是{
    
    12},[1,2]中随机10%pop(i,:) = rand + 1;%pop(i,:) = rand(1) + 1;两者都可以
    pop(i,:) = (rands(1) + 1) / 2 + 1;   
    V(i,:) = 0.5 * rands(1);  %初始化速度,[-0.5,0.5]
    % 适应度 把初始化的,10*1的种群,代入到函数中,得到1*10的适应度函数
    %fitness函数只能显示1*n的数据,这是设置的
    fitness(i) = fun(pop(i,:));   %针对每一个个体去调用适应度函数
end
%% V. 个体极值和群体极值 个体最佳和群体最佳
%选择最大或者最小都可以,但是一定要统一,毕竟是随机
%[最大值 对应的位置]
[bestfitness bestindex] = max(fitness);%1-10中最大的适应度函数值就是,fitness不加括号
%g_best = max(pop);输出的群体最佳和群体极值是一样(结果虽然是一样的,是偶然,),    0.9528    1.0490

%这三个里面,只有,p_best与fitness函数无关
%位置——在群体中,适应度函数值最大的对应的位置
g_best = pop(bestindex,:);      %全局最佳,并不是十个数里面最大的gbest = max(pop);,而是群体极值中最大的,对应的位置
p_best = pop;                   %个体最佳,十个个体,此时没有进入循环,在循环中,个体最佳是所有循环中个体最佳的

%值
p_best_fitness = fitness;       %个体最佳适应度值——个体极值
g_best_fitness = bestfitness;   %全局最佳适应度值——群体极值

%% VI. 迭代寻优
for i = 1:maxgen%50
        %加入权重(2)
    w = ws - (ws - we)*(maxgen - i)/maxgen;
    for j = 1:sizepop%10
        % 速度更新           个体最佳*10 每一次都选取最佳               全局最佳(每次循环中的最佳)
        V(j,:) = w*V(j,:) + c1*rand*(p_best(j,:) - pop(j,:)) + c2*rand*(g_best - pop(j,:));
        
        V(j,find(V(j,:)>Vmax)) = Vmax;%边界约束
        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) > p_best_fitness(j)%当前的适应度函数值大于个体极值,就把当前个体,以及适应度函数值赋给best
            p_best(j,:) = pop(j,:);
            p_best_fitness(j) = fitness(j);
        end
        
        % 群体最优更新
        if fitness(j) > g_best_fitness%当前的适应度函数值大于群体极值,就把当前个体,以及适应度函数值赋给best
            g_best = pop(j,:);
            g_best_fitness = fitness(j);
        end
    end 
    yy(i) = g_best_fitness;          
end

%% VII. 输出结果并绘图
[g_best_fitness g_best]%寻找到的极值点——[值,位置]
plot(g_best, g_best_fitness,'r*')%极值点对应的变量

figure
plot(yy)
title('最优个体适应度','fontsize',12);
xlabel('进化代数','fontsize',12);ylabel('适应度','fontsize',12);


结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43641765/article/details/111414915