做实验需要解决多目标优化问题,之前也没用过Matlab,看代码也是学习Matlab语法的过程,所以很详细的注解了基本上每一行代码,下面代码亲测可以直接运行,如果有问题的地方欢迎指正。
下面代码可能有些长,主要是注释加的比较多,如果想要替换函数的话,直接在evaluate_objective里替换,在主函数里修改M和V即可
目录
4.快速非支配排序和拥挤度计算代码:non_domination_sort_mod
5.锦标赛选择过程:tournament_selection
7.生成新的种群(精英策略):replace_chromosome
一.NSGA-2算法简介
SGA2主要是对NSGA算法的改进。NSGA是N. Srinivas 和 K. Deb在1995年发表的一篇名为《Multiobjective function optimization using nondominated sorting genetic algorithms》的论文中提出的该算法在快速找到Pareto前沿和保持种群多样性方面都有很好的效果,不过在这么多年的应用中也出现了如下的一些问题:
1。非支配排序的时间复杂的很大,为O(MN3)。其中M为目标函数的数量,N为种群规模。
2。不支持精英策略。精英策略在保持好的个体及加速向Pareto前沿收敛方面都有很好的表现。
3。需要自己指定共享参数。该参数将对种群的多样性产生很大的影响。
关于MOP的理解可参考另一篇博客:https://blog.csdn.net/qq_39552268/article/details/111656270
二.NSGA-2算法整体流程图
流程图各个步骤旁边的是函数名对应下面的各个算法函数名
这是最终跑出的结果:
三.算法及各函数讲解
1.主函数:nsga_2_optimization
function nsga_2_optimization
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pop = 200; %种群数量
gen = 500; %迭代次数
M = 2; %目标函数数量
V = 30; %维度(决策变量的个数) 决策变量就是解的个数
min_range = zeros(1, V); %下界 生成1*30的个体向量 全为0
max_range = ones(1,V); %上界 生成1*30的个体向量 全为1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
chromosome = initialize_variables(pop, M, V, min_range, max_range);%初始化种群
chromosome = non_domination_sort_mod(chromosome, M, V);%对初始化种群进行非支配快速排序和拥挤度计算
for i = 1 : gen
pool = round(pop/2);%round() 四舍五入取整 交配池大小
tour = 2;%竞标赛 参赛选手个数
parent_chromosome = tournament_selection(chromosome, pool, tour);%竞标赛选择适合繁殖的父代
mu = 20;%交叉和变异算法的分布指数
mum = 20;
%% parent_chromosome 竞标赛选择的适合繁殖的父代 M 目标函数数量 V维度(决策变量的个数) mu = 20;%交叉和变异算法的分布指数 mum = 20;
%%min_range = zeros(1, V); %下界 生成1*30的个体向量 全为0
%%max_range = ones(1,V); %上界 生成1*30的个体向量 全为1 这个在这里用来约束解(Xi)的范围
%%offspring_chromosome不一定生成了500个后代
offspring_chromosome = genetic_operator(parent_chromosome,M, V, mu, mum, min_range, max_range);%进行交叉变异产生子代 该代码中使用模拟二进制交叉和多项式变异 采用实数编码
[main_pop,~] = size(chromosome);%父代种群的大小
[offspring_pop,~] = size(offspring_chromosome);%子代种群的大小
clear temp
intermediate_chromosome(1:main_pop,:) = chromosome;
intermediate_chromosome(main_pop + 1 : main_pop + offspring_pop,1 : M+V) = offspring_chromosome;%合并父代种群和子代种群
intermediate_chromosome = non_domination_sort_mod(intermediate_chromosome, M, V);%对新的种群进行快速非支配排序
%%精英选择 从子代和父代中选出Pop个
chromosome = replace_chromosome(intermediate_chromosome, M, V, pop);%选择合并种群中前N个优先的个体组成新种群
%%每计算100代清空下控制台
if ~mod(i,100)
clc;
fprintf('%d generatio