%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MATLAB Code for %
% %
% Non-dominated Sorting Genetic Algorithm II (NSGA-II) %
% Version 1.0 - April 2010 %
% %
% Programmed By: S. Mostapha Kalami Heris %
% %
% e-Mail: sm.kalami@gmail.com %
% kalami@ee.kntu.ac.ir %
% %
% Homepage: http://www.kalami.ir %
% %
% nsga2.m : main file of the program %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear;
close all;
% for m=1:20
CostFunction=@MyCost5; %将MyCost5函数给CostFunction,以后用CostFunction来调用
TestProblem=5; %给后面的选择情况
npop=100; % main population size
nvar=10; % number of unknown variables
nobj=numel(CostFunction(zeros(1,nvar))); % number of objective functions
maxit=20; % maximum number of iterations迭代次数
VarMin=0; % lower bound of unknown variables
VarMax=1; % upper bound of unknown variables
VarRange=[VarMin VarMax]; % range of unknown variables
pc=0.8; % crossover ratio交叉比例
nc=round(pc*npop/2)*2; % number of parents (also offsprings)父代数目(子代)四舍五入
pm=0.3; % mutation ratio变异比率
nm=round(pm*npop); % number of mutants变异体的数量
% initialization
pop=CreateEmptyIndividuals(npop); %创建一个结构数组pop来保存个体npop的数据
for i=1:numel(pop) %生成position和cost的值
pop(i).Position=unifrnd(VarMin,VarMax,[1 nvar]); %unifrnd函数是生成(连续)均匀分布的随机数[变量及其范围],返回[1 nvar]数组
pop(i).Cost=CostFunction(pop(i).Position); %位置position(x)带入当然会生成cost(y)的值
end
% main loop
for it=1:maxit
[pop F]=NonDominatedSorting(pop); %快速非支配排序
pop=CalcCrowdingDistance(pop,F); %计算拥挤度
disp(['Iteration ' num2str(it) ': Number of 1st Front Individuals = ' num2str(numel(F{1}))]);
if it==maxit
break;
end
pop2=CreateEmptyIndividuals(nc); %初始化父代种群(具有六个属性)
for k=1:nc/2
p1=BinaryTournamentSelection(pop); %选择
p2=BinaryTournamentSelection(pop); %选择
ch=Crossover(p1,p2); %交叉
ch(1).Cost=CostFunction(ch(1).Position); %变异
ch(2).Cost=CostFunction(ch(2).Position); %变异
pop2(2*k-1)=ch(1);
pop2(2*k)=ch(2);
end
pop3=CreateEmptyIndividuals(nm);
for k=1:nm
p=BinaryTournamentSelection(pop); %选择
q=Mutate(p,VarRange); %交叉
q.Cost=CostFunction(q.Position); %变异
pop3(k)=q;
end
pop=[pop %产生下一代种群
pop2
pop3];
[pop F]=NonDominatedSorting(pop); %快速非支配排序
pop=CalcCrowdingDistance(pop,F); %计算拥挤度
pop=SortPopulation(pop); %重新排序后的种群
pop=pop(1:npop); %取排序后的前一百个最优
end
rep_costs=GetCosts(pop); %收集最后排序完的种群的损失信息
Np=500;
P1=0:1/Np:(Np-1)/Np; %以下情况选一种
switch TestProblem
case 1
P2=1-sqrt(P1); %ZDT1 and 4
case 2
P2=1-P1.^2; %for ZDT2
case 3
P2=1-sqrt(P1)-P1.*sin(10*pi*P1);%for ZDT3
Pd=P2(2:Np)-P2(1:Np-1);
ind=find(Pd>0);
P1(ind)=[];P2(ind)=[];
Ps=size(P2,2);
Pd=P2(2:Ps)-P2(1:Ps-1);
ind=find(Pd>0);
pss=size(ind,2);
P2(ind(pss)+1:Ps)=[];
P1(ind(pss)+1:Ps)=[];
for j=pss-1:-1:1
indJ=find(P2<P2(ind(j)));
P2(ind(j)+1:indJ(1)-1)=5;
end
ind=find(P2==5);
P1(ind)=[];
P2(ind)=[];
case 4
P2=1-sqrt(P1); %ZDT1 and 4
case 5
P1=1-exp(-4*P1).*sin(6*pi*P1).^6;%for ZDT6
P2=1-P1.^2;%for ZDT6
end
P=[P1;P2]; %目标函数y1y2
% Calculate Closeness to P* (Generational Distance) of the Pareto front in
% the final population.计算外部文档中的非支配解与函数真正的帕雷托解之间的平均距离
%计算最终人口中帕累托前沿的P *(代数距离)的亲密度
M=size(rep_costs,2); %rep_costs返回一个矩阵的第二维的长度(列数)
N=size(P,2); %rep_costs最后排序完成的种群,P是目标函数y1y2的种群
for i=1:M
for j=1:N
Dq1=0;
for k=1:nobj
Dq1=Dq1+(rep_costs(k,i)-P(k,j))^2; %求排序完的种群与目标函数的距离差值
end
Dq2(j)=sqrt(Dq1);
end
Dq(i)=min(Dq2);
end
GD=sqrt(sum(Dq.^2))/M; %平均距离
%计算当前文档中接的分布平均度
for i=1:size(rep_costs,2)
d1=[];
d2=[];
for k=1:size(rep_costs,2)
for j=1:nobj
d1(j)=abs(rep_costs(j,i)-rep_costs(j,k));
end
d2(k)=sum(d1);
end
s=find(d2==0);
d2(s)=[];
d(i)=min(d2);
end
d_average=mean(d);
eta=sqrt(sum((d_average-d).^2)/(M-1));
% Calculate diversity metrics of the Pareto front in the final population.
%计算最终人群中帕累托前沿的多样性指标
[rep_costs(1,:),IF1]=sort(rep_costs(1,:));
rep_costs(2,:)=rep_costs(2,IF1);
for k=1:nobj
dm1(k)=(rep_costs(k,1)-P(k,1))^2;
dm2(k)=(rep_costs(k,M)-P(k,N))^2;
end
DM1=sqrt(sum(dm1));
DM2=sqrt(sum(dm2));
DM=DM1+DM2;
for i=1:M-1
for j=1:nobj
di1(j)=(rep_costs(j,i)-rep_costs(j,i+1))^2;
end
di(i)=sqrt(sum(di1));
end
Davg=mean(di);
Ds=(DM+sum(abs(di-Davg)))/(DM+Davg*(M-1));
%画出非支配解的分布图(在适应度空间上)即帕雷托前沿的分布图
figure;
hold on
plot(P(1,:),P(2,:),'b-');
plot(rep_costs(1,:),rep_costs(2,:),'rx');
% end