草庐IT

MATLAB实现多目标粒子群优化算法(MOPSO)

乔木cc 2023-04-11 原文

MATLAB实现多目标粒子群优化算法(MOPSO)

这里如何用MATLAB实现多目标粒子群优化算法。
本教程参考:MATLAB实现多目标粒子群算法
对其中的优化项、优化目标项进行了简单的修改。优化项由1个修改成了2个,优化目标由2个修改成了3个。

同时,参考MATLAB源码,将该算法在C#上也进行了实现,有需要的可以参考:C#实现多目标粒子群优化算法(MOPSO)

程序源码下载链接:

链接:https://pan.baidu.com/s/1UML4slk6PN9rMFN8rbxP9g
提取码:hzdz

程序运行效果:

有2个优化目标函数,并且优化目标函数设置合理的情况下,理想情况下,MOPSO的优化结果在平面内成线状
有3个优化目标函数,并且优化目标函数设置合理的情况下,理想情况下,MOPSO的优化结果在空间内成面状,如下图所示。

MATLAB主要程序如下:

其中,1为MOPSO的主程序,2-11均为函数。

1、MOPSO的主程序

clc;
clear;
close all;
CostFunction = @(x) evaluate_objective(x);  %目标函数ZDT1
nVar = 2;                                     %变量个数
VarSize = [1 nVar];                            %变量矩阵大小
VarMin = 0;                                    %变量值定义域
VarMax = 360;                                  %注意: 该函数变量不能出现负值
MaxIt = 30;                                   %最大迭代次数
N = 40;                                        %种群规模
nRep = 50;                                     %档案库大小
w = 0.9;                                       %惯性权重系数
wdamp = 0.99;                                  %惯性权重衰减率
c1 = 1.7;                                      %个体学习因子
c2 = 1.8;                                      %全局学习因子
nGrid = 5;                                     %每一维的分格数
alpha = 0.1;                                   %膨胀率
beta = 2;                                      %最佳选择压
gamma = 2;                                     %删除选择压
mu = 0.1;                                      %变异概率
empty_particle.Position = [];                  %粒子位置向量
empty_particle.Velocity = [];                  %粒子速度向量
empty_particle.Cost = [];                      %粒子目标值向量
empty_particle.Best.Position = [];             %粒子最佳位置向量
empty_particle.Best.Cost = [];                 %粒子最佳目标值向量
empty_particle.IsDominated = [];               %粒子被支配个体向量
empty_particle.GridIndex = [];                 %粒子栅格索引向量
empty_particle.GridSubIndex = [];              %粒子栅格子索引向量
pop = repmat(empty_particle,N,1);              %repmat平铺矩阵%粒子初始空矩阵

for i = 1:N  %初始化N个个体
     % 产生服从均匀分布, VarSize大小的位置矩阵
     pop(i).Position = unifrnd(VarMin,VarMax,VarSize);
     pop(i).Velocity = zeros(VarSize);
     pop(i).Cost = CostFunction(pop(i).Position);
     pop(i).Best.Position = pop(i).Position;
     pop(i).Best.Cost = pop(i).Cost;
end

pop = DetermineDomination(pop);
rep = pop(~[pop.IsDominated]);
Grid = CreateGrid(rep,nGrid,alpha);
for i = 1:numel(rep)
 rep(i) = FindGridIndex(rep(i),Grid);
 % GridIndex = 绝对位置,.GridSubIndex = 坐标位置
end

