Matlab新手快速上手2(粒子群算法)

        本文根据一个较为简单的粒子群算法框架详细分析粒子群算法的实现过程,对matlab新手友好,源码在文末给出。

粒子群算法简介

        粒子群算法(Particle Swarm Optimization,PSO)是一种群体智能优化算法,灵感来源于鸟群或鱼群等生物群体的行为。在PSO中,每个潜在解被表示为粒子,这些粒子在解空间中移动,并且其位置和速度根据个体经验和群体经验进行更新。

        PSO 算法的核心思想是通过模拟群体行为来搜索解空间中的最优解。每个粒子代表了解空间中的一个潜在解,并且根据其当前位置和速度来调整其移动方向。粒子的速度和位置的更新依赖于两个重要的信息:个体最优(局部最优)和全局最优。

PSO 算法的基本步骤如下:

  1. 初始化粒子群:随机生成一组粒子,并随机初始化它们的位置和速度。

  2. 评估适应度:对每个粒子根据其当前位置计算适应度值。

  3. 更新个体最优位置:对于每个粒子,根据其当前位置和个体历史最优位置,更新其个体最优位置。

  4. 更新全局最优位置:根据整个粒子群的个体最优位置,更新全局最优位置。

  5. 更新粒子速度和位置:根据个体历史最优位置和全局历史最优位置,以及一些随机因素,更新每个粒子的速度和位置。

  6. 重复迭代:重复步骤 3~5 直到达到停止条件(例如达到最大迭代次数或找到满意的解)。

        PSO 算法的优点包括简单易实现、不需要太多的参数调整、能够处理高维问题以及对于非线性、非凸优化问题有较好的收敛性。然而,它也有一些缺点,例如对于高度多模态函数可能会陷入局部最优、收敛速度慢等。

参数与子函数定义:

function PSO
%---------------------------------- 共性参数 -------------------------------
NP=20;D=2;                    % 种群规模,变量个数
selfw=2.0;globalw=2.0;        % 自身因子,全局因子
w=0.5;maxgen=1000;       % 惯性因子,限定步数
%---------------------------------- 个性参数 -------------------------------
MinX=-65.536;MaxX=65.536; %变量范围
%------------------------------- 粒子位置初始化 ----------------------------
X=MinX+(MaxX-MinX)*rand(NP,D);
F=fun(X);
selfX=X;selfF=F;dX=zeros(NP,D);
%--------------------------------- 适应度统计 ------------------------------
[Bestf,Indexf]=sort(F); globalfi=Bestf(NP);
globalBestX=X(Indexf(NP),:);
function F=fun(X)
a=[-32 -16 0 16 32 -32 -16 0 16 32 -32 -16 0 16 32 -32 -16 0 16 32 -32 -16 0 16 32;...
   -32 -32 -32 -32 -32 -16 -16 -16 -16 -16 0 0 0 0 0 16 16 16 16 16 32 32 32 32 32];
F=0.002*ones(size(X,1),1);
for j=1:1:25
    F=F+1./(j+(X(:,1)-a(1,j)).^6+(X(:,2)-a(2,j)).^6);%计算适应度
end

如代码中,省略号的意思是将代码延续到下一行,使代码更易读。无实际意义

参数定义

X矩阵表示NP行2列,元素为0-1的随机值的矩阵,每一行表示一个粒子,两个参数分别为粒子的x坐标和y坐标。

 F矩阵与计算适应度

 ones函数在上一个遗传算法的文章中已经介绍,F=0.002*ones(size(X,1),1);这个代码生成了一个列数为1,与X矩阵行数相等的矩阵,矩阵元素全为0.002。

        下面的for循环就是计算适应度的过程,如代码所示,这个函数根据距离权重也就是j的值(1-25)计算了每个粒子到25个参考点之间的距离之和,得出与最优距离的适应度(0-1)越接近1表示适应度越好,最终目的也就是使用算法找到最结果最趋近1的解,也就是第一个点(-32,-32)的解,为什么是第一个点,带入点的坐标计算就得知,若距离每个点都不相近,那么结果就是一个很大的值除1,就是趋近于0的值,当粒子趋近于第一个点时,结果就趋近1/1也就是1。 

