|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 uqHZau 于 2020-6-2 14:09 编辑
" [$ D( b2 [( d. ` q9 n7 j9 K5 A- y, a- a- ]7 G3 v2 G
为了能随时了解Matlab主要操作及思想。7 ~) M$ C( C. S* ]8 u# G( y) H
3 f; X7 O5 K- P0 V' [' u
故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。
8 J s* a( y! g; _: ~- R, b+ e3 _ O) p) A- d" _5 c
NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面:
) m& Q% z0 `4 G& ^- v1 ]' P4 J# J+ d①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体; ' N0 k. h! ~7 ? ?5 C6 W9 N9 B& `
②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度; - C6 D) c4 H, F$ T, g% A$ b
③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。" O+ x# q" B& F0 K- E
# S) |+ N/ g7 k1 \/ W* O1 x1 F9 }Matlab实现:0 _. N" R7 ~9 \! I8 X* X& _ E$ t
# [0 h6 D8 e- D( d$ bfunction NSGAII()
) g+ i3 g$ _" Y2 pclc;format compact;tic;hold on
0 b. X X( u n! b/ k$ d; T2 @% _( F' B, j. v) R
%---初始化/参数设定) e+ _' g G4 S7 z
generations=100; %迭代次数' ^7 g, Z" Q4 |3 {& Q& [3 V
popnum=100; %种群大小(须为偶数)
7 O/ l ~" k. v& W, ? poplength=30; %个体长度
3 @0 T* ?5 A* D0 j+ T; N minvalue=repmat(zeros(1,poplength),popnum,1); %个体最小值
0 k q* S6 h7 Y- r, Z1 x maxvalue=repmat(ones(1,poplength),popnum,1); %个体最大值 : S' \7 ~1 g$ R! d* q7 {( `! E
population=rand(popnum,poplength).*(maxvalue-minvalue)+minvalue; %产生新的初始种群
- u" h: S8 f3 c, M. q+ ~( ?8 h1 v# @9 y$ K2 \# T7 F. U
%---开始迭代进化
6 W* p9 n+ X/ }1 v# w% \; ?1 }6 I for gene=1:generations %开始迭代
6 M9 }0 R5 ^. a/ x0 U
5 ~5 O& o/ L$ A# p6 \# q%-------交叉 / K- g* H" U+ ?. m! ^
newpopulation=zeros(popnum,poplength); %子代种群6 c, g* _# Z* h+ w& L S
for i=1:popnum/2 %交叉产生子代6 E i3 Y' b! |$ T& ]
k=randperm(popnum); %从种群中随机选出两个父母,不采用二进制联赛方法. X. [" {' W0 X2 ]4 n3 G, `
beta=(-1).^round(rand(1,poplength)).*abs(randn(1,poplength))*1.481; %采用正态分布交叉产生两个子代& u: v4 E, o; g) w: j! k; e, s, U
newpopulation(i*2-1,: )=(population(k(1),: )+population(k(2),: ))/2+beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第一个子代
& D! \* X$ S$ J9 j* ^# b; @ newpopulation(i*2,: )=(population(k(1),: )+population(k(2),: ))/2-beta.*(population(k(1),: )-population(k(2),: ))./2; %产生第二个子代; e. K* j; B5 z2 n( V2 d
end# i; B/ D1 Z& k) R/ e' @
; X! F- @2 L: a5 G- S" U+ x%-------变异
9 k# Z3 o2 F* T& o' S' h: r k=rand(size(newpopulation)); %随机选定要变异的基因位
5 q7 }: N) R7 e% n: L4 ?* U. I! P miu=rand(size(newpopulation)); %采用多项式变异+ F" ^. ^( e1 x1 n" A
temp=k<1/poplength & miu<0.5; %要变异的基因位
+ m I6 w* h- ^1 q8 O 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); %变异情况一
/ c' E! w# k3 c. n 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)); %变异情况二
$ u; Y O2 T+ b1 ^
h( ?5 j F; T: h- z%-------越界处理/种群合并 8 o! u$ a" O4 U8 y/ o
newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理
. v9 l5 u/ p+ x* d8 k, E newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理
# l6 L& ~3 y! S; X) a! }. W0 K5 M. Y newpopulation=[population;newpopulation]; %合并父子种群
( d4 [: H, {3 x g& M) [7 r- o* X# ^% N: [
%-------计算目标函数值 ( I4 p3 m2 j0 q5 H6 D3 m
functionvalue=zeros(size(newpopulation,1),2); %合并后种群的各目标函数值,这里的问题是ZDT1
- X- z/ D% l+ f. s/ L* P" B functionvalue(:,1)=newpopulation(:,1); %计算第一维目标函数值7 w& I% c1 B: U ?
g=1+9*sum(newpopulation(:,2:poplength),2)./(poplength-1);
6 G, r/ u d, V- L( ? functionvalue(:,2)=g.*(1-(newpopulation(:,1)./g).^0.5); %计算第二维目标函数值
0 H5 [# U/ U% m/ w6 j1 V. x. Y6 a c R- K8 L+ O' {! K3 ~
%-------非支配排序
) Y0 {) ?. \2 K& Z$ O fnum=0; %当前分配的前沿面编号7 Z; \/ m/ Q. ]
cz=false(1,size(functionvalue,1)); %记录个体是否已被分配编号8 j6 `& E& }6 ]: @
frontvalue=zeros(size(cz)); %每个个体的前沿面编号
* ~5 _9 v5 u! [/ Y [functionvalue_sorted,newsite]=sortrows(functionvalue); %对种群按第一维目标值大小进行排序( w3 X5 g, c; ]0 `
while ~all(cz) %开始迭代判断每个个体的前沿面,采用改进的deductive sort1 C- f8 y! H& U6 E
fnum=fnum+1;3 ^# C& \. A" `& y
d=cz;* [5 Z" N0 L# r9 s7 w$ i
for i=1:size(functionvalue,1)
2 l" T1 R) F L6 `- _ if ~d(i): p$ Y/ s3 u5 _+ o* V, L& U
for j=i+1:size(functionvalue,1)
6 [; z4 h+ g+ f7 P& s6 U if ~d(j)" }/ k w# R% V+ q% U- t1 F
k=1; . D. K5 }, s/ ^( ?- Y' N
for m=2:size(functionvalue,2)
3 n: d9 J V- F; n& o: U* C if functionvalue_sorted(i,m)>functionvalue_sorted(j,m)
. ?! G5 X8 _9 c2 r$ W7 _' g k=0;
6 b( g; h( u }- b9 G$ e8 t! y7 m& ? break
; A/ \. u+ l" U8 Z( E+ H end
1 b9 u2 ^ M% h! ]( m/ ^+ F9 { end
$ t/ q9 m& \* q' U9 W& g+ F9 l if k
% h0 F& f; a! g% X/ i: `. _ d(j)=true;7 b. A3 w* p$ w2 r
end8 t- {( Z, b) C$ k
end* f. c9 t0 O: y1 A, t: Z
end2 w# ]; Z# T+ n
frontvalue(newsite(i))=fnum;- H/ C& r' c+ N' M [7 `
cz(i)=true;
- ~8 v& H$ ~5 y% s* c3 p end8 e: j: N1 y( u3 l3 C; D' x
end( m; W: A7 o! z9 ~. m" B, z! f, G
end" J1 o4 k% ^) q9 F7 M# R; }# `9 R0 |
; }0 G# c" p5 |+ ~
%-------计算拥挤距离/选出下一代个体
5 A8 Y. i% d8 `% R8 x7 W fnum=0; %当前前沿面
K: i# z4 \3 W9 b) Y while numel(frontvalue,frontvalue<=fnum+1)<=popnum %判断前多少个面的个体能完全放入下一代种群, b; N$ d* A! U0 o- r6 W2 H
fnum=fnum+1;. o. V1 _* @: \: {* Z
end ; U0 t8 z# r( o! T; D8 v" q* b
newnum=numel(frontvalue,frontvalue<=fnum); %前fnum个面的个体数
& O# N1 C; M2 |# `, L1 O4 d# I population(1:newnum,: )=newpopulation(frontvalue<=fnum,: ); %将前fnum个面的个体复制入下一代
% V& X4 _7 i: N0 i2 W, w* y+ J' v popu=find(frontvalue==fnum+1); %popu记录第fnum+1个面上的个体编号' o4 O6 I0 M* U/ A' Z {
distancevalue=zeros(size(popu)); %popu各个体的拥挤距离
! e2 d7 q) H$ w5 Z fmax=max(functionvalue(popu,: ),[],1); %popu每维上的最大值
4 h: X" J9 j& E" G; _* u fmin=min(functionvalue(popu,: ),[],1); %popu每维上的最小值
9 ^# A8 V5 K$ q: ?* P for i=1:size(functionvalue,2) %分目标计算每个目标上popu各个体的拥挤距离
5 J& w5 X# u( m9 m [~,newsite]=sortrows(functionvalue(popu,i));2 T1 u7 v0 {* g. l3 @% ~8 {
distancevalue(newsite(1))=inf;
% V4 L+ H& N* a1 t7 j- L distancevalue(newsite(end))=inf;
+ @9 w2 w! X# m! t! ~5 C$ S for j=2:length(popu)-1 L8 G; L8 \4 T) l E, V* \
distancevalue(newsite(j))=distancevalue(newsite(j))+(functionvalue(popu(newsite(j+1)),i)-functionvalue(popu(newsite(j-1)),i))/(fmax(i)-fmin(i));6 c/ k2 `2 _. X9 ]# E
end
4 U0 y+ P- ?/ _" W" }$ {/ _ end . x* x; ?& U. B6 V) j7 `
popu=-sortrows(-[distancevalue;popu]')'; %按拥挤距离降序排序第fnum+1个面上的个体" v) \1 r( j$ T
population(newnum+1: popnum,: )=newpopulation(popu(2,1: popnum-newnum),: ); %将第fnum+1个面上拥挤距离较大的前popnum-newnum个个体复制入下一代
9 V' e m% f3 R; C- f/ b! l. C6 F end
& ?. F2 o+ z3 J, g
1 E! {4 c& q9 C" C+ w$ C%---程序输出 ( ^( L% _% J3 z9 F) ?9 \, }- c7 i
fprintf('已完成,耗时%4s秒\n',num2str(toc)); %程序最终耗时
. {! h! h* U% k6 E output=sortrows(functionvalue(frontvalue==1,: )); %最终结果:种群中非支配解的函数值
$ j/ Y1 e( q' u6 O$ U plot(output(:,1),output(:,2),'*b'); %作图- y2 }& u* \, C* V& I
axis([0,1,0,1]);xlabel('F_1');ylabel('F_2');title('ZDT1')6 m5 E6 k8 P9 h8 R( q# c% @, B
end/ q$ \! q7 n' v6 |. c1 m5 `/ C) ?* _
8 \" `4 i$ N( @2 q( G
* K2 w$ x. z; Z) u6 n
# x5 n6 w% u- G M3 L |
|