%MOPSO主循环
 for it = 1:MaxIt
     for i = 1:N %逐一个体更新速度和位置,0.5的概率发生变异
         leader = SelectLeader(rep,beta);   %从支配个体轮盘赌选出全局最佳个体
         rep = [rep;pop(~[pop.IsDominated])];   %添加新的最佳栅格位置到库
         pop(i).Velocity = w*pop(i).Velocity + ...
             c1*rand(VarSize).*(pop(i).Best.Position-pop(i).Position)+ ...
             c2*rand(VarSize).*(leader.Position-pop(i).Position);    %速度更新
         pop(i).Position = pop(i).Position+pop(i).Velocity;   %位置更新
         pop(i).Position = limitToPosition(pop(i).Position,VarMin,VarMax);   %限制变量变化范围
         pop(i).Cost = CostFunction(pop(i).Position);   %计算目标函数值
         %应用变异策略
         pm = (1-(it-1)/(MaxIt-1)^(1/mu));  % 变异概率逐渐变小
         NewSol.Position = Mutate(pop(i).Position,pm,VarMin,VarMax);
         NewSol.Cost = CostFunction(NewSol.Position);   % 计算变异后的目标值
         if Dominates(NewSol,pop(i))
             pop(i).Position = NewSol.Position;
             pop(i).Cost  = NewSol.Cost;
         else %0.5的概率决定是否接受变异
             if rand < 0.5
                 pop(i).Position = NewSol.Position;
                 pop(i).Cost = NewSol.Cost;
             end
         end
         if Dominates(pop(i),pop(i).Best)   % 如果当前个体优于先前最佳个体,则替换之
             pop(i).Best.Position = pop(i).Position;
             pop(i).Best.Cost = pop(i).Cost;
         else %0.5的概率替换个体最佳
             if rand <0.5
                 pop(i).Best.Position = pop(i).Position;
                 pop(i).Best.Cost = pop(i).Cost;
             end
         end
     end   %每个个体
     
     rep =  DetermineDomination(rep);
     rep = rep(~[rep.IsDominated]);
     Grid = CreateGrid(rep,nGrid,alpha); 
    for i =1:numel(rep) 
        rep(i) = FindGridIndex(rep(i),Grid); 
    end 
    if numel(rep) > nRep 
        Extra = numel(rep)-nRep; 
        for e = 1:Extra 
            rep = DeleteOneRepMemebr(rep,gamma); 
        end 
    end 
     
    disp(['迭代次数 =',num2str(it)]); 
    w = w*wdamp; 
end 

figure(1); 
location = [rep.Cost];   %取最优结果
scatter3(location(1,:),location(2,:),location(3,:),'filled','b'); 
xlabel('f1');ylabel('f2'); zlabel('f3');
title('Pareto 最优边界图'); 
box on; 

2、evaluate_objective.m(对应主程序中的CostFunction)

%============================= 
%计算目标函数值 
%============================= 
function f =evaluate_objective(x) 

f(1) = x(1)*0.01;%优化目标1
f(2) = (361-x(1))*(361-x(2))*0.02;%优化目标2
f(3) = x(2)*0.01;%优化目标3
        
f = [f(1);f(2);f(3)]; 

end

3、DetermineDomination.m

%============================= 
%判断全局支配状况,返回0 = 非支配解 
%============================= 
function pop =DetermineDomination(pop) 
        nPop = numel(pop); 
        for i =1:nPop 
            pop(i).IsDominated = false;   %初始化为互不支配 
        end 
        for i = 1:nPop-1 
            for j = i+1:nPop 
                if Dominates(pop(i),pop(j)) 
                    pop(j).IsDominated = true; 
                end 
                    if Dominates(pop(j),pop(i)) 
                        pop(i).IsDominated = true; 
                    end 
            end 
        end 
end 

4、Dominates.m

%============================= 
%判断两个目标值x,y的支配状态 
% x支配y,返回1;y支配x,返回0 
%============================= 
function b = Dominates(x,y) 
        if isstruct(x) 
            x=x.Cost; 
        end 
        if isstruct(y) 
            y=y.Cost; 
        end 
        b=all(x<=y) && any(x<y); 
end 

5、CreateGrid.m

%============================= 
%创建栅格矩阵 
%============================= 
function Grid = CreateGrid(pop,nGrid,alpha) 
        c = [pop.Cost]; 
        cmin = min(c,[],2); 
        cmax = max(c,[],2); 
        dc = cmax-cmin; 
        cmin = cmin-alpha*dc; 
        cmax = cmax+alpha*dc; 
        nObj = size(c,1); 
        empty_grid.LB = []; 
        empty_grid.UB = []; 
        Grid = repmat(empty_grid,nObj,1); 
         
        for j = 1:nObj 
            cj = linspace(cmin(j),cmax(j),nGrid+1); 
            Grid(j).LB = [-inf cj]; 
            Grid(j).UB = [cj +inf]; 
        end 
end 

6、FindGridIndex.m

%============================= 
%栅格索引定位 
%============================= 
function particle = FindGridIndex(particle,Grid) 
        nObj = numel(particle.Cost); 
        nGrid = numel(Grid(1).LB); 
        particle.GridSubIndex = zeros(1,nGrid); 
        for j = 1:nObj 
            particle.GridSubIndex(j) = find(particle.Cost(j)<=Grid(j).UB,1,'first'); 
            %从左到右找到第一个目标值小于栅格值的位置 
        end 
        particle.GridIndex = particle.GridSubIndex(1); 
        for j = 2:nObj   % 左上角开始数到右下角,先数行再换行继续数 
            particle.GridIndex = particle.GridIndex-1; 
            particle.GridIndex = nGrid*particle.GridIndex; 
            particle.GridIndex = particle.GridIndex + particle.GridSubIndex(j); 
        end 
