多目标粒子群算法(MOPSO):原理讲解与代码实现 Matlab代码免费获取

news2024/11/27 4:39:43

        声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~

目录

粒子群算法

多目标粒子群算法

一、外部档案

二、突变算子

流程图

性能测评

完整代码


粒子群优化算法(PSO)是一种模拟鸟类觅食行为的算法,由Eberhart 和Kennedy 于1995年提出。这种算法因其操作简单、速度快等特点,在处理多目标优化问题时被广泛采用。多目标粒子群优化算法(MOPSO)由Carlos A. CoelloCoello 等人提出,旨在将传统的粒子群算法(PSO)扩展到多目标优化问题中。

MOPSO算法通过外部存档和Pareto支配基本原理来处理多个目标,具有适用范围广、设置参数少、优化结构简单的特点,在多个领域得到了广泛应用。相比于单目标算法,多目标算法考虑的内容更多,更容易受到审稿人的青睐。因此,本文将介绍该算法的原理与代码。

本期代码免费赠送,需要代码的小伙伴可直接拉到最后!

粒子群算法

作为群体智能演化算法,PSO模拟自然界中鸟类的觅食行为,将食物的位置类比为优化问题的最优解集,将鸟类的飞行方向与位置类比为粒子的速度和位置。根据全局最优(gBest)和个体历史最优(pBest)的信息交互,不断更新粒子的位置和速度,提高搜索效率、有效引导种群往PF方向收敛,但这也导致其可能陷入局部最优,其具体更新过程可以表示如下:

式中:Xi(t)为位置向量,Xi(t)=[xi1(t),xi2(t),…,xid(t)],Vi(t)为速度向量,Vi(t)=[vi1(t),vi2(t),…,vid(t)],Xi(t)和Vi(t)分别表示粒子i第t时刻的位置和速度,Xi(t+1)和Vi(t+1)分别为更新后的位置和速度;pBesti(t)和gBesti(t)分别表示粒子i在t时刻的历史最优位置和全局最优位置;w为惯性权重因子;c1和c2为大于零的加速因子;γ1, γ2∈[0,1]。

多目标粒子群算法

相比于刚刚的单目标粒子群算法,多目标粒子群算法MOPSO主要体现在两个方面的区别,一是外部档案,二是突变算子。

一、外部档案

外部档案即利用网格划分法对算法中的精英个体进行更新。首先,将目标空间划分为若干网格,任意一个网格都为考察对象,并计算外部存档内种群个体的适应度值;其次,计算每个网格内粒子个数,并将其作为分布密度,分布密度的倒数即为网格被选择概率,通过轮盘赌方式选择网格。最后,被选中的网格中随机确定精英个体位置。具体分为以下几个步骤:

1)目标空间划分

对目标空间进行划分时,需确定目标空间中每个维度的最大、最小边界(minFi ,maxFi)。通过边界计算网格的模,公式如下:

式中:Fi 为第 i 个维度的目标函数值, i =1,2, ……, n;M为第 i 个维度要划分的网格数。

2)计算网格内粒子数

遍历外部存档中的粒子,计算粒子所在网格编号。对于第i个粒子,通过公式(5)计算网格位置。

通过粒子编号可以确定粒子所处的网格位置,以此来确定,每个网格被选择的概率为

式中:Numk 为第 k 个网络的粒子数。

3)基于轮盘赌确定网格和猎物位置

通过轮盘赌方式确定网格。首先,需要将每个网格被选中的概率归一化处理,如下:

其次,计算各网格累积概率,如下: 

最后,通过生成随机数选择网格内的粒子。通过网格划分法确定猎物位置避免算法陷入局部最优的同时,为提升算法收敛速度,当种群超出边界时,算法不对个体直接赋边界值,而是超出界限的相应值赋予猎物位置,避免算法重复搜索边界位置。公式如下:

网格划分法基于划分网格内粒子数对网格进行选取,为算法提供了更优猎物位置使算法的Pareto前沿分布更加均匀。而且对超出搜索边界的个体位置选取返回猎物位置的更新方法而不是采取返回边界位置的更新方法,更加有效的提升了算法收敛速度。

