专栏首页图灵技术域NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)

NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)

为了能随时了解Matlab主要操作及思想。

故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。

感谢郭伟学长提供的代码。

代码所有权归郭伟学长。

在看Matlab实现之前,请先看一下NSGA-II算法概述

NSGA-II多目标遗传算法概述

NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面: ①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体; ②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度; ③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。

Matlab实现:

MATLAB

function NSGAII()
clc;format compact;tic;hold on
    
%---初始化/参数设定
 
    generations=100;                                %迭代次数
    popnum=100;                                     %种群大小(须为偶数)
    poplength=30;                                   %个体长度
    minvalue=repmat(zeros(1,poplength),popnum,1);   %个体最小值
    maxvalue=repmat(ones(1,poplength),popnum,1);    %个体最大值    
    population=rand(popnum,poplength).*(maxvalue-minvalue)+minvalue;    %产生新的初始种群
    
%---开始迭代进化
 
    for gene=1:generations                      %开始迭代
        
%-------交叉 
 
        newpopulation=zeros(popnum,poplength);  %子代种群
        for i=1:popnum/2                        %交叉产生子代
            k=randperm(popnum);                 %从种群中随机选出两个父母,不采用二进制联赛方法
            beta=(-1).^round(rand(1,poplength)).*abs(randn(1,poplength))*1.481; %采用正态分布交叉产生两个子代
            newpopulation(i*2-1,:)=(population(k(1),:)+population(k(2),:))/2+beta.*(population(k(1),:)-population(k(2),:))./2;    %产生第一个子代           
            newpopulation(i*2,:)=(population(k(1),:)+population(k(2),:))/2-beta.*(population(k(1),:)-population(k(2),:))./2;      %产生第二个子代
        end
        
%-------变异        
 
        k=rand(size(newpopulation));    %随机选定要变异的基因位
        miu=rand(size(newpopulation));  %采用多项式变异
        temp=k<1/poplength & miu<0.5;   %要变异的基因位
        newpopulation(temp)=newpopulation(temp)+(maxvalue(temp)-minvalue(temp)).*((2.*miu(temp)+(1-2.*miu(temp)).*(1-(newpopulation(temp)-minvalue(temp))./(maxvalue(temp)-minvalue(temp))).^21).^(1/21)-1);        %变异情况一
        newpopulation(temp)=newpopulation(temp)+(maxvalue(temp)-minvalue(temp)).*(1-(2.*(1-miu(temp))+2.*(miu(temp)-0.5).*(1-(maxvalue(temp)-newpopulation(temp))./(maxvalue(temp)-minvalue(temp))).^21).^(1/21));  %变异情况二
        
%-------越界处理/种群合并        
 
        newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理
        newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理
        newpopulation=[population;newpopulation];                               %合并父子种群
        
%-------计算目标函数值        
 
        functionvalue=zeros(size(newpopulation,1),2);           %合并后种群的各目标函数值,这里的问题是ZDT1
        functionvalue(:,1)=newpopulation(:,1);                  %计算第一维目标函数值
        g=1+9*sum(newpopulation(:,2:poplength),2)./(poplength-1);
        functionvalue(:,2)=g.*(1-(newpopulation(:,1)./g).^0.5); %计算第二维目标函数值
        
%-------非支配排序        
 
        fnum=0;                                             %当前分配的前沿面编号
        cz=false(1,size(functionvalue,1));                  %记录个体是否已被分配编号
        frontvalue=zeros(size(cz));                         %每个个体的前沿面编号
        [functionvalue_sorted,newsite]=sortrows(functionvalue);    %对种群按第一维目标值大小进行排序
        while ~all(cz)                                      %开始迭代判断每个个体的前沿面,采用改进的deductive sort
            fnum=fnum+1;
            d=cz;
            for i=1:size(functionvalue,1)
                if ~d(i)
                    for j=i+1:size(functionvalue,1)
                        if ~d(j)
                            k=1;                            
                            for m=2:size(functionvalue,2)
                                if functionvalue_sorted(i,m)>functionvalue_sorted(j,m)
                                    k=0;
                                    break
                                end
                            end
                            if k
                                d(j)=true;
                            end
                        end
                    end
                    frontvalue(newsite(i))=fnum;
                    cz(i)=true;
                end
            end
        end
        