end

7、limitToPosition.m

%============================= 
%限制变量变化范围在定义域内 
%============================= 
function Position = limitToPosition(Position,VarMin,VarMax)     
        for i =1:size(Position,2) 
            if Position(i)<VarMin 
                Position(i) = VarMin; 
            elseif Position(i) > VarMax 
                Position(i) = VarMax; 
            end 
        end 
end 

8、SelectLeader.m

%============================= 
%从全局支配个体中找出一个最佳个体 
%============================= 
function leader = SelectLeader(rep,beta) 
        GI = [rep.GridIndex]; 
        OC = unique(GI); 
        %一个栅格可能被多个支配解占用 
        N = zeros(size(OC)); 
        for k =1:numel(OC) 
            N(k) = numel(find(GI == OC(k))); 
        end 
        % 计算选择概率,为了增加多样性,尽量不选多次出现的个体 
        % 如果N大P就小, 即多次出现的栅格点被选中的概率小 
        P = exp(-beta*N); 
        P = P/sum(P);  
        sci = RouletteWheelSelection(P);   %轮盘赌策略选择 
        sc = OC(sci);   % 轮盘赌选择的栅格点 
        SCM = find(GI==sc); 
        smi = randi([1 numel(SCM)]); 
        sm = SCM(smi); 
        leader = rep(sm);   %当前全局最佳位置点
end 

9、RouletteWheelSelection.m

%============================= 
%轮盘赌选择一个较好的支配个体 
%============================= 
function i = RouletteWheelSelection(P) 
        r = rand; 
        C = cumsum(P); 
        i = find(r<=C,1,'first'); 
end

10、Mutate.m

%============================= 
%使用变异策略 
%============================= 
function xnew = Mutate(x,pm,VarMin,VarMax) 
        nVar = numel(x); 
        j = randi([1 nVar]); 
        dx = pm*(VarMax-VarMin); 
        lb = x(j)-dx; 
        if lb<VarMin 
            lb=VarMin; 
        end 
        ub = x(j)+dx; 
        if ub > VarMax 
            ub = VarMax; 
        end 
        xnew = x; 
        xnew(j) = unifrnd(lb,ub); 
end

11、DeleteOneRepMemebr.m

%============================= 
%删除档案库中的一个个体 
%============================= 
function rep = DeleteOneRepMemebr(rep,gamma) 
        GI = [rep.GridIndex]; 
        OC = unique(GI); 
        N = zeros(size(OC)); 
        for k = 1:numel(OC) 
            N(k) = numel(find(GI == OC(k))); 
        end 
        P = exp(gamma*N); 
        P = P/sum(P); 
        sci = RouletteWheelSelection(P); 
        sc = OC(sci); 
        SCM = find(GI == sc); 
        smi = randi([1 numel(SCM)]); 
        sm = SCM(smi); 
        rep(sm) = []; 
end 

有关MATLAB实现多目标粒子群优化算法(MOPSO)的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. Matlab imread()读到了什么 (浅显 当复习文档了) - 2

    matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1

  3. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  4. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  5. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  6. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  7. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  8. ruby - Arrays Sets 和 SortedSets 在 Ruby 中是如何实现的 - 2

    通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复

  9. ruby - "public/protected/private"方法是如何实现的,我该如何模拟它? - 2

    在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定

  10. ruby - 实现k最近邻需要哪些数据? - 2

    我目前有一个reddit克隆类型的网站。我正在尝试根据我的用户之前喜欢的帖子推荐帖子。看起来K最近邻或k均值是执行此操作的最佳方法。我似乎无法理解如何实际实现它。我看过一些数学公式(例如k表示维基百科页面),但它们对我来说并没有真正意义。有人可以推荐一些伪代码,或者可以查看的地方,以便我更好地了解如何执行此操作吗? 最佳答案 K最近邻(又名KNN)是一种分类算法。基本上,您采用包含N个项目的训练组并对它们进行分类。如何对它们进行分类完全取决于您的数据,以及您认为该数据的重要分类特征是什么。在您的示例中,这可能是帖子类别、谁发布了该项

随机推荐