zeros函数

  • 作用:创建一个全为0的矩阵。
  • 用法:Z = zeros(m,n);表示创建了一个mxn的元素全为0的矩阵。
  • 举例:Z = zreos(3,4);这样就创建了一个3行4列的元素全为0的矩阵

sort函数:

[Bestf,Indexf]=sort(F);这个sort函数是给Bestf排序的,其中排序后的结果存储在 Bestf中,排序后元素在原向量中的索引存储在 Indexf中。例如:

  • 假设有以下向量 F= [10, 30, 20, 50, 40]运行[Bestf,Indexf] = sort(F)
  • Bestf 存储了排序后的结果:Bestf = [10, 20, 30, 40, 50]。
  • Indexf 存储了排序后元素在原向量中的索引:Indexf = [1, 3, 2, 5, 4]。

变量定义:

globalfi =Bestf(NP);表示记录粒子与所有目标点的最佳的权重距离之和,最佳值记录在globalfi 中。

globalBestX=X(Indexf(NP),:);表示索引这个最佳粒子并记录在globalBestX中。

a矩阵

a矩阵存储了15个的参考点坐标,第i个参考点的坐标就是(x_{i},y_{i}) = (a(1,i),a(2,i)),例如第一个参考点坐标就是(32,32)

size函数

  • 作用:函数用于获取数组的尺寸。
  • 一个参数:例如:A = [1, 2, 3; 4, 5, 6]; s = size(A);这时输出[2,3]表示这是2行3列的矩阵
  • 两个参数:s = size(A, 1);这样会返回A的行数2,s = size(A, 2);这样会返回A的列数3

算法开始

for gen=1:1:maxgen
    time(gen)=gen;
    %---------------------------- 粒子位置移动 -----------------------------
    for i=1:1:NP
        for j=1:1:D
            dX(i,j)=w*dX(i,j)+selfw*rand*(selfX(i,j)-X(i,j))+...
                globalw*rand*(globalBestX(1,j)-X(i,j));
            X(i,j)=X(i,j)+dX(i,j);    %移动后的位置
            if X(i,j)>MaxX X(i,j)=MaxX;end
            if X(i,j)<MinX X(i,j)=MinX;end
        end
    end
    F=fun(X);
    %----------------------------- 适应度统计 ------------------------------
    [Bestf,Indexf]=sort(F); Bestfi=Bestf(NP);
    BestX=X(Indexf(NP),:);
    %---------------------------- 更新自身最优 -----------------------------
    for i=1:1:NP
        if F(i)>=selfF(i)
            selfF(i)=F(i);selfX(i,:)=X(i,:);
        end
    end
    %---------------------------- 更新全局最优 -----------------------------
    if Bestfi>=globalfi
        globalfi=Bestfi;globalBestX=BestX;
    end
    %----------------------------- 记录结果 --------------------------------
    BestJ(gen)=globalfi;
    if mod(gen,10)==0
        disp(sprintf('当前代数:%d;当前结果:%f',gen,globalfi));
    end
    plot(time,BestJ,'r');axis([1,maxgen,0,1.1]);
    xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
    if globalfi>1.0 break;end
end
disp(sprintf('迭代步数:%d;优化结果:%f',gen,globalfi));
%---------------------------- 子函数1:目标函数 ----------------------------
disp(F);
disp(BestX);

        首先for循环规定迭代次数为1000次,也就是粒子最多行进1000次,time存储for循环的的第几次迭代。

粒子移动:

        接下来是粒子移动,这是整个代码的核心部分,首先两个for循环更新所有粒子的x和y坐标,dX用于存储每个粒子的坐标变化包括x和y两个值也就是两个变化方向,可以理解为粒子的变化向量,也就是粒子的行进方向和速度。

