|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 uqHZau 于 2020-6-2 14:09 编辑
$ ]! \; u5 T* _7 N/ _5 V& |! A4 ]) i# {. \1 c0 Y8 ?! S
为了能随时了解Matlab主要操作及思想。7 v/ M1 V# k+ X
/ C& a3 ?4 F' D0 v/ _
故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。 & ~( _8 [ ]1 }. a8 K/ @: ~2 \; _
4 @7 W' g( N! N' q6 u$ N; f
NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面: ( P7 x) l; T5 @- C. D0 l
①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体; ! n: r% p8 f1 h4 ?: [
②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度;
2 K3 N/ [- C6 E7 G- F③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。
, B3 Z" |, d' ~8 }$ ^% H* X. \/ f* c) a+ Y
Matlab实现:
. Q% G+ D8 D/ r' o: q
1 o) A D2 N; d$ m+ kfunction NSGAII()+ Y T* {8 |( v. T6 T/ {
clc;format compact;tic;hold on/ S3 L/ L2 {* x
: m2 R- u$ i$ _' S& ~5 v: k; P%---初始化/参数设定0 |) c+ X% x, Z* }* x: h
generations=100; %迭代次数
0 M5 j$ d+ G+ l9 I) E$ w$ m popnum=100; %种群大小(须为偶数)" Q& v6 r9 ?, ]. v# K
poplength=30; %个体长度9 S9 n9 ]( _) V" B+ Z
minvalue=repmat(zeros(1,poplength),popnum,1); %个体最小值
, Y' N0 Q/ x' q. V maxvalue=repmat(ones(1,poplength),popnum,1); %个体最大值
% J; K: n- M$ |6 ~. e; k$ C! t* T# Z population=rand(popnum,poplength).*(maxvalue-minvalue)+minvalue; %产生新的初始种群2 n+ x7 F* [+ R( N. k# Y
# r0 t8 c9 {4 U
%---开始迭代进化% Z/ x' Q4 ~8 k' M0 I' t, x1 D
for gene=1:generations %开始迭代7 M; f2 t0 z2 G- K, R$ f/ C0 [) F
8 ]2 t5 T$ D" C9 s+ {- q. V* i
%-------交叉 / t6 ?: t* V0 b) v x( S- S% U
newpopulation=zeros(popnum,poplength); %子代种群
: P: T2 A; `7 U5 e- g for i=1:popnum/2 %交叉产生子代+ f7 k8 x: Q3 B9 m+ J f. k
k=randperm(popnum); %从种群中随机选出两个父母,不采用二进制联赛方法
7 E- ~7 H/ d8 J( l! e1 D beta=(-1).^round(rand(1,poplength)).*abs(randn(1,poplength))*1.481; %采用正态分布交叉产生两个子代
+ B5 F/ B& D: {; Q& }6 P% r. [) t newpopulation(i*2-1,: )=(population(k(1),: )+population(k(2),: ))/2+beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第一个子代
1 |! V. K( b9 h8 u1 @ newpopulation(i*2,: )=(population(k(1),: )+population(k(2),: ))/2-beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第二个子代2 C8 P# @2 E6 f* {0 \
end
/ I: \4 p9 z$ O( I: I0 Z# E u' ?. b, c6 `5 L0 X. x k
%-------变异 S, ]. _8 d6 j1 d: |' p
k=rand(size(newpopulation)); %随机选定要变异的基因位
$ Z, g, S. H) p i miu=rand(size(newpopulation)); %采用多项式变异
9 O* j9 j5 S+ J. T8 {8 O- ?& w temp=k<1/poplength & miu<0.5; %要变异的基因位. t9 t% |; ^" a& p9 g7 a, |/ Y
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); %变异情况一 f+ d2 F! ?4 L8 h3 P" `+ u
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)); %变异情况二
7 l i4 s; [! r, N6 ~2 C" j
3 e: m# A% b* l0 ?2 h, s# c%-------越界处理/种群合并
& @" L! E2 [5 F, z; ]% j- x newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理5 V1 G$ C7 k9 E/ J
newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理
: X7 m$ O! d$ K/ z3 {4 D' Y/ h# { newpopulation=[population;newpopulation]; %合并父子种群
. A9 [5 c- `2 u# `: x& M
3 K+ c' u0 o8 t8 n/ }%-------计算目标函数值
0 _& |2 n5 H3 [% T- M% N+ z- A; G% O functionvalue=zeros(size(newpopulation,1),2); %合并后种群的各目标函数值,这里的问题是ZDT1
8 s: E3 l9 L0 c' W functionvalue(:,1)=newpopulation(:,1); %计算第一维目标函数值
( E" y! X% ^ X g=1+9*sum(newpopulation(:,2:poplength),2)./(poplength-1);
- j* G0 a7 U+ L" K: z. y functionvalue(:,2)=g.*(1-(newpopulation(:,1)./g).^0.5); %计算第二维目标函数值
8 v) F, [# S5 p* d! K
0 N# f: Z/ ~+ H1 ]2 U/ `# h0 v8 E) C$ r%-------非支配排序
1 R, ^3 |1 g0 ^$ |6 m fnum=0; %当前分配的前沿面编号
; f3 W \- R( ], C* C' C0 B; w cz=false(1,size(functionvalue,1)); %记录个体是否已被分配编号
% F+ m; k9 X2 E7 h frontvalue=zeros(size(cz)); %每个个体的前沿面编号
" X: G1 M4 Z3 e% z0 ] Y# t7 w) N [functionvalue_sorted,newsite]=sortrows(functionvalue); %对种群按第一维目标值大小进行排序
" G. T+ J9 h( l while ~all(cz) %开始迭代判断每个个体的前沿面,采用改进的deductive sort
3 [8 c: l8 u- p. x) j fnum=fnum+1;
; W& U3 o( c$ M3 h }; x d=cz;
a. A+ k: r% f2 h: \' G0 w! d for i=1:size(functionvalue,1)
7 P5 e$ Q/ j4 |% f* x+ ^6 d if ~d(i)" I/ b' e' f& q7 [
for j=i+1:size(functionvalue,1)
9 {! b; G# S; D9 a7 z) D+ w+ t1 g if ~d(j)6 m8 O3 I& e8 }5 k2 o6 Z' }; j
k=1; : H1 A- r: W, h% _. p
for m=2:size(functionvalue,2)
3 F& X1 i% c( T9 d if functionvalue_sorted(i,m)>functionvalue_sorted(j,m)& s7 R( G% m; ^, Y, i/ C( |( c0 M* W
k=0;
* _" [6 ~- s; W) a break
# Y! {4 l5 |5 \5 \ end
5 M+ {" K3 r( q r4 d end9 f; ~# P% `! C1 @# _/ r, c
if k% s# I9 f8 x# O0 V
d(j)=true;; j& c0 @9 _$ K
end4 d! {, U% }2 M
end
& f8 }' P$ [. P% r end) J- t; k0 a: I( `' a9 a9 S; R
frontvalue(newsite(i))=fnum;
; H* @, N1 B/ L3 x7 ` cz(i)=true;
" E% |5 Z- {' M# }& N6 a end) U4 e0 n; i9 y1 n( @
end
$ K: k" Q) l# C end
! r' ?, n% ^- }! [! y- A$ P) ^+ h/ ]1 [, t" D4 |7 M
%-------计算拥挤距离/选出下一代个体
3 N# t7 I. P/ S1 u2 `) H% p @3 M# d# M fnum=0; %当前前沿面
- r3 W, W1 W" T. z3 O5 x while numel(frontvalue,frontvalue<=fnum+1)<=popnum %判断前多少个面的个体能完全放入下一代种群
9 S7 i! V @1 s5 M; Y% w! c fnum=fnum+1;
" e0 D+ |6 O, S5 [. [' |6 G end
: w7 l5 o: k! d p9 X newnum=numel(frontvalue,frontvalue<=fnum); %前fnum个面的个体数, q+ l1 S9 Y3 O" W- _0 i
population(1:newnum,: )=newpopulation(frontvalue<=fnum,: ); %将前fnum个面的个体复制入下一代
7 H3 T& `" u1 w" ]2 T$ @3 r popu=find(frontvalue==fnum+1); %popu记录第fnum+1个面上的个体编号
; G$ ^8 @: B$ b/ d* a3 Y& z distancevalue=zeros(size(popu)); %popu各个体的拥挤距离# r! T% U" B: {% p+ k% Y8 o4 A, @
fmax=max(functionvalue(popu,: ),[],1); %popu每维上的最大值
& H1 a! C; I: F fmin=min(functionvalue(popu,: ),[],1); %popu每维上的最小值
( l. ]1 X( g/ A+ @/ e! }8 t W for i=1:size(functionvalue,2) %分目标计算每个目标上popu各个体的拥挤距离
% {! U$ K8 F0 i5 b [~,newsite]=sortrows(functionvalue(popu,i));
3 p5 Y; y7 @7 ^( ~ distancevalue(newsite(1))=inf;
0 K( y* f2 c$ l distancevalue(newsite(end))=inf;
1 a0 w0 Q. B; p* H for j=2:length(popu)-1* h* |- h- n* n$ U: c9 Q, p. s2 ?
distancevalue(newsite(j))=distancevalue(newsite(j))+(functionvalue(popu(newsite(j+1)),i)-functionvalue(popu(newsite(j-1)),i))/(fmax(i)-fmin(i));8 [8 `. }* m* G$ m1 p# m
end, G; T, O- Y% ]& e8 f. j
end 0 x& u" }/ V5 B% I( s
popu=-sortrows(-[distancevalue;popu]')'; %按拥挤距离降序排序第fnum+1个面上的个体: S( P. o# s; P6 _- p2 k9 w. i+ P
population(newnum+1: popnum,: )=newpopulation(popu(2,1: popnum-newnum),: ); %将第fnum+1个面上拥挤距离较大的前popnum-newnum个个体复制入下一代
' l/ e. J3 [( j end
' y% F0 ~5 V0 D9 O0 Z, e& k4 t. A q7 a$ {+ V
%---程序输出 ' G! m5 p# g8 D
fprintf('已完成,耗时%4s秒\n',num2str(toc)); %程序最终耗时
5 [! k( S/ G$ Q t6 k1 s* g5 h output=sortrows(functionvalue(frontvalue==1,: )); %最终结果:种群中非支配解的函数值, ~3 p; S* W1 E' }$ @! n7 x
plot(output(:,1),output(:,2),'*b'); %作图. W; Y. z' c+ e2 U7 q/ e+ B7 E2 L
axis([0,1,0,1]);xlabel('F_1');ylabel('F_2');title('ZDT1')
8 f. Z& |" {" x1 l0 L' Z3 vend* Y: B0 Z' U9 U, l/ t
4 X9 Y9 r, ]* S
; e9 v6 H' |# ]6 {2 K, ~8 p6 t
/ p- v4 B; V8 Z8 e7 |' [1 G |
|