NSGA-II算法matlab程序(翻译)
NSGA-II算法共享
最近在学习多目标优化算法,涉及到NSGA-II算法,看了网上的很多资料,挺有收获。之前一直在学网上的代码,但是发现限制函数只能用来限制决策变量的变化区间(只能在初始化中实现),对于复杂的不等式限制函数却无能为力:发现好多人同我一样,都遇到过这个问题。终于找到这个示例文件,我就对照着之前的一篇注释https://blog.csdn.net/joekepler/article/details/80820240,自学了一遍。然后又把另一个可以添加约束条件的代码贴出来,和许多初学者共享。
流程图
借用之前的流程图,简单介绍一下这个算法。具体的内容可以去查论文。
1 主函数
函数初始化过程包含在主函数中运行。
clear all
global V M xl xu etac etam p pop_size pm
%设定全局变量
%函数需要设置一个测试问题序号,1-14分别对应着不同的测试函数,1-9为无限制测试函数,10-14为
%不等式限制的测试函数
% pop_size定义为种群的数量,V为设计变量数目,no_runs运行次数,gen_max种群最大值,
% M目标函数个数
p=input('Test problem index : \n');
pop_size=80; % 种群数量;
no_runs=1; % 算法执行轮数;
M=2; %目标函数个数;
gen_max=500; % 最大迭代次数,500次;
fname='test_case'; % 将目标函数及限制条件copy给fname;
if p==13, % OSY
pop_size=100;
no_runs=10;
end;
if (p==2 | p==5 | p==7), gen_max=1000; end;
if p<=9 % Unconstrained test functions
tV=[2;30;3;1;30;4;30;10;10];
V=tV(p);
txl=[-5*ones(1,V);zeros(1,V);-5*ones(1,V);-1000*ones(1,V);zeros(1,V);-1/sqrt(V)*ones(1,V);zeros(1,V); 0 -5*ones(1,V-1);zeros(1,V)];
txu=[10*ones(1,V); ones(1,V);5*ones(1,V);1000*ones(1,V);ones(1,V);1/sqrt(V) *ones(1,V);ones(1,V);1 5*ones(1,V-1);ones(1,V)];
xl=(txl(p,1:V)); % lower bound vector
xu=(txu(p,1:V)); % upper bound vectorfor
etac = 20; % distribution index for crossover
etam = 20; % distribution index for mutation / mutation constant
else % Constrained test functions
p1=p-9;
tV=[2;2;2;6;2]; %p=10-14分别对应的决策变量个数,例如p=10,tV=2;
V=tV(p1);
txl=[0 0 0 0 0 0;-20 -20 0 0 0 0;0 0 0 0 0 0;0 0 1 0 1 0;0.1 0 0 0 0 0];
txu=[5 3 0 0 0 0;20 20 0 0 0 0;pi pi 0 0 0 0;10 10 5 6 5 10;1 5 0 0 0 0];
%xl和xu分别是决策变量的上下限,txl,txu分别对应着决策变量的取值范围
%如p1=1,对应p=10,0<x1<5,0<x2<3
xl=(txl(p1,1:V)); % lower bound vector
xu=(txu(p1,1:V)); % upper bound vectorfor i=1:NN
etac = 20; % 交叉分布指数
etam = 100; % 变异分布指数
end
pm=1/V; % Mutation Probability
Q=[];
for run = 1:no_runs
%% 种群初始化
xl_temp=repmat(xl, pop_size,1);
xu_temp=repmat(xu, pop_size,1);
%将种群变量初始化到search domain的区间内
x = xl_temp+((xu_temp-xl_temp).*rand(pop_size,V));
%% Evaluate objective function
for i =1:pop_size
%初始化参数时,目标函数及限制函数值计算
[ff(i,:) err(i,:)] =feval(fname, x(i,:));
end
%归一化误差初始值,将多个目标函数的误差值作和,要求最后和为0;
error_norm=normalisation(err);
population_init=[x ff error_norm];
%对初始值进行非支配排序
[population front]=NDS_CD_cons(population_init);
iii = 0;
%% 按照迭代次数循环
for gen_count=1:gen_max
%锦标赛竞选代码
parent_selected=tour_selection(population);
%模拟二进制交叉和多项式变异
child_offspring = genetic_operator(parent_selected(:,1:V));
for ii = 1:pop_size
[fff(ii,:) err(ii,:)]=feval(fname, child_offspring(ii,:)); %对子代的种群进行目标值评估;
end
error_norm=normalisation(err);
child_offspring=[child_offspring fff error_norm];
%% INtermediate population (Rt= Pt U Qt of 2N size)生成含有2N条染色体的种群;
population_inter=[population(:,1:V+M+1) ; child_offspring(:,1:V+M+1)]; %合并父代和子代种群;
[population_inter_sorted front]=NDS_CD_cons(population_inter); % 对新的种群进行快速非支配排序;
%选择合并后种群中的前N个优先个体形成新的种群N;
new_pop=replacement(population_inter_sorted, front);
population=new_pop;
if mod(gen_count,100) == 0
fprintf('The iteration times = %f \n',gen_count);
end
end
new_pop=sortrows(new_pop,V+1);
paretoset(run).trial=new_pop(:,1:V+M+1);
Q = [Q; paretoset(run).trial];
end
%% 帕累托前沿plot
if run==1
plot(new_pop(:,V+1),new_pop(:,V+2),'*')
else
[pareto_filter front]=NDS_CD_cons(Q); % Applying non domination sorting on the combined Pareto solution set
rank1_index=find(pareto_filter(:,V