惯性因子:

        w表示粒子的惯性因子,w*dX(i,j)表示粒子沿上一次的速度与方向行进,w的值为0.5表示速度减慢为一半,后面的算式表示根据自身最优与全局最优改变方向并增加速度,详细实现在下面给出:。

自身最优:

    for i=1:1:NP
        if F(i)>=selfF(i)
            selfF(i)=F(i);selfX(i,:)=X(i,:);
        end
    end

这个表示更新自身最优的过程,selfF表示粒子每次的与最优解的适应度(0-1),越接近1表示越接近最优解,selfX表示记录所有粒子的自身最优解的位置,因此selfw*rand*(selfX(i,j)-X(i,j))就是得出当前粒子坐标与最优坐标的差,并乘上自身因子与随机值selfw*rand,表示速度。

全局最优:

    if Bestfi>=globalfi
        globalfi=Bestfi;globalBestX=BestX;
    end

与上面自身最优同理,根据最好粒子的适应度,更新全局最优解的坐标,其实也就是适应度最好的粒子,同理globalw*rand*(globalBestX(1,j)-X(i,j))也就是向全局最优解方向移动一定的值。

总结:根据惯性因子、自身最优、全局最优实现粒子的更新,惯性因子让粒子保持上一次的移动方向,自身最优与全局最优都是让粒子改变方向,根据权重向着这两个方向偏移一定的角度和速度,最终实现粒子的寻优过程。

源代码:

%---------------------------------- 程序说明 -------------------------------

%                           该程序实现了普通粒子群算法

%---------------------------------- 程序正文 -------------------------------
function PSO
%---------------------------------- 共性参数 -------------------------------
NP=20;D=2;                    % 种群规模,变量个数
selfw=2.0;globalw=2.0;        % 自身因子,全局因子
w=0.5;maxgen=1000;       % 惯性因子,限定步数
%---------------------------------- 个性参数 -------------------------------
MinX=-65.536;MaxX=65.536; %变量范围
%------------------------------- 粒子位置初始化 ----------------------------
X=MinX+(MaxX-MinX)*rand(NP,D);
F=fun(X);
selfX=X;selfF=F;dX=zeros(NP,D);
%--------------------------------- 适应度统计 ------------------------------
[Bestf,Indexf]=sort(F); globalfi=Bestf(NP);
globalBestX=X(Indexf(NP),:);
%------------------------------- 程序主循环开始 ----------------------------
for gen=1:1:maxgen
    time(gen)=gen;
    %---------------------------- 粒子位置移动 -----------------------------
    for i=1:1:NP
        for j=1:1:D
            dX(i,j)=w*dX(i,j)+selfw*rand*(selfX(i,j)-X(i,j))+...
                globalw*rand*(globalBestX(1,j)-X(i,j));
            X(i,j)=X(i,j)+dX(i,j);    %移动后的位置
            if X(i,j)>MaxX X(i,j)=MaxX;end
            if X(i,j)<MinX X(i,j)=MinX;end
        end
    end
    F=fun(X);
    %----------------------------- 适应度统计 ------------------------------
    [Bestf,Indexf]=sort(F); Bestfi=Bestf(NP);
    BestX=X(Indexf(NP),:);
    %---------------------------- 更新自身最优 -----------------------------
    for i=1:1:NP
        if F(i)>=selfF(i)
            selfF(i)=F(i);selfX(i,:)=X(i,:);
        end
    end
    %---------------------------- 更新全局最优 -----------------------------
    if Bestfi>=globalfi
        globalfi=Bestfi;globalBestX=BestX;
    end
    %----------------------------- 记录结果 --------------------------------
    BestJ(gen)=globalfi;
    if mod(gen,10)==0
        disp(sprintf('当前代数:%d;当前结果:%f',gen,globalfi));
    end
    plot(time,BestJ,'r');axis([1,maxgen,0,1.1]);
    xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
    if globalfi>1.0 break;end
