|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 uqHZau 于 2020-6-2 14:09 编辑
6 [4 P% E3 {$ M7 w9 e9 m/ u3 C2 N
2 B+ [! W# J+ l5 o8 E" D. d# o为了能随时了解Matlab主要操作及思想。
3 b+ ]# g) V$ U9 V# H
9 d8 C0 v5 i2 f$ D W2 y故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。
9 k8 _" U& L1 g2 Z! v6 m X% E& }) ~2 o/ W5 V1 a
NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面: " d: N: W0 ^+ s/ Y3 m2 P' V: X* l
①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体;
/ H9 Z" h9 U# K②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度; . A4 L, A, S* T0 m: k
③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。
5 a/ i- u# t' Q- d& e% V/ o- H# @/ \$ D% B
Matlab实现:
! k/ }5 x4 D, a# M, Y* c
# ? h- D5 x& |9 f- s" pfunction NSGAII()
; y7 p, x( h2 a! \6 A) ^clc;format compact;tic;hold on" N2 R1 }% x5 E' k3 \8 a
8 U- V! @! g" ^1 d% x$ _
%---初始化/参数设定% y; v) D, a/ @( c! E. e
generations=100; %迭代次数% c# G m. ^0 }" }
popnum=100; %种群大小(须为偶数)) K1 k; W Y! `$ b4 [# U1 I. k D
poplength=30; %个体长度3 f4 ^( @3 ^9 ~" k- i m
minvalue=repmat(zeros(1,poplength),popnum,1); %个体最小值; l6 F" q5 n5 i* U
maxvalue=repmat(ones(1,poplength),popnum,1); %个体最大值
5 Y$ ^3 c6 b/ t1 g2 ~ population=rand(popnum,poplength).*(maxvalue-minvalue)+minvalue; %产生新的初始种群% u% h0 }' T, J
$ v# R/ y. T* h5 U
%---开始迭代进化
% I2 M& C" z' { for gene=1:generations %开始迭代
' N0 r3 L6 [& ~6 m! B
# J; u# U+ f) f%-------交叉 4 c# a# ~/ J4 C0 S% z( K1 y% @2 ^
newpopulation=zeros(popnum,poplength); %子代种群$ [: Y( I) d* {! R. R( C4 f. {
for i=1:popnum/2 %交叉产生子代4 P, ^. t6 k1 R. s
k=randperm(popnum); %从种群中随机选出两个父母,不采用二进制联赛方法
7 G6 W9 N0 L% ? C beta=(-1).^round(rand(1,poplength)).*abs(randn(1,poplength))*1.481; %采用正态分布交叉产生两个子代
0 F5 s+ v5 h( j# |0 W newpopulation(i*2-1,: )=(population(k(1),: )+population(k(2),: ))/2+beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第一个子代
6 i- Z0 G2 k5 g& N+ [0 A- _2 e newpopulation(i*2,: )=(population(k(1),: )+population(k(2),: ))/2-beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第二个子代
" X% q6 H7 v( d5 I end
! K$ l4 H. ]4 b
+ J7 o$ z8 K; y1 i: T%-------变异
9 X* \* l1 c- x( Z) ?$ A1 A5 m, ^ k=rand(size(newpopulation)); %随机选定要变异的基因位0 g l" | G0 g! H" ?' r$ e& P
miu=rand(size(newpopulation)); %采用多项式变异
5 S/ V6 p" z0 a6 g- h temp=k<1/poplength & miu<0.5; %要变异的基因位: |. `2 h+ u v! H' x6 h
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); %变异情况一* P! |+ D+ }5 R' c* M1 o# g; b% p
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)); %变异情况二6 ^ A6 S1 [/ |, @' y2 H* d0 l
4 E0 n7 P5 Y9 H( \* ^%-------越界处理/种群合并 7 W' T+ b- V5 _ X! T& b0 z% f
newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理$ Z' J y% K; V2 X
newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理
3 }! O) E, L8 Q newpopulation=[population;newpopulation]; %合并父子种群
2 a A, h. e8 w9 n" z: n
7 q3 n" X. t/ H0 o1 ^ G2 V; G%-------计算目标函数值
' g) e( O+ w# S2 q2 H: A functionvalue=zeros(size(newpopulation,1),2); %合并后种群的各目标函数值,这里的问题是ZDT1
4 T) i0 p+ z- H9 D: k) Z# h% l functionvalue(:,1)=newpopulation(:,1); %计算第一维目标函数值" g; O; z& ?7 G' M7 l# e
g=1+9*sum(newpopulation(:,2:poplength),2)./(poplength-1);
$ V+ @% Z( n* m) h- ?; K functionvalue(:,2)=g.*(1-(newpopulation(:,1)./g).^0.5); %计算第二维目标函数值! b2 K8 _3 Y5 ~( U
- k, P; ?* M0 `, I# ^%-------非支配排序
" c5 F' O$ X2 s9 M4 K fnum=0; %当前分配的前沿面编号2 {) ]& j2 H0 a, d# B
cz=false(1,size(functionvalue,1)); %记录个体是否已被分配编号
5 Z9 p1 I/ o7 J9 K7 s9 N( A' K frontvalue=zeros(size(cz)); %每个个体的前沿面编号
3 p; C. a8 }9 x$ \ [functionvalue_sorted,newsite]=sortrows(functionvalue); %对种群按第一维目标值大小进行排序
+ W- v) ~1 O7 C while ~all(cz) %开始迭代判断每个个体的前沿面,采用改进的deductive sort
6 Z( N; w P g9 a fnum=fnum+1;9 V! ]9 i" `) E9 P
d=cz;- b' [3 x0 D) P. _( u* ^. r: l
for i=1:size(functionvalue,1)5 X; j( a& ?+ `2 _
if ~d(i) y$ a4 O4 _7 ?. _8 q: d# V
for j=i+1:size(functionvalue,1)
* k, P8 U3 c# ]( J. d if ~d(j)
" o: W! ?) ~" W k=1; 0 o1 |1 T- J% s! W& u
for m=2:size(functionvalue,2)
7 c0 c. [/ c# v; E) \: ~) i if functionvalue_sorted(i,m)>functionvalue_sorted(j,m)
( @1 [: u2 N& U( e k=0;; F: e$ z% Q$ o; z
break
0 N; J" V6 _5 }5 E4 f end
8 N4 j& J! {, ? @3 Q: O- `% e+ t2 ] end
, B" ~" @+ @7 g) S9 P% ? if k
/ F1 ?- e$ W( @& I% S3 n5 S, v d(j)=true;
8 F7 t- n+ G% x, Y7 p end
4 f) ^' O3 d# v k, k; h end
+ w+ F" w6 U6 a- ^. V- ~ end% [6 ~! R3 O# n* I p
frontvalue(newsite(i))=fnum;1 W6 ]' O4 d4 M5 x1 o; r! E
cz(i)=true;6 \) y" ~7 g. H, L) K2 w' A
end
% l5 O2 U. ^) s* d1 j$ ]- k end
& g: G k4 k, o+ T- ]* k end
& c9 O: H0 ]8 M1 M' r3 F/ L) [! `7 x& ~* N6 ~2 }) `
%-------计算拥挤距离/选出下一代个体
* u( @6 @0 F% z fnum=0; %当前前沿面
4 t: r8 ~0 b4 T3 Y9 ^ while numel(frontvalue,frontvalue<=fnum+1)<=popnum %判断前多少个面的个体能完全放入下一代种群! u, o7 ~2 S3 ~* `# }' i
fnum=fnum+1;% J m7 J+ E9 ^/ m; V5 S4 L
end
6 n# K; R6 b# ?. x! o/ ~+ v' U newnum=numel(frontvalue,frontvalue<=fnum); %前fnum个面的个体数
) s; d- i( ~$ w1 W" ]+ }8 h population(1:newnum,: )=newpopulation(frontvalue<=fnum,: ); %将前fnum个面的个体复制入下一代
9 p$ U7 A s! } popu=find(frontvalue==fnum+1); %popu记录第fnum+1个面上的个体编号* H6 ?! H6 w, Z7 F2 _% B( s: Q! d
distancevalue=zeros(size(popu)); %popu各个体的拥挤距离0 n3 P; t2 e; b( I
fmax=max(functionvalue(popu,: ),[],1); %popu每维上的最大值3 |" G2 o2 N( _8 _0 ^: B0 u
fmin=min(functionvalue(popu,: ),[],1); %popu每维上的最小值
5 t: ^8 T9 t/ x# z( o _' G( \ for i=1:size(functionvalue,2) %分目标计算每个目标上popu各个体的拥挤距离
) Z! t4 E) B* N2 S4 Q" H [~,newsite]=sortrows(functionvalue(popu,i));# ^1 Y! J5 c3 f$ \2 ~5 H
distancevalue(newsite(1))=inf;8 M1 H F9 I; h& \$ b, _3 [. H
distancevalue(newsite(end))=inf;9 j& b4 G7 m! j: q
for j=2:length(popu)-1
* c' H& X& L/ Q3 ^6 ?- |' F distancevalue(newsite(j))=distancevalue(newsite(j))+(functionvalue(popu(newsite(j+1)),i)-functionvalue(popu(newsite(j-1)),i))/(fmax(i)-fmin(i));
, D. @$ |2 H% _9 ^ end4 ?. O8 ~. D5 c+ @8 ~8 y8 X
end
6 @( }; K2 q4 K- _- X popu=-sortrows(-[distancevalue;popu]')'; %按拥挤距离降序排序第fnum+1个面上的个体4 @+ R, c0 L/ z% B
population(newnum+1: popnum,: )=newpopulation(popu(2,1: popnum-newnum),: ); %将第fnum+1个面上拥挤距离较大的前popnum-newnum个个体复制入下一代 $ g' \' w9 b' i& T+ l5 ]# A
end% z5 X$ ~: z( \1 I$ |
+ F' O* M- k8 K3 N%---程序输出 * W* G' F( @+ p/ l8 J% ~
fprintf('已完成,耗时%4s秒\n',num2str(toc)); %程序最终耗时* v, v4 v5 U' Q& o
output=sortrows(functionvalue(frontvalue==1,: )); %最终结果:种群中非支配解的函数值' z& C% @. m. c _2 M+ l
plot(output(:,1),output(:,2),'*b'); %作图2 ?. x% A/ l/ B9 \2 V, J
axis([0,1,0,1]);xlabel('F_1');ylabel('F_2');title('ZDT1')
4 {* T. S) Z, w+ H$ yend0 n! m: x- a( J, u
) V X& z% G2 @2 k% U5 d2 v
$ h0 n0 _ H. Y4 @ V: _
! o$ ?) j, N7 _, ~ |
|