|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
为了能随时了解Matlab主要操作及思想。 故本文贴上NSGA-Ⅱ算法Matlab实现(测试函数为ZDT1)。 感谢郭伟学长提供的代码。 代码所有权归郭伟学长。
3 {! ?5 L" U/ |2 H1 k; k- h! ?NSGA-Ⅱ就是在第一代非支配排序遗传算法的基础上改进而来,其改进主要是针对如上所述的三个方面:" V) R+ o' B+ ^ h' `
①提出了快速非支配排序算法,一方面降低了计算的复杂度,另一方面它将父代种群跟子代种群进行合并,使得下一代的种群从双倍的空间中进行选取,从而保留了最为优秀的所有个体;
: `8 o1 e* j5 C" [) `8 p②引进精英策略,保证某些优良的种群个体在进化过程中不会被丢弃,从而提高了优化结果的精度;
/ P! x- I0 E1 M" k! x③采用拥挤度和拥挤度比较算子,不但克服了NSGA中需要人为指定共享参数的缺陷,而且将其作为种群中个体间的比较标准,使得准Pareto域中的个体能均匀地扩展到整个Pareto域,保证了种群的多样性。
' ^( r: s4 i% b( z1 O8 v# H% V a; h8 a& l; `9 X6 o
Matlab实现:3 w' r$ U$ D- ?: ^) g I4 B
* ~3 M$ g/ S2 B* f2 W, ?- r
MATLAB
* W: S1 n) a/ X3 x
; [0 ] w2 g5 ifunction NSGAII()) ~2 N% [4 c9 N
clc;format compact;tic;hold on) d+ [& s+ y7 f. D" e
- P+ b" l# P+ K; C7 i# H%---初始化/参数设定
; o' _+ b- _* }: z5 V4 O generations=100; %迭代次数: ^7 r' U# D: K! g3 T% q6 K* ]
popnum=100; %种群大小(须为偶数)
$ c' h1 B( ^0 B1 q# h K4 }% L) P poplength=30; %个体长度3 C- w/ Z' y1 d
minvalue=repmat(zeros(1,poplength),popnum,1); %个体最小值
: Z# Y; ]# P, [8 o3 ]* u" X$ H maxvalue=repmat(ones(1,poplength),popnum,1); %个体最大值 * H9 J6 N" n0 z; N, h# V8 }
population=rand(popnum,poplength).*(maxvalue-minvalue)+minvalue; %产生新的初始种群 z8 j5 I3 T* t6 A6 z, l: l; C
. v5 ~5 B H' f% k. U( e
%---开始迭代进化0 ~& n8 J$ f' t4 D7 L3 C
for gene=1:generations %开始迭代7 S- V8 j$ N7 V5 ]8 d
" w" {8 Z' q. X( F5 p: ^1 ~/ B%-------交叉
0 z' H1 b6 K+ m2 ` newpopulation=zeros(popnum,poplength); %子代种群- U# F* G$ ~/ N/ B4 \
for i=1:popnum/2 %交叉产生子代% j: \ e7 A/ }! N/ q* I$ t
k=randperm(popnum); %从种群中随机选出两个父母,不采用二进制联赛方法, b/ r4 G# q$ r1 e: x
beta=(-1).^round(rand(1,poplength)).*abs(randn(1,poplength))*1.481; %采用正态分布交叉产生两个子代' u; F F/ d& P/ O2 C% p4 i& A
newpopulation(i*2-1,:)=(population(k(1),:)+population(k(2),:))/2+beta.*(population(k(1),:)-population(k(2),:))./2; %产生第一个子代
* B; P! A2 b8 W H' W newpopulation(i*2,:)=(population(k(1),:)+population(k(2),:))/2-beta.*(population(k(1),:)-population(k(2),:))./2; %产生第二个子代" c2 Y; W- w# c, J& D; |% t! {
end9 y: k4 i$ B0 Z5 [$ V- A8 c
6 R: p; `6 c9 n/ e& }1 h%-------变异 / v" Q7 g, w) D% P) f7 r- t( J
k=rand(size(newpopulation)); %随机选定要变异的基因位7 w1 e6 x$ l$ j9 T
miu=rand(size(newpopulation)); %采用多项式变异. Q9 e; v0 X, Z7 w7 \+ v# j- D
temp=k<1/poplength & miu<0.5; %要变异的基因位
( M3 ~- k3 K# `# Q 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); %变异情况一- O2 W" w. U# b5 Q" @/ ^
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 a+ L8 s# q9 U
6 }) y0 |$ g& b+ ?& Q%-------越界处理/种群合并
: g. O4 T0 \6 | o! s- R; _4 n newpopulation(newpopulation>maxvalue)=maxvalue(newpopulation>maxvalue); %子代越上界处理
% e5 M: Q H. {9 }( B$ I newpopulation(newpopulation<minvalue)=minvalue(newpopulation<minvalue); %子代越下界处理, c0 X' C: z8 N5 q: r) {, l
newpopulation=[population;newpopulation]; %合并父子种群: W$ D( D" D$ P4 |/ b: Y+ ^
6 \+ [0 `* \( o( |$ V8 J D- g. ]%-------计算目标函数值 ) Q4 ~5 D( j0 ^* V$ N! b
functionvalue=zeros(size(newpopulation,1),2); %合并后种群的各目标函数值,这里的问题是ZDT1* i: b: h" K( j' C& \* {9 ?7 {
functionvalue(:,1)=newpopulation(:,1); %计算第一维目标函数值
' T7 Y. _' ]- M g=1+9*sum(newpopulation(:,2:poplength),2)./(poplength-1);
" O9 j g8 `/ q$ m9 j% t& W functionvalue(:,2)=g.*(1-(newpopulation(:,1)./g).^0.5); %计算第二维目标函数值
/ D5 ^( F5 V9 k% }9 O/ |0 X* w# w8 R $ o$ G$ P$ w: C/ Q- A
%-------非支配排序
/ e2 x9 u7 R1 b0 @ fnum=0; %当前分配的前沿面编号
A0 ~7 a2 y3 c% L5 p1 D% x0 h cz=false(1,size(functionvalue,1)); %记录个体是否已被分配编号
' g, A4 y! Z6 J$ z: P* C frontvalue=zeros(size(cz)); %每个个体的前沿面编号
# I2 G1 F9 ~( H$ K J. h9 ~ [functionvalue_sorted,newsite]=sortrows(functionvalue); %对种群按第一维目标值大小进行排序
5 c2 ?0 Q/ o( a( _$ M0 i while ~all(cz) %开始迭代判断每个个体的前沿面,采用改进的deductive sort3 N' g! c, r* j W+ E! _ m
fnum=fnum+1;
/ e5 a7 {1 H x5 U8 ? d=cz;6 O' f' d; [& z# g# o5 d2 u2 t
for i=1:size(functionvalue,1)
, U' A! t1 V( p5 H3 @ if ~d(i)0 D6 q B( y8 e
for j=i+1:size(functionvalue,1)
, J5 l0 U, x/ j- Z0 B z' B if ~d(j)# i% F% @! v \" O4 ^+ n
k=1;
" j3 r, E. Z% O5 Q for m=2:size(functionvalue,2)* g! X5 D, x B; j, V$ s! F
if functionvalue_sorted(i,m)>functionvalue_sorted(j,m)
4 V3 v2 D) A1 z, O( y2 @* c' f k=0;* m! [# k( |' o
break- o' l6 l% \& V
end0 r: O* D6 h Y/ o! R7 ?3 q, @
end3 l0 g* D6 X8 J+ X, I) n, U( n# Q
if k
% J. H+ C3 `% G, |; M d(j)=true;+ {4 l! H# J! g, w% V# \" \2 k: ]
end# H- c7 \. V( E' q
end; X3 u2 C c5 y. r3 X. u
end; ~* l% y) ?& Q& G: @! C0 F( a2 C; T; E% U
frontvalue(newsite(i))=fnum;0 k1 L' z2 R, d& _5 F v" P6 `4 V6 ?. X
cz(i)=true;
1 [5 H( I. |2 {% y end6 {7 d$ H/ ^" L g
end) h, q0 ^9 W* t V
end
7 q5 ^ u/ V# G ) m& J4 a; g, w! N0 |
%-------计算拥挤距离/选出下一代个体 ( j1 K3 ]: d3 U1 a a7 F
fnum=0; %当前前沿面# T( @. ^3 M z+ R
while numel(frontvalue,frontvalue<=fnum+1)<=popnum %判断前多少个面的个体能完全放入下一代种群
& q4 I& u, K" z4 g2 B fnum=fnum+1;, B- R" W6 x# H. k4 L1 d
end - ?7 P# g* u ~
newnum=numel(frontvalue,frontvalue<=fnum); %前fnum个面的个体数
7 K, n; ]% M" s6 z" Q$ _5 A population(1:newnum,:)=newpopulation(frontvalue<=fnum,:); %将前fnum个面的个体复制入下一代
7 M3 |6 `' c% e0 I3 f5 @5 G' W popu=find(frontvalue==fnum+1); %popu记录第fnum+1个面上的个体编号
6 i. Q- C a$ g7 Q7 k5 l1 { distancevalue=zeros(size(popu)); %popu各个体的拥挤距离5 Z$ `2 @- [4 C8 y& X( U% e
fmax=max(functionvalue(popu,:),[],1); %popu每维上的最大值 z5 w5 S2 y/ F& u! d7 p1 ^
fmin=min(functionvalue(popu,:),[],1); %popu每维上的最小值
& v% e; m4 t8 V) S9 w for i=1:size(functionvalue,2) %分目标计算每个目标上popu各个体的拥挤距离* ~6 p" X! \6 K1 j) X
[~,newsite]=sortrows(functionvalue(popu,i));
9 Z& g. J' O# N8 f- t0 u distancevalue(newsite(1))=inf;
& e) r' ?9 M! z% w distancevalue(newsite(end))=inf;
& M5 c% E0 ^: N S& `: ^ for j=2:length(popu)-1# R& |; U3 [ X1 X. ~* w8 b
distancevalue(newsite(j))=distancevalue(newsite(j))+(functionvalue(popu(newsite(j+1)),i)-functionvalue(popu(newsite(j-1)),i))/(fmax(i)-fmin(i));
3 F. U ?; u8 ]: H) U6 R' j end
% q$ X% m) a. {3 N! j$ t" T end 0 F) U3 i. q4 \: R
popu=-sortrows(-[distancevalue;popu]')'; %按拥挤距离降序排序第fnum+1个面上的个体7 j! K& s/ ?# T" }* d6 o
population(newnum+1:popnum,:)=newpopulation(popu(2,1:popnum-newnum),:); %将第fnum+1个面上拥挤距离较大的前popnum-newnum个个体复制入下一代
: }8 m$ m Y9 Q, x7 p" ?& p end
' G2 [: V+ O$ w8 ~
* b: ^& e% T6 J%---程序输出 & }. M* q- z5 u" u. n' P' T
fprintf('已完成,耗时%4s秒\n',num2str(toc)); %程序最终耗时
1 b: a) C3 a7 f1 X* }) C output=sortrows(functionvalue(frontvalue==1,:)); %最终结果:种群中非支配解的函数值8 R/ H: n* g* f* o, R/ x5 G
plot(output(:,1),output(:,2),'*b'); %作图
1 {6 ^, U. `1 M9 p axis([0,1,0,1]);xlabel('F_1');ylabel('F_2');title('ZDT1')
; f* x& D+ P4 T6 J% yend4 | d# j" U- p& j2 r! l7 F
$ w2 [: A: @9 [( Z) b6 U" e6 W! V
1 v- B8 V$ C9 f8 p u/ P, f1 X |
|