EDA365电子论坛网

标题: NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1) [打印本页]

作者: pulbieup    时间: 2020-9-16 17:05
标题: NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)
为了能随时了解Matlab主要操作及思想。
故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。
感谢郭伟学长提供的代码。
代码所有权归郭伟学长。
在看Matlab实现之前,请先看一下:NSGA-II多目标遗传算法概述
$ h9 ~0 ]$ K) O" e) {5 O3 y; T5 r' s
NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面:6 y& |' U/ b' T- |1 G3 s! x
①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体;
' g% S8 D: {3 y* s②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度;! f) ^& G, o" h/ S9 Z' M/ X
③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。4 G5 f; l) e+ R. y

9 s& G! o6 b' xMatlab实现:$ D1 ~$ R$ ~1 ]! u

5 x- L3 q8 V! I/ T' G8 I  `MATLAB7 y$ m! P: D0 a* @( d; S+ E
* R1 I5 i4 @; a- m8 m
function NSGAII()2 d% t! ?1 r! e5 f: l
clc;format compact;tic;hold on0 E$ b2 a/ {* c& _, L" O$ F/ K0 k( K' ^
    0 }- I) d( T4 s  _# X
%---初始化/参数设定
7 b9 i7 q, O* R. f3 m    generations=100;                                %迭代次数; \) b( P, {- D! r
    popnum=100;                                     %种群大小(须为偶数)
: X# b7 o: E# W7 x( l$ m. Q/ O    poplength=30;                                   %个体长度9 @7 J0 K0 i  i3 v
    minvalue=repmat(zeros(1,poplength),popnum,1);   %个体最小值# G+ y, z3 B4 ~& Z
    maxvalue=repmat(ones(1,poplength),popnum,1);    %个体最大值   
! X2 b5 N: r; g3 o$ }, }  L    population=rand(popnum,poplength).*(maxvalue-minvalue)+minvalue;    %产生新的初始种群
! q! f! D6 Z) S) ]    % U, S3 Q! q0 g0 u
%---开始迭代进化
6 J3 P# n  G9 J2 M. f( W6 L    for gene=1:generations                      %开始迭代. V$ x. Q7 g7 A* g) L$ k
        
; M5 G4 ~! D6 p  l1 m* j%-------交叉 5 o. B0 @8 k* O* N6 \
        newpopulation=zeros(popnum,poplength);  %子代种群% ]$ _9 |, H2 @% |$ e* ^
        for i=1:popnum/2                        %交叉产生子代
) _( s2 `! H) v# g            k=randperm(popnum);                 %从种群中随机选出两个父母,不采用二进制联赛方法  T! S( h5 c* e. t$ o. Q0 g
            beta=(-1).^round(rand(1,poplength)).*abs(randn(1,poplength))*1.481; %采用正态分布交叉产生两个子代
; m) H0 d5 c! q* F            newpopulation(i*2-1,:)=(population(k(1),:)+population(k(2),:))/2+beta.*(population(k(1),:)-population(k(2),:))./2;    %产生第一个子代           
" ~: W5 J# v4 Y/ r            newpopulation(i*2,:)=(population(k(1),:)+population(k(2),:))/2-beta.*(population(k(1),:)-population(k(2),:))./2;      %产生第二个子代% M6 T  ]2 f, s$ [' u0 P8 @
        end
( S8 z; L  b3 @1 t' y! l        ; R+ a8 R# o2 n7 m) h/ v/ r: a+ K
%-------变异        , K) ^9 q, m) @
        k=rand(size(newpopulation));    %随机选定要变异的基因位
5 f9 ]5 E; N4 s8 d/ Z        miu=rand(size(newpopulation));  %采用多项式变异
/ E- _) h( @: \) H+ ?$ o' x        temp=k<1/poplength & miu<0.5;   %要变异的基因位  `& }0 J) H" d2 C
        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);        %变异情况一; X. i( t& B; {* ^7 i8 K$ w
        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));  %变异情况二
