找回密码
 注册
关于网站域名变更的通知
查看: 422|回复: 1
打印 上一主题 下一主题

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

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-11-2 15:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
为了能随时了解Matlab主要操作及思想。5 w4 ]! n& x% e* i

# r  K( N: k1 ]3 V) h/ O故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。2 w$ I; D' v" i/ w4 p! v) d

5 a# ]* W+ a3 N4 n+ o感谢郭伟学长提供的代码。. p2 @6 Y* ]: c8 q; Y6 b+ g

/ f5 q& u2 s) d代码所有权归郭伟学长。. m7 u* `$ e2 p' l( J7 w% s- \7 S! S8 J

/ h% Q- h7 j! |* H6 [) J% o# ^NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面:
. X; e$ z* y4 s: s0 w①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体;
. ]: P+ _1 H# a- q( q②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度;9 g6 P& @3 Z7 z  u' }
③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。( Y; c  i& r/ i2 n2 H% @6 J8 l; G
/ q% L1 _" Y3 X& `$ l. P1 @+ l
Matlab实现:( t' b( N( R9 A6 e$ \& L* T

4 r$ b. x, I$ X! U& l& E. s1 r
  • function NSGAII()
  • clc;format compact;tic;hold on
  • %---初始化/参数设定

  • ; y5 L& q: f7 T2 F3 k" M
  •     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;    %产生新的初始种群
  • %---开始迭代进化

  • - _: J! Q0 L8 A; q2 e$ H
  •     for gene=1:generations                      %开始迭代
  • %-------交叉
  • - W& p4 Z3 k) B8 i3 M5 K) G6 ^
  •         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
  • %-------变异
  • + t. W  a; a8 y* z% y  j) R- A
  •         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));  %变异情况二
  • %-------越界处理/种群合并

  • ! Z6 g: r- i" V' ~+ F1 r( `0 G
  •         newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理
  •         newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理
  •         newpopulation=[population;newpopulation];                               %合并父子种群
  • %-------计算目标函数值

  • ) Z- D; z/ x1 a2 ~
  •         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); %计算第二维目标函数值
  • %-------非支配排序

  • * r8 l; y! ~$ j: I
  •         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
  • %-------计算拥挤距离/选出下一代个体

  • 3 w4 u/ ~# Z2 b8 G4 t  e5 t/ D
  •         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
  • 0 z6 L5 S: \# U# U5 B9 A
  • %---程序输出
  • 3 e% b: Z% r5 u
  •     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( l! t4 f$ x  [" w2 H
         

该用户从未签到

2#
发表于 2020-11-2 16:33 | 只看该作者
NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-2 07:52 , Processed in 0.140625 second(s), 24 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表