%-------计算拥挤距离/选出下一代个体        
 
        fnum=0;                                                                 %当前前沿面
        while numel(frontvalue,frontvalue<=fnum+1)<=popnum                      %判断前多少个面的个体能完全放入下一代种群
            fnum=fnum+1;
        end        
        newnum=numel(frontvalue,frontvalue<=fnum);                              %前fnum个面的个体数
        population(1:newnum,:)=newpopulation(frontvalue<=fnum,:);               %将前fnum个面的个体复制入下一代                       
        popu=find(frontvalue==fnum+1);                                          %popu记录第fnum+1个面上的个体编号
        distancevalue=zeros(size(popu));                                        %popu各个体的拥挤距离
        fmax=max(functionvalue(popu,:),[],1);                                   %popu每维上的最大值
        fmin=min(functionvalue(popu,:),[],1);                                   %popu每维上的最小值
        for i=1:size(functionvalue,2)                                           %分目标计算每个目标上popu各个体的拥挤距离
            [~,newsite]=sortrows(functionvalue(popu,i));
            distancevalue(newsite(1))=inf;
            distancevalue(newsite(end))=inf;
            for j=2:length(popu)-1
                distancevalue(newsite(j))=distancevalue(newsite(j))+(functionvalue(popu(newsite(j+1)),i)-functionvalue(popu(newsite(j-1)),i))/(fmax(i)-fmin(i));
            end
        end                                      
        popu=-sortrows(-[distancevalue;popu]')';                                %按拥挤距离降序排序第fnum+1个面上的个体
        population(newnum+1:popnum,:)=newpopulation(popu(2,1:popnum-newnum),:);	%将第fnum+1个面上拥挤距离较大的前popnum-newnum个个体复制入下一代        
    end
 
%---程序输出    
 
    fprintf('已完成,耗时%4s秒\n',num2str(toc));          %程序最终耗时
    output=sortrows(functionvalue(frontvalue==1,:));    %最终结果:种群中非支配解的函数值
    plot(output(:,1),output(:,2),'*b');                 %作图
    axis([0,1,0,1]);xlabel('F_1');ylabel('F_2');title('ZDT1')
end

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • NSGA-Ⅱ算法C++实现(测试函数为ZDT1)

    https://www.omegaxyz.com/2017/04/14/nsga-iiintro/

    里克贝斯
  • matlab多目标优化算法之NSGA-Ⅱ【含源代码】

    当优化问题的目标函数为两个或两个以上时,该优化问题就是多目标优化。不同于单目标优化问题,多目标问题没有单独的解能够同时优化所有目标,也就是目标函数之间存在着冲...

    matlab爱好者
  • Jmetal 4+ 使用指南四使用Jmetal进行试验-NSGAIIStudy(一)

    演化计算与人工智能
  • NSGA-II多目标遗传算法概述

    Non dominated sorting genetic algorithm -II NSGA-Ⅱ是目前最流行的多目标遗传算法之一,它降低了非劣排序遗传算法...

    里克贝斯
  • Jmetal 4+ 使用指南三使用Jmetal进行试验

    演化计算与人工智能
  • 多目标进化算法应用于提高医药数据领域学习器的性能(CS AI)

    原文标题完整翻译:多目标进化算法应用于提高在医药数据领域使用整体特征选择和离散化模型的学习器的性能

    Donuts_choco
  • Jmetal 4+ 使用指南一以NSGA-II为例

    演化计算与人工智能
  • Jmetal 4+ 使用指南六 Experimentation example: StandardStudy

    演化计算与人工智能
  • NSGA2算法MATLAB实现(能够自定义优化函数)

    以前写了一个简单的NSGA2的算法能够用在ZDT1函数上:https://www.omegaxyz.com/2017/05/04/nsga2matlabzdt1...

    里克贝斯
  • 基于稀疏化鲁棒LS-SVR与多目标优化的铁水硅含量软测量建模

    今天跟大家分享一篇之前发表的文章,《基于稀疏化鲁棒LS-SVR与多目标优化的铁水硅含量软测量建模 》。 摘要: 针对高炉炼铁过程的关键工艺指标——铁水硅含量[...

    昱良
  • 遗传算法系列之五:多目标遗传算法和遗传编程

    在遗传算法深入研究的阶段,人们提出将各种将遗传算法应用到更广泛领域,从而产生了一些有趣的后续工作。这些后续工作中,多目标遗传算法和遗传编程由于它们重要...

    AlgorithmDog
  • 动态多目标优化研究综述

    转载自http://cjc.ict.ac.cn/online/onlinepaper/lrc-20207694828.pdf

    演化计算与人工智能
  • Jmetal 4+ 使用指南二

    并且生成四个文件,分别是目标函数值,决策变量值,log日志文件 这种方式指定的问题是写在main方法中的problem = new ZDT3("ArrayRea...

    演化计算与人工智能
  • 机器学习学习笔记(1) -- 简析入门

    机器学习是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科;机器学习是一种偏向于技术的方法,研究目的包括模式识别、神经网络和深...

    挽风
  • 论文研读-多目标自适应memetic算法

    演化计算与人工智能
  • matlab实现BP算法,预测上证指数涨跌

    乐说科技
  • Jmetal 4+ 使用指南七-并行算法

    演化计算与人工智能
  • Jmetal 4+ 使用指南五 使用Jmetal进行试验-Running the experiments

    这是因为相对地址在我目前的环境下win10+R下读不出来,因此此处换成绝对地址。在java环境中这种写法是正确的的,但是在R语言的环境中,这是有错误的 有两个地...

    演化计算与人工智能
  • Math-Model(一)算法综述

    美赛马上来了,总结一下这些年参赛的算法(我打编程位),数学建模主要模型不单独写,参考数学模型第四版教材即可,只给出编程中一些重要的算法目录,如果有方法漏写,请评...

    Pulsar-V

扫码关注云+社区

领取腾讯云代金券