一、启动项目
1、方法一、用GUI工具运行
2、方法二、用程序运行(推荐)
直接用命令运行
%% NSGA-II求ZDT1问题
platemo('algorithm', @NSGAII, 'problem', @ZDT1, 'N', 100, 'M',2, 'D',10, 'maxFE', 1000);
下面步骤,主要基于这种方法步骤,故省去第一步里GUI里调用 cb_start的代码
二、分析 platemo里的前几行代码
分别是下面几行代码
[PRO,input] = getSetting(varargin);
Problem = PRO(input{:});
[ALG,input] = getSetting(varargin,Problem);
if nargout > 0
Algorithm = ALG(input{:},'save',0);
else
Algorithm = ALG(input{:});
end
Algorithm.Solve(Problem);
if nargout > 0
P = Algorithm.result{end};
varargout = {P.decs,P.objs,P.cons};
end
1、[PRO,input] = getSetting(varargin);
这行代码主要是根据输入的参数,获取算法和问题的名称
input为输入参数,PRO为问题的函数,即 @ZDT1
2、Problem = PRO(input{:});
这行代码将调用 @ZDT1 ,通常会调用它的构造函数。
因为 ZDT1 类继承于PROBLEM类,故先调用 PROBLEM 类的 PROBLEM 方法
然后调用子类ZDT1的方法
3、[ALG,input] = getSetting(varargin,Problem);
获取算法的设置,跳过
4、if nargout > 0
指的是调用当前函数是否需要返回,目前我们是直接调用platemo命令,没有接受返回值,故此处nargout=0
5、 Algorithm = ALG(input{:});
ALG 即 NSGA-II 类
input值如下
即调用 NSGAII类的构造方法
由于 NSGAII类继承了ALGORITHM类
故先调用 ALGORITHM 类的 ALGORITHM方法
因为 NSGAII类没有构造方法,这里也没有调用NSGAII里的main方法,故暂时不用看NSGAII具体代码
三、Algorithm.Solve(Problem);
1、Algorithm.Solve(Problem);
才是核心代码的入口,我们要具体看下做了什么
这里说下addpath部分,因为ALGORITHM和NSGA-II不在同一个目录下,调用可能找不到文件,所以需要addpath。
但是,如果我们这是一个单体项目,所有文件都加入到了MatLab路径(环境变量)中,往往不需要上面的addpath
2、看看 obj.main(obj.pro);
即 NSGAII类的main方法
终于到了算法的实现部分
四、NSGA-II的实现
1、初始化种群和求适应度
Population = Problem.Initialization();
ZDT1类没有Initialization方法,故调用 PROBLEM 类的Initialization方法
2、对初始化的种群进行非支配排序和拥挤度计算
[~,FrontNo,CrowdDis] = EnvironmentalSelection(Population,Problem.N);
这里面代码相对复杂,先求非支配排序,后计算个体拥挤度
总之,就是选出靠前的帕累托前沿的个体,选不满的话,对下一个帕累托前沿进行拥挤度计算排序,选拥挤度大的。
3、开始循环
while Algorithm.NotTerminated(Population)
4、基于非支配排序和拥挤度选择父代,采用二元锦标赛选取
MatingPool = TournamentSelection(2,Problem.N,FrontNo,-CrowdDis);
就是从100个种群里,每次挑选2个,这两个取最优的,然后重复操作。
5、采用交叉、变异产生子代,并求适应度
Offspring = OperatorGA(Problem,Population(MatingPool));
6、合并父代和子代,并求下一代
[Population,FrontNo,CrowdDis] = EnvironmentalSelection([Population,Offspring],Problem.N);
将父代和子代合并一起选择下一代,采用之前的非支配排序+拥挤度计算的方法。
具体就不看了
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