end
disp(sprintf('迭代步数:%d;优化结果:%f',gen,globalfi));
%---------------------------- 子函数1:目标函数 ----------------------------
disp(F);
disp(BestX);
function F=fun(X)
a=[-32 -16 0 16 32 -32 -16 0 16 32 -32 -16 0 16 32 -32 -16 0 16 32 -32 -16 0 16 32;...
   -32 -32 -32 -32 -32 -16 -16 -16 -16 -16 0 0 0 0 0 16 16 16 16 16 32 32 32 32 32];
F=0.002*ones(size(X,1),1);
for j=1:1:25
    F=F+1./(j+(X(:,1)-a(1,j)).^6+(X(:,2)-a(2,j)).^6);%计算适应度
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/562545.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Oracle正則匹配練習一

1.使用分割符號 select regexp_substr(A_B_C, [^_], 1, 2) FROM DUAL

Android 获取手机整体流量使用情况以及某个应用的流量的统计

源代码下载地址&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/b6ab9000c0bd

CSS基础:position定位的5个类型详解!

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端工具”&#xff0c;可获取 Web 开发工具合…

鸿蒙OpenHarmony【轻量系统编写“Hello World”程序】 (基于Hi3861开发板)

编写“Hello World”程序 下方将通过修改源码的方式展示如何编写简单程序&#xff0c;输出“Hello world”。请在下载的源码目录中进行下述操作。 前提条件 已参考鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到…

QT中的OpenGL学习-----3D图形

一、3D坐标系 记住V_clip M_projection * M_view * M_model * V_local就行&#xff0c;可以在顶点着色器里面添加位置信息&#xff1a; #version 330 core layout (location 2) in vec3 aPos;//location属性位置有16个 layout (location 3) in vec3 aColor; layout (locati…

基础算法前缀和与差分

前言 本次博客会介绍一维和二维的前缀和&#xff0c;以及一维二维差分的基本使用&#xff0c;尽量画图&#xff0c;多使用配合文字 使大家理解&#xff0c;希望有所帮助吧 一维前缀和 问题描述 这里有一个长度为n的数组&#xff0c;我们要算出【2,5】区间的元素和 暴力思…

linux定时备份数据库sql文件(表格、视图、存储过程,已保存的查询语句不会被备份)

创建一个脚本文件xxx.sh 为其设置全部权限chmod 777 xxx.sh #!/bin/bash # 设置备份目录和文件名 current_time$(date "%Y%m%d_%H%M%S") backup_dir"/root/db_back/db" backup_file"$backup_dir/db_ship_backup_$current_time.sql" log_file&…

【JavaEE初阶】网络原理|认识协议|协议分层|TCP/IP模型|封装和分用

一、认识协议 1.概念 简单来说&#xff1a;就是一种通信双方&#xff0c;对于通信规则的约定&#xff08;标准&#xff09;&#xff0c;一定是通信双方都认可的 但是这个协议不一定是认可面非常广的&#xff0c;即使是两个人之间的也可叫做协议 就好⽐⻅⽹友&#xff0c;彼此…

Docker搭建项目管理软件禅道

文章目录 一、简介二、部署三、使用 一、简介 禅道是以项目管理为核心的协作平台&#xff0c;旨在帮助团队高效地进行项目管理和协作。 禅道提供了项目管理、任务管理、团队协作、文档管理、报告统计等功能。 禅道官网 二、部署 操作系统&#xff1a;22.04.4 创建文件夹 …

Linux驱动开发——(三)并发与竞争

目录 一、并发与竞争简介 二、原子操作 2.1 原子操作简介 2.2 原子整形操作API 2.3 原子位操作API 2.4 原子操作驱动代码 三、自旋锁 3.1 自旋锁简介 3.2 自旋锁API 3.3 自旋锁驱动代码 四、信号量 4.1 信号量简介 4.2 信号量API 4.3 信号量驱动代码 一、并发与…

