EDA365电子论坛网
标题:
NSGA2 算法Matlab实现
[打印本页]
作者:
uqHZau
时间:
2020-6-2 14:07
标题:
NSGA2 算法Matlab实现
本帖最后由 uqHZau 于 2020-6-2 14:09 编辑
" K9 N: j: {: a% \6 ^
+ q, K; H6 E' v' t2 N( ^
为了能随时了解Matlab主要操作及思想。
* F* T* G n# S8 V. g/ B
. E( s* b) H% s0 U2 u& Q
故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。
9 ^3 H8 K* I' ^0 T
6 C/ Y- P& ^) C& P, u8 n) d+ D9 [
NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面:
# S) u& s8 }7 U
①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体;
7 M& b7 R, U ^
②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度;
3 F" G# C4 _2 [' I
③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。
' Z, M2 U, E6 m" D
2 T/ g/ f6 ]* s5 M
Matlab实现:
0 ~& a# x5 Y. V# s2 a
. _' O/ v5 r: P- t9 ^* s
function NSGAII()
7 p% l7 u. }7 f" S6 W( d
clc;format compact;tic;hold on
# J5 f) D7 `+ ~# |3 V
+ s/ P! B6 m# l+ G$ u" v2 _4 V: E
%---初始化/参数设定
/ f( C$ Y( Z3 h/ Y
generations=100; %迭代次数
! G+ D3 Z, B% c2 S( d# r+ t& o
popnum=100; %种群大小(须为偶数)
- \/ x5 y; l: Q0 J' |
poplength=30; %个体长度
* M, o- L: r+ n( e0 `; S! z
minvalue=repmat(zeros(1,poplength),popnum,1); %个体最小值
% E$ W# |! Y, x8 I( j6 E3 r0 s0 n
maxvalue=repmat(ones(1,poplength),popnum,1); %个体最大值
: ~5 b9 h7 a) X _% t6 c5 |) W% y
population=rand(popnum,poplength).*(maxvalue-minvalue)+minvalue; %产生新的初始种群
. p1 G! U' \" a" H0 f
& u3 j! C2 f4 t8 j! q" M0 {
%---开始迭代进化
* ^: D* E% |0 i- |
for gene=1:generations %开始迭代
" Z0 n( U7 l2 a0 c0 }7 T
0 s k0 | v! Q4 Y7 N! ^
%-------交叉
! t; F- I: s5 U) l6 L2 D8 ^
newpopulation=zeros(popnum,poplength); %子代种群
" k5 g& d; B1 \9 e
for i=1:popnum/2 %交叉产生子代
, |3 G! @/ Y9 g' K
k=randperm(popnum); %从种群中随机选出两个父母,不采用二进制联赛方法
3 l$ l' B8 g% C* y
beta=(-1).^round(rand(1,poplength)).*abs(randn(1,poplength))*1.481; %采用正态分布交叉产生两个子代
* Y$ y; W1 L; W6 V$ \
newpopulation(i*2-1,: )=(population(k(1),: )+population(k(2),: ))/2+beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第一个子代
6 q7 d- [7 e( K! }
newpopulation(i*2,: )=(population(k(1),: )+population(k(2),: ))/2-beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第二个子代
/ [+ Q6 Q! A: P
end
- M% m7 g. c2 N
! E9 V- S9 a3 B/ u3 S
%-------变异
& T$ J; i' [1 M+ `) ?' v: Z+ s
k=rand(size(newpopulation)); %随机选定要变异的基因位
7 D# O Z2 l3 D9 M( B7 D: D
miu=rand(size(newpopulation)); %采用多项式变异
; }3 k# G5 h$ [) u- v k, s2 }
temp=k<1/poplength & miu<0.5; %要变异的基因位
. X9 H ]* R( t, Q7 U4 l6 }
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); %变异情况一
/ L4 A: N" e% Z/ x) v- _
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)); %变异情况二
1 R# P; p* w' r6 f8 ^0 R( ?
* l' L+ v3 k! Q* t) b- o, t
%-------越界处理/种群合并
0 h4 ?4 V! W L3 I, t$ W& w$ ]
newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理
9 Q4 M+ F0 t: Z9 E" A
newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理
" P- l( D; I4 E; H4 n6 s) _
newpopulation=[population;newpopulation]; %合并父子种群
! F7 R' n! D2 Y/ m% s$ l) y
* D& p/ T( Z1 T
%-------计算目标函数值
7 g& A0 i# {1 m7 w& v% p
functionvalue=zeros(size(newpopulation,1),2); %合并后种群的各目标函数值,这里的问题是ZDT1
- J% o1 Y. C$ _. ?) O. Q1 ]1 S9 s
functionvalue(:,1)=newpopulation(:,1); %计算第一维目标函数值
/ _( F5 r' A# D. D$ y1 B
g=1+9*sum(newpopulation(:,2:poplength),2)./(poplength-1);
: ~3 u. ]6 `/ n
functionvalue(:,2)=g.*(1-(newpopulation(:,1)./g).^0.5); %计算第二维目标函数值
9 q4 i' i: }1 u# I1 k
9 Z# S' H$ U( \5 n+ `9 Y
%-------非支配排序
3 D3 Y- u( k4 E0 N3 L' l
fnum=0; %当前分配的前沿面编号
6 v G: O1 y8 t5 s7 U
cz=false(1,size(functionvalue,1)); %记录个体是否已被分配编号
8 q1 V, {- F1 H1 b. F( o
frontvalue=zeros(size(cz)); %每个个体的前沿面编号
- f! `$ w( J& e! x
[functionvalue_sorted,newsite]=sortrows(functionvalue); %对种群按第一维目标值大小进行排序
" R( ?5 c7 P) t! v4 K
while ~all(cz) %开始迭代判断每个个体的前沿面,采用改进的deductive sort
0 u- A4 |# R$ C: y
fnum=fnum+1;
$ N/ }: G2 D7 q. L7 _
d=cz;
$ @# S% C" V7 r/ U3 Z/ i$ u. V6 j
for i=1:size(functionvalue,1)
+ z* V- c6 W, x2 e2 a
if ~d(i)
! V5 z( P1 E5 [& r! i9 x
for j=i+1:size(functionvalue,1)
: a" {5 N) p, z" ^ S* n
if ~d(j)
( J$ k, i- e, T; K4 f
k=1;
, G N+ d$ X8 W% P6 \
for m=2:size(functionvalue,2)
5 C$ x+ }3 H" e1 K
if functionvalue_sorted(i,m)>functionvalue_sorted(j,m)
- ?; f, r! @; I4 h- x
k=0;
$ L8 X) T! m' O5 T$ ~+ t x
break
: D4 M" t. ]. S& B5 L. k h/ X
end
7 H* n1 |% B+ {0 H
end
$ m; O4 C# y# \5 Y& k' V% K
if k
2 e9 Q# W; X3 P3 e
d(j)=true;
8 |; `! l2 X2 v
end
( Z8 D, e' }$ y: @
end
. Y8 b1 m1 A8 f
end
; S0 \ K6 }1 u5 o
frontvalue(newsite(i))=fnum;
. N/ |( f6 z8 P; O) c5 _' k8 e
cz(i)=true;
( G5 r5 m/ M; g# ?
end
+ X/ U$ R0 ~" z/ x
end
. h, B9 h# Z4 m' H! @) Z8 i: ~
end
9 ~8 h' O; ^% P! F; ?% i
/ s8 b: E9 e9 K* F% p: E) t3 C
%-------计算拥挤距离/选出下一代个体
4 X2 f. o9 M( n; m" v) l8 x
fnum=0; %当前前沿面
/ ?2 s! H$ S3 B0 c( e! z! E, x. f
while numel(frontvalue,frontvalue<=fnum+1)<=popnum %判断前多少个面的个体能完全放入下一代种群
( l4 W3 x% k# s6 k" v1 ^
fnum=fnum+1;
: Y6 T8 w" u1 {3 b s" E( R! v; Z
end
+ ^( _3 e% K) W* t2 t/ X+ s
newnum=numel(frontvalue,frontvalue<=fnum); %前fnum个面的个体数
- S6 C5 i! s" R8 `" a+ N
population(1:newnum,: )=newpopulation(frontvalue<=fnum,: ); %将前fnum个面的个体复制入下一代
& n1 q2 | F {) {. h, R
popu=find(frontvalue==fnum+1); %popu记录第fnum+1个面上的个体编号
6 {: l5 f! M/ y F6 W/ D, o, a8 ~
distancevalue=zeros(size(popu)); %popu各个体的拥挤距离
8 q5 r. F8 a# a4 e/ r' {
fmax=max(functionvalue(popu,: ),[],1); %popu每维上的最大值
1 t/ m& n3 H4 Y
fmin=min(functionvalue(popu,: ),[],1); %popu每维上的最小值
- i8 `( p$ ~5 [9 [7 d. K: |5 r1 W5 ]5 H3 i
for i=1:size(functionvalue,2) %分目标计算每个目标上popu各个体的拥挤距离
6 T5 I @+ k- e9 p
[~,newsite]=sortrows(functionvalue(popu,i));
. T$ ?5 r" n2 a4 }* J) y- W# j
distancevalue(newsite(1))=inf;
3 t& m2 T9 C8 U6 i4 b# K
distancevalue(newsite(end))=inf;
4 e/ {* d' m+ `! n6 A6 f
for j=2:length(popu)-1
0 s7 M& W+ W7 E
distancevalue(newsite(j))=distancevalue(newsite(j))+(functionvalue(popu(newsite(j+1)),i)-functionvalue(popu(newsite(j-1)),i))/(fmax(i)-fmin(i));
+ @+ K7 B- O' m& ?6 y& z
end
1 \1 l- X* O6 A2 f; N5 f4 v% \
end
2 y) D2 l( A, @6 b* m
popu=-sortrows(-[distancevalue;popu]')'; %按拥挤距离降序排序第fnum+1个面上的个体
: b6 {4 b! ^0 R/ k' Y/ I
population(newnum+1: popnum,: )=newpopulation(popu(2,1: popnum-newnum),: ); %将第fnum+1个面上拥挤距离较大的前popnum-newnum个个体复制入下一代
' }, z8 B" }9 q# C. {
end
# K0 W# v0 y. ~! o9 i4 H1 y/ M
' j# L; m/ K1 T" X7 i
%---程序输出
( w$ J( D$ X7 G d" i% f% [
fprintf('已完成,耗时%4s秒\n',num2str(toc)); %程序最终耗时
- m8 T5 @4 W9 |0 B, Y1 y
output=sortrows(functionvalue(frontvalue==1,: )); %最终结果:种群中非支配解的函数值
8 `1 X" t8 q+ [7 y8 ^5 T/ b
plot(output(:,1),output(:,2),'*b'); %作图
/ B: d4 r0 N! ]
axis([0,1,0,1]);xlabel('F_1');ylabel('F_2');title('ZDT1')
$ u/ H! }( @5 Z. \$ |" o% d [
end
$ x! x0 S' Y( [( y+ E6 _! ^* D
9 U; {: G8 l; G4 O
$ ?: g, l1 f2 W7 Y! u( k6 d' E, G
, W7 g# D. q9 G/ \
作者:
CCxiaom
时间:
2020-6-2 14:53
NSGA2 算法Matlab实现
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2