( C2 ^% B" A( n* C8 V! g. n        * d: o2 g6 S& J! S
%-------越界处理/种群合并        
, L1 s: z. `4 M2 P3 M  P        newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理# h' m- s: B: d: L
        newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理4 ?% c' ~& m( |5 O: L. q$ ?- s& G
        newpopulation=[population;newpopulation];                               %合并父子种群
2 U) l% w0 S; ]3 R, r& l7 ?: ]9 I        ! R. @; B4 P4 R
%-------计算目标函数值        7 _; X% f  {4 m+ \
        functionvalue=zeros(size(newpopulation,1),2);           %合并后种群的各目标函数值,这里的问题是ZDT1
: A6 f( t% ^+ l5 {        functionvalue(:,1)=newpopulation(:,1);                  %计算第一维目标函数值3 l  j/ j& H/ d! q: z; M
        g=1+9*sum(newpopulation(:,2:poplength),2)./(poplength-1);
1 y" V& O( E: l7 t- I! x7 k        functionvalue(:,2)=g.*(1-(newpopulation(:,1)./g).^0.5); %计算第二维目标函数值
; [3 g$ p+ [% X: U# X( g$ |        & M* w- ]# b+ C# _8 k9 \
%-------非支配排序        
! x) d. a9 r( R6 N+ V8 ]        fnum=0;                                             %当前分配的前沿面编号
' Y/ P/ s4 P$ i8 ?+ f/ i$ R( T        cz=false(1,size(functionvalue,1));                  %记录个体是否已被分配编号& ^$ r% J! C1 E& Y; Z6 Q$ ]  S
        frontvalue=zeros(size(cz));                         %每个个体的前沿面编号
# t" Q! u% }+ Y  B$ s/ \        [functionvalue_sorted,newsite]=sortrows(functionvalue);    %对种群按第一维目标值大小进行排序2 _- S2 ^2 i/ p7 O/ f- c
        while ~all(cz)                                      %开始迭代判断每个个体的前沿面,采用改进的deductive sort3 c; C2 G! s# ]
            fnum=fnum+1;
+ Q% H8 |/ O  I# @9 p7 a            d=cz;6 E, ]6 g( w4 @. Y3 M; |* i4 M
            for i=1:size(functionvalue,1)5 M" Z. O! s% f9 H4 W
                if ~d(i)! g/ L) u2 d. Y. {
                    for j=i+1:size(functionvalue,1)* v0 @$ G; X( T' V
                        if ~d(j)
1 \% u% Y$ G! m, D- x! b                            k=1;                            8 J1 L. ]' a9 ?1 l3 m( a/ e
                            for m=2:size(functionvalue,2)
. n: p  \1 a* A/ `8 }0 F                                if functionvalue_sorted(i,m)>functionvalue_sorted(j,m)
( t( d- Z4 C' ^# e- d                                    k=0;. i( k9 E% S& K; A8 E) i
                                    break
' b# Z1 g* d6 L                                end
8 N5 K" e7 ?+ K3 W4 |" e6 w2 x                            end
' P, M7 q8 G* w8 y3 T                            if k1 q( o0 f# {$ y: J
                                d(j)=true;- f' ~8 ], f: u* ^+ ?- }) f3 P  f
                            end9 Y1 q+ z4 d# g/ N% U8 H6 D
                        end
$ m* h4 M- I8 O3 X! l                    end
2 O% Y# P6 ?7 i, M) z                    frontvalue(newsite(i))=fnum;( j6 U9 v$ T( G
                    cz(i)=true;
& I! X+ f1 B2 Y& o  q' G& s4 [                end, S5 D) J* `+ t7 ?# u
            end
  s9 G* \. M, E: U        end
1 ^$ p2 x' o0 M# }" \0 _        
- a7 O; N  Y( |1 s1 J* x%-------计算拥挤距离/选出下一代个体          }6 m  K! P/ {7 @
        fnum=0;                                                                 %当前前沿面& t9 p% k, [' C# z! x, o% ?  Z
        while numel(frontvalue,frontvalue<=fnum+1)<=popnum                      %判断前多少个面的个体能完全放入下一代种群& T9 B- e1 n( K, r, ]
            fnum=fnum+1;
' ^  [% }2 e3 n& V        end        
2 _% T& h# E; j/ d/ H, d        newnum=numel(frontvalue,frontvalue<=fnum);                              %前fnum个面的个体数$ g+ ~9 U8 b# [6 f: p
        population(1:newnum,:)=newpopulation(frontvalue<=fnum,:);               %将前fnum个面的个体复制入下一代                       5 \. G3 j6 H8 ^9 O6 n5 ~" }
        popu=find(frontvalue==fnum+1);                                          %popu记录第fnum+1个面上的个体编号/ B; @  H% [& B0 g. e+ o
        distancevalue=zeros(size(popu));                                        %popu各个体的拥挤距离
0 y" @0 b) C+ z: W$ C2 |# M' |        fmax=max(functionvalue(popu,:),[],1);                                   %popu每维上的最大值4 N; S) n0 _' b+ g3 f) r
        fmin=min(functionvalue(popu,:),[],1);                                   %popu每维上的最小值4 k8 F9 @9 W; n! q
        for i=1:size(functionvalue,2)                                           %分目标计算每个目标上popu各个体的拥挤距离5 Z" \7 L) q% a) l3 W9 ~
            [~,newsite]=sortrows(functionvalue(popu,i));! R4 g8 J* J( V  x
            distancevalue(newsite(1))=inf;
/ E$ A7 M8 I1 c1 M9 m* C            distancevalue(newsite(end))=inf;$ _. _4 P5 c/ p6 E! `6 e
            for j=2:length(popu)-1
5 P; e; I; x) U4 `8 p! e" E7 Y                distancevalue(newsite(j))=distancevalue(newsite(j))+(functionvalue(popu(newsite(j+1)),i)-functionvalue(popu(newsite(j-1)),i))/(fmax(i)-fmin(i));
& \" {1 u) U" l8 O0 o. O4 {% S            end& p- ]9 y) V1 Q! G; M
        end                                        J! L  Y4 i/ e+ Q2 O
        popu=-sortrows(-[distancevalue;popu]')';                                %按拥挤距离降序排序第fnum+1个面上的个体( M& P9 J/ z# d# d5 U, i
        population(newnum+1:popnum,:)=newpopulation(popu(2,1:popnum-newnum),:);        %将第fnum+1个面上拥挤距离较大的前popnum-newnum个个体复制入下一代        2 g1 S$ _2 E! H% ?9 S
    end
+ j$ [+ c# Q& Q; s9 K9 g# }9 s1 g/ j$ [, b& \) ^  @3 W
%---程序输出   
- T' |/ a* o4 s    fprintf('已完成,耗时%4s秒\n',num2str(toc));          %程序最终耗时
2 W! Z4 }* o/ h2 T( v. I1 u    output=sortrows(functionvalue(frontvalue==1,:));    %最终结果:种群中非支配解的函数值( k7 j5 ~. i% u" ^/ P+ G& I
    plot(output(:,1),output(:,2),'*b');                 %作图/ |: M8 c( O9 x/ @9 s' n# u
    axis([0,1,0,1]);xlabel('F_1');ylabel('F_2');title('ZDT1')
. o4 b/ Q3 f7 d! Send" A& }) b9 M- X% U  V& l8 ?
- n2 u9 e- q- a  a3 e
( N% G- T2 U1 ~5 C

作者: hope123    时间: 2020-9-16 17:43
提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2