二、突变算子

突变算子通过引入随机扰动,有效避免了粒子群陷入局部最优,提升了算法的全局搜索能力。均匀突变保证了随机性,而非均匀突变则随着迭代次数的增加逐渐减少突变程度,平衡了探索和开发的关系。

将粒子群分成三部分,分别是不进行突变、进行均匀突变和进行非均匀突变。

第一部分粒子不进行突变。

第二部分粒子,按照比例进行均匀突变,即随机改变一部分粒子的位置。均匀突变的粒子位置重新在搜索空间内生成。

第三部分粒子,进行非均匀突变,其突变程度随代数的增加而逐渐减小。

突变算子通过增加搜索空间的多样性以及不同类型的突变策略,保证算法在初期进行充分的探索,而在后期则逐渐收敛至最优解附近。

流程图

为了更清晰的展示PSO与MOPSO的流程,这边给出两个算法的流程图,非常清晰~

性能测评

为这边以三个多目标函数“ZDT1”、“ZDT3”、“Viennet2”为例,检测一下MOPSO的性能。图中有帕累托真实前沿,越靠近前沿面则代表效果越好。

ZDT1:

ZDT3:

Viennet2:

可以看到,绝大多数粒子都能够接近前沿面,但仍然有改进的空间~

完整代码

MOPSO完整代码如下:

function REP = MOPSO(params,MultiObj)
​
    % Parameters
    Np      = params.Np;
    Nr      = params.Nr;
    maxgen  = params.maxgen;
    W       = params.W;
    C1      = params.C1;
    C2      = params.C2;
    ngrid   = params.ngrid;
    maxvel  = params.maxvel;
    u_mut   = params.u_mut;
    fun     = MultiObj.fun;
    nVar    = MultiObj.nVar;
    var_min = MultiObj.var_min(:);
    var_max = MultiObj.var_max(:);
​
    % Initialization
    POS = repmat((var_max-var_min)',Np,1).*rand(Np,nVar) + repmat(var_min',Np,1);
    VEL = zeros(Np,nVar);
    POS_fit  = fun(POS);
    if size(POS,1) ~= size(POS_fit,1)
        warning(['The objective function is badly programmed. It is not returning' ...
            'a value for each particle, please check it.']);
    end
    PBEST    = POS;
    PBEST_fit= POS_fit;
    DOMINATED= checkDomination(POS_fit);
    REP.pos  = POS(~DOMINATED,:);
    REP.pos_fit = POS_fit(~DOMINATED,:);
    REP      = updateGrid(REP,ngrid);
    maxvel   = (var_max-var_min).*maxvel./100;
    gen      = 1;