Redis-cluster集群架构

一、集群架构 上述集群架构师一个由多个主从节点群组成的分布式服务器&#xff0c;具有复制、高可用和分片的特性。Redis集群不需要sentine哨兵也能完成节点移除和故障转移。官方文档称可以扩展上万个节点。推荐不超过1000个&#xff1b;从节点只担任备份的角色&#xff0c;不承…

JavaWeb过滤器

Javaweb过滤器是一种用于在Servlet处理请求之前或之后对请求进行预处理或后处理的组件。过滤器可以用于拦截请求、修改请求参数、过滤响应内容等操作。其主要作用包括&#xff1a; 拦截请求&#xff1a;过滤器可以拦截客户端请求&#xff0c;对请求进行验证、过滤或修改&#x…

STL-list的使用及其模拟实现

在C标准库中&#xff0c;list 是一个双向链表容器&#xff0c;用于存储一系列元素。与 vector 和 deque 等容器不同&#xff0c;list 使用带头双向循环链表的数据结构来组织元素&#xff0c;因此list插入删除的效率非常高。 list的使用 list的构造函数 list迭代器 list的成员函…

【Interconnection Networks 互连网络】Dragonfly Topology 蜻蜓网络拓扑

蜻蜓拓扑 Dragonfly Topology 1. 拓扑参数2. Topology Description 拓扑描述3. Topology Variations 拓扑变体 蜻蜓拓扑 Dragonfly Topology 1. 拓扑参数 Dragonfly拓扑参数&#xff1a; N N N: 网络中终端(terminal)的总数量 p p p: 连接到每个路由器的终端数量 a a a: 每…

Go语言并发控制

channel // cancelFn 数据通道关闭通知退出 func cancelFn(dataChan chan int) {for {select {case val, ok : <-dataChan:// 关闭data通道时&#xff0c;通知退出// 一个可选是判断data指定值时退出if !ok {fmt.Printf("Channel closed &#xff01;&#xff01;&…

Rest接口/Nginx日志记录和采集

文章目录 一、Rest接口日志二、Nginx日志三、采集日志四、夜莺查看Nginx日志五、夜莺查看Rest接口日志 一、Rest接口日志 记录日志字典定义 接口URL接口名称,类别,入参全记录,出参全记录,入参字段1:中文名1/入参字段2:中文名2,出参字段1:中文名1/test/api/login账户登录,登录…

java-单列集合List详解

一、List概述 ​​​​​​​List 接口继承自 Collection 接口。这意味着所有 List 类型的对象都是 Collection 类型的对象&#xff0c;它们共享 Collection 接口中定义的所有方法。 List集合的特点&#xff1a; 1、有序&#xff1a;存和取得元素顺序一致 2、有索引&#xf…

Java- Object根父类

在java中&#xff0c;所有的类都有一个公共的父类&#xff0c;这个java.lang.Object类 * * * Object所有类的根&#xff0c;成为超类。 1.证明Object是根 public class A_Object01 {public static void main(String[] args) {//证明Object是根//基本数据类型int a 0;Object…

【硬十宝典】——1.4【基础知识】电源完整性——理解与设计

定义&#xff1a; 电源完整性&#xff08;Power integrity&#xff09;简称PI&#xff0c;是确认电源来源及目的端的电压及电流是否符合需求。 电源完整性在现今的电子产品中相当重要。有几个有关电源完整性的层面&#xff1a;芯片层面、芯片封装层面、电路板层面及系统层面。…

18-Echarts 配置系列之:数据集 dataset

简介&#xff1a; 数据集&#xff08;dataset&#xff09;是专门用来管理数据的组件。简化在每一个系列中设置数据&#xff0c;这一个配置是在Echarts4 中开始支持。 通过数据集配置&#xff0c;避免为每一个系列创建一个数据&#xff0c;避免格式转化的痛苦。 简单举例&…