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' x
Matlab实现:
$ D1 ~$ R$ ~1 ]! u
5 x- L3 q8 V! I/ T' G8 I `
MATLAB
7 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 on
0 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 sort
3 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 k
1 q( o0 f# {$ y: J
d(j)=true;
- f' ~8 ], f: u* ^+ ?- }) f3 P f
end
9 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! S
end
" 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