​
    % Plotting and verbose
    if(size(POS_fit,2)==2)
        h_fig = figure(1);
        h_par = plot(POS_fit(:,1),POS_fit(:,2),'or'); hold on;
        h_rep = plot(REP.pos_fit(:,1),REP.pos_fit(:,2),'ok'); hold on;
        try
            set(gca,'xtick',REP.hypercube_limits(:,1)','ytick',REP.hypercube_limits(:,2)');
            axis([min(REP.hypercube_limits(:,1)) max(REP.hypercube_limits(:,1)) ...
                  min(REP.hypercube_limits(:,2)) max(REP.hypercube_limits(:,2))]);
            grid on; xlabel('f1'); ylabel('f2');
        end
        drawnow;
    end
    if(size(POS_fit,2)==3)
        h_fig = figure(1);
        h_par = plot3(POS_fit(:,1),POS_fit(:,2),POS_fit(:,3),'or'); hold on;
        h_rep = plot3(REP.pos_fit(:,1),REP.pos_fit(:,2),REP.pos_fit(:,3),'ok'); hold on;
        try
                set(gca,'xtick',REP.hypercube_limits(:,1)','ytick',REP.hypercube_limits(:,2)','ztick',REP.hypercube_limits(:,3)');
                axis([min(REP.hypercube_limits(:,1)) max(REP.hypercube_limits(:,1)) ...
                      min(REP.hypercube_limits(:,2)) max(REP.hypercube_limits(:,2))]);
        end
        grid on; xlabel('f1'); ylabel('f2'); zlabel('f3');
        drawnow;
        axis square;
    end
    display(['Generation #0 - Repository size: ' num2str(size(REP.pos,1))]);
​
    % Main MPSO loop
    stopCondition = false;
    while ~stopCondition
​
        % Select leader
        h = selectLeader(REP);
​
        % Update speeds and positions
        VEL = W.*VEL + C1*rand(Np,nVar).*(PBEST-POS) ...
                     + C2*rand(Np,nVar).*(repmat(REP.pos(h,:),Np,1)-POS);
        POS = POS + VEL;
​
        % Perform mutation
        POS = mutation(POS,gen,maxgen,Np,var_max,var_min,nVar,u_mut);
​
        % Check boundaries
        [POS,VEL] = checkBoundaries(POS,VEL,maxvel,var_max,var_min);       
​
        % Evaluate the population
        POS_fit = fun(POS);
​
        % Update the repository
        REP = updateRepository(REP,POS,POS_fit,ngrid);
        if(size(REP.pos,1)>Nr)
             REP = deleteFromRepository(REP,size(REP.pos,1)-Nr,ngrid);
        end
​
        % Update the best positions found so far for each particle
        pos_best = dominates(POS_fit, PBEST_fit);
        best_pos = ~dominates(PBEST_fit, POS_fit);
        best_pos(rand(Np,1)>=0.5) = 0;
        if(sum(pos_best)>1)
            PBEST_fit(pos_best,:) = POS_fit(pos_best,:);
            PBEST(pos_best,:) = POS(pos_best,:);
        end
        if(sum(best_pos)>1)
            PBEST_fit(best_pos,:) = POS_fit(best_pos,:);
            PBEST(best_pos,:) = POS(best_pos,:);
        end
​
        % Plotting and verbose
        if(size(POS_fit,2)==2)
            figure(h_fig); delete(h_par); delete(h_rep);
            h_par = plot(POS_fit(:,1),POS_fit(:,2),'or'); hold on;
            h_rep = plot(REP.pos_fit(:,1),REP.pos_fit(:,2),'ok'); hold on;
            try
                set(gca,'xtick',REP.hypercube_limits(:,1)','ytick',REP.hypercube_limits(:,2)');
                axis([min(REP.hypercube_limits(:,1)) max(REP.hypercube_limits(:,1)) ...
                      min(REP.hypercube_limits(:,2)) max(REP.hypercube_limits(:,2))]);
            end
            if(isfield(MultiObj,'truePF'))
                try delete(h_pf); end
                h_pf = plot(MultiObj.truePF(:,1),MultiObj.truePF(:,2),'.','color','g'); hold on;
            end
            grid on; xlabel('f1'); ylabel('f2');
            drawnow;
            axis square;
        end
        if(size(POS_fit,2)==3)
            figure(h_fig); delete(h_par); delete(h_rep); 
            h_par = plot3(POS_fit(:,1),POS_fit(:,2),POS_fit(:,3),'or'); hold on;
            h_rep = plot3(REP.pos_fit(:,1),REP.pos_fit(:,2),REP.pos_fit(:,3),'ok'); hold on;
            try
                set(gca,'xtick',REP.hypercube_limits(:,1)','ytick',REP.hypercube_limits(:,2)','ztick',REP.hypercube_limits(:,3)');
                axis([min(REP.hypercube_limits(:,1)) max(REP.hypercube_limits(:,1)) ...
                      min(REP.hypercube_limits(:,2)) max(REP.hypercube_limits(:,2)) ...
                      min(REP.hypercube_limits(:,3)) max(REP.hypercube_limits(:,3))]);
            end
            if(isfield(MultiObj,'truePF'))
                try delete(h_pf); end
                h_pf = plot3(MultiObj.truePF(:,1),MultiObj.truePF(:,2),MultiObj.truePF(:,3),'.','color','g'); hold on;
            end
            grid on; xlabel('f1'); ylabel('f2'); zlabel('f3');
            drawnow;
            axis square;
        end
        display(['Generation #' num2str(gen) ' - Repository size: ' num2str(size(REP.pos,1))]);
​
        % Update generation and check for termination
        gen = gen + 1;
        if(gen>maxgen), stopCondition = true; end
    end
    hold off;
end

其中有部分函数封装为了子函数,因篇幅原因文章中无法全部放下。

因此,需要完整代码(能够运行出结果展示中的图片)的小伙伴因此,需要完整代码的小伙伴只需点击下方小卡片,再后台回复关键词,不区分大小写:

MOPSO

若有其他更多代码需求或免费代码,可查看链接:更多代码链接

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式linux系统中SPI子系统原理分析01

大家好,今天给大家分享一下,如何使用linux系统中的SPI通信协议,实现主从设备之间的信息传递。 SPI是一种常见的设备通用通信协议。它是一个独特优势就是可以无中断发送数据,可以连续发送或接收任意数量的位。而在I2C和UART中,数据以数据包的形式发送,有限定位数。 …

【Java05】Java中的多维数组

从数组底层运行机制上看,Java没有多维数组一说。所谓多维数组,是说一个引用变量指向的元素也是引用变量。 例如,type[] arrayName是个指向type类型元素的数组。倘若type也是数组引用变量,比如int[],那么这个数组就可以…

算法题解记录29+++全排列(百日筑基)

一、题目描述 题目难度:中等 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示…

VUE3版本新特性

VUE3版本新特性 VUE3和VUE2的区别路由的使用vite安装项目新特性使用 1.VUE3和VUE2的区别 2020年9月18日,Vue.js发布版3.0版本,代号:One Piece 于 2022 年 2 月 7 日星期一成为新的默认版本! Vue3性能更高,初次渲染快55%, 更新渲染快133% 。…

ROS中使用超声波传感器(附代码)

在ROS中使用超声波传感器通常涉及到订阅或发布sensor_msgs/Range类型的消息。下面是一个简单的示例,展示了如何使用C在ROS中编写一个超声波传感器的驱动程序。这个例子假设你有一个超声波传感器连接到了Arduino或者其他微控制器,并且该微控制器已经通过串…

FreeRtos-09事件组的使用

1. 事件组的理论讲解 事件组:就是通过一个整数的bit位来代表一个事件,几个事件的or和and的结果是输出 #define configUSE_16_BIT_TICKS 0 //configUSE_16_BIT_TICKS用1表示16位,用0表示32位 1.1 事件组适用于哪些场景 某个事件若干个事件中的某个事件若干个事件中的所有事…

经历的分享

我是三本计算机科学技术跨考上岸的学生,本科阶段技术能力并没有掌握多少,在选择导师时屡屡碰壁,我当时向许多计算机方向的导师,比如大数据方向,计算机视觉 迁移学习和图像处理方向的导师全都拒绝了我,最终学校给我分配…

Ubuntu 在线或离线安装docker

查看自己的ubuntu版本 在终端中执行以下命令: lsb_release -a 终端中的复制粘贴: ctrl shift c ctrl shifr v 在线安装docker(不需要外网): 命令行安装:Ubuntu Docker -- 从入门到实践 看完…

Apollo9.0 PNC源码学习之Control模块(五)—— 基于LQR的横向控制

前面文章: Apollo9.0 PNC源码学习之Control模块(一) Apollo9.0 PNC源码学习之Control模块(二) Apollo9.0 PNC源码学习之Control模块(三) Apollo9.0 PNC源码学习之Control模块(四&…

git Fork或者git clone克隆别人的项目到自己的仓库如何保持原仓库同步

一、问题描述 有时候我们会clone别人的项目到自己的仓库来进行二次开发,开发好之后提交到自己的仓库,如有原仓库有更新了,可以选择性的进行同步 二、解决方法 这里以ruoyi-vue-pro得前端项目来进行演示,创建一个目录,在目录下随便创建一个文…

示例:WPF中TreeView自定义TreeNode泛型绑定对象

一、目的&#xff1a;在开发中经常需要绑定TreeView&#xff0c;所以定义了一个泛型的TreeNode<T>用来方便绑定对象和复用 二、实现 public partial class TreeNodeBase<T> : SelectBindable<T>, ITreeNode{public TreeNodeBase(T t) : base(t){}private Obs…

Milvus跨集群数据迁移

将 Milvus 数据从 A 集群&#xff08;K8S集群&#xff09;迁到 B 集群&#xff08;K8S集群&#xff09;&#xff0c;解决方案很多&#xff0c;这里提供一个使用官方 milvus-backup 工具进行数据迁移的方案。 注意&#xff1a;此方案为非实时同步方案&#xff0c;但借助 MinIO 客…

嵌入式技术学习——c51——串口

一、串口介绍。 串口是一个 通讯接口。成本低&#xff0c;容易使用&#xff0c;通信线路简单&#xff0c;可实现两个设备的相互通信 单片机的串口可以实现单片机于单片机&#xff0c;单片机与电脑&#xff0c;单片机与其他模块相互通信。 51单片机内部自带UART&#xff0c;通…

AI训练Checkpoint对存储的影响

检查点&#xff08;Checkpoints&#xff09;是机器学习和深度学习训练过程中的一个重要机制&#xff0c;旨在定期保存训练状态&#xff0c;以便在训练过程中遇到失败或中断时能够从中断处恢复训练&#xff0c;而无需从头开始。 随着模型参数量的剧增&#xff0c;Checkpoint文件…

智慧档案库房建设费用大概多少

智慧档案库房建设费用因地区、规模和具体需求而异&#xff0c;以下是一些常见费用项&#xff1a; 1. 建筑物建设费用&#xff1a;包括设计、施工、装修、材料等费用。 2. 设备费用&#xff1a;包括服务器、网络设备、存储设备、十防等硬件设备的费用。 3. 软件费用&#xff1a;…

Aeron:两个代理之间的单向IPC(One-way IPC between two agents)

一、概述 本例展示了如何通过 IPC 在调度于不同线程的两个代理之间传输缓冲区。在继续学习本示例之前&#xff0c;最好先复习一下Simplest Full Example &#xff0c;因为该示例展示的是 IPC 通信&#xff0c;没有增加代理的复杂性。读者还应熟悉Media Driver 流程构建如下&…

Maya 2024 mac/win版:创意无界,设计新生

Maya 2024是一款由Autodesk推出的业界领先的三维计算机图形软件&#xff0c;广泛应用于电影、游戏、广告等创意产业。这款软件以其强大的功能和卓越的性能&#xff0c;为艺术家们提供了一个实现创意梦想的平台。 Maya 2024 mac/win版获取 在建模方面&#xff0c;Maya 2024提供…

Linux_理解程序地址空间和页表

目录 1、进程地址空间示意图 2、验证进程地址空间的结构 3、验证进程地址空间是虚拟地址 4、页表-虚拟地址与物理地址 5、什么是进程地址空间 6、进程地址空间和页表的存在意义 6.1 原因一&#xff08;效率性&#xff09; 6.2 原因二&#xff08;安全性&#xff09; …

Langchain中使用Ollama提供的Qwen大模型进行Function Call实现天气查询、网络搜索

Function Call&#xff0c;或者叫函数调用、工具调用&#xff0c;是大语言模型中比较重要的一项能力&#xff0c;对于扩展大语言模型的能力&#xff0c;或者构建AI Agent&#xff0c;至关重要。 Function Call的简单原理如下&#xff1a; 按照特定规范&#xff08;这个一般是L…

TensorRT的循环样例代码

官方文档地址 https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#define-loops 非顺序结构&#xff0c;其内容确实有点乱&#xff0c;而且没有完整可运行的样例。 可以有多个IIteratorLayer, IRecurrenceLayer, and ILoopOutputLayer 层&#xff0c;…