运行算法
要使用jMetal运行算法,您有两种选择:使用IDE或使用命令行。我们将在本节中解释这两种方法。我们首先讨论如何配置启发式算法来解决问题。
配置算法
在jMetal 5中,为了配置和运行算法,我们需要为此编写一个类;我们把这样的类称为runner。用外部配置文件配置算法的功能还未实现。
我们为jMetal中包含的每个算法都提供了至少一个runner类。它们可以在“jmetal exec”模块的文件夹中找到https://github.com/jMetal/jMetal/tree/master/jmetal-exec/src/main/java/org/uma/jmetal/runner/multiobjective.
作为示例代码,我们使用NSGA-II算法不同的runner类来展示配置和使用算法的不同方式:
NSGAIIRunner
: 标准NSGA-II的配置,用于解决连续变量的问题。NSGAIIIntegerRunner
: 用于解决整数问题的配置。NSGAIIBinaryRunner
: 用于解决二进制问题的配置。NSGAIIMeasuresRunner
: 似于NSGAIIRunner
,但它包括如何使用单位的示例。NSGAIIMeasuresWithChartsRunner
: 类似于NSGAIIMeasuresRunner
,但绘制一个图形,显示在执行算法期间帕累托前沿的演变。NSGAIIStoppingByTimeRunner
: 如何配置NSGA-II使其基于预定义的时间停止计算。ParallelNSGAIIRunner
: 和NSGAIIRunner
一样,但是使用多线程技术进行并行计算
我们接下来描述“NSGAIIRunner”类。Javadoc文档中标明了所需的参数:第一个是定义了所优化问题数学表达式的类;第二个参数是可有可无的,指向了包含参考帕累托前沿文件的路径,这个前沿近似于待解决问题的最佳帕累托前沿,如果提供,将用于计算程序优化的效果如何。下面就针对代码进行详细的叙述:
public class NSGAIIRunner extends AbstractAlgorithmRunner {
/**
* @param args Command line arguments.
* @throws JMetalException
* @throws FileNotFoundException
* Invoking command: java org.uma.jmetal.runner.multiobjetive.NSGAIIRunner problemName [referenceFront]
*/
public static void main(String[] args) throws JMetalException, FileNotFoundException {
“main”方法的第一部分声明了要解决的问题的类型(主要讨论“DoubleSolution”个体)和交叉变异等各种算子。“referenceParetoFront”用于指明可选的参考前沿:
Problem<DoubleSolution> problem;
Algorithm<List<DoubleSolution>> algorithm;
CrossoverOperator<DoubleSolution> crossover;
MutationOperator<DoubleSolution> mutation;
SelectionOperator<List<DoubleSolution>, DoubleSolution> selection;
String referenceParetoFront = "" ;
下一组代码对命令行进行了处理。当未指示任何参数时,默认情况下会解决基准问题(示例中为ZDT1):
String problemName ;
if (args.length == 1) {
problemName = args[0];
} else if (args.length == 2) {
problemName = args[0] ;
referenceParetoFront = args[1] ;
} else {
problemName = "org.uma.jmetal.problem.multiobjective.zdt.ZDT1";
referenceParetoFront = "jmetal-problem/src/test/resources/pareto_fronts/ZDT1.pf" ;
}
然后通过问题类的名称加载Problem对象:
problem = ProblemUtils.<DoubleSolution> loadProblem(problemName);
然后配置算子和算法:
double crossoverProbability = 0.9 ;
double crossoverDistributionIndex = 20.0 ;
crossover = new SBXCrossover(crossoverProbability, crossoverDistributionIndex) ;
double mutationProbability = 1.0 / problem.getNumberOfVariables() ;
double mutationDistributionIndex = 20.0 ;
mutation = new PolynomialMutation(mutationProbability, mutationDistributionIndex) ;
selection = new BinaryTournamentSelection<DoubleSolution>(new RankingAndCrowdingDistanceComparator<DoubleSolution>());
algorithm = new NSGAIIBuilder<DoubleSolution>(problem, crossover, mutation)
.setSelectionOperator(selection)
.setMaxEvaluations(25000)
.setPopulationSize(100)
.build() ;
最后一步是运行算法并将得到的解写入两个文件:一个用于变量值,一个用于存储每组变量计算得到的目标函数值;如果提供了参考前沿,还会打印计算解的准确性:
AlgorithmRunner algorithmRunner = new AlgorithmRunner.Executor(algorithm)
.execute() ;
List<DoubleSolution> population = algorithm.getResult() ;
long computingTime = algorithmRunner.getComputingTime() ;
JMetalLogger.logger.info("Total execution time: " + computingTime + "ms");
printFinalSolutionSet(population);
if (!referenceParetoFront.equals("")) {
printQualityIndicators(population, referenceParetoFront) ;
}
}
使用IDE运行算法
一旦配置了算法,就可以使用最喜欢的IDE来执行它们。例如,在使用IntellJ Idea的情况下,如果要运行NSGA-II,您可以选择runner类名并通过单击鼠标左键选择选项“Run’nsgaiRunner.main()”:
执行后,以下消息将打印到输出控制台中:
jul 27, 2015 4:21:59 PM org.uma.jmetal.runner.multiobjective.NSGAIIRunner main
INFORMACIÓN: Total execution time: 1147ms
jul 27, 2015 4:21:59 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Random seed: 1438006918503
jul 27, 2015 4:21:59 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Objectives values have been written to file FUN.tsv
jul 27, 2015 4:21:59 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Variables values have been written to file VAR.tsv
jul 27, 2015 4:22:00 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printQualityIndicators
INFORMACIÓN:
Hypervolume (N) : 0.6594334269577787
Hypervolume : 0.6594334269577787
Epsilon (N) : 0.012122558511198256
Epsilon : 0.012122558511198256
GD (N) : 2.054388435747992E-4
GD : 2.054388435747992E-4
IGD (N) : 1.8304524180524584E-4
IGD : 1.8304524180524584E-4
IGD+ (N) : 0.003808931172199927
IGD+ : 0.003808931172199927
Spread (N) : 0.34070732976112383
Spread : 0.34070732976112383
R2 (N) : 0.13179198315493879
R2 : 0.13179198315493879
Error ratio : 1.0
标有(N)
的结果表明,在计算质量指标之前,前沿已标准化。
使用命令行运行算法
如果计划从命令行运行jMetal算法,则必须遵循以下要求:
- 使用“mvn package”构建项目。这将为每个子项目(即,
jmetal core
、jmetal problem
、jmetal algorithm
和jmetal exec
)创建一个包含所有依赖项的jar文件。 - 指出这些jar文件的位置。你至少有两种方法。一个是设置“CLASSPATH”环境变量:
export CLASSPATH=jmetal-core/target/jmetal-core-5.6-jar-with-dependencies.jar:jmetal-problem/target/jmetal-problem-5.6-jar-with-dependencies.jar:jmetal-exec/target/jmetal-exec-5.6-jar-with-dependencies.jar:jmetal-problem/target/jmetal-problem-5.6-jar-with-dependencies.jar
或者可以这样执行算法(以执行NSGA-II为例):
java org.uma.jmetal.runner.multiobjective.NSGAIIRunner
- 另一种方法是使用
java
命令的-cp
或-classpath
选项指示这些jar文件的位置:
java -cp jmetal-exec/target/jmetal-exec-5.0-SNAPSHOT-jar-with-dependencies.jar:jmetal-core/target/jmetal-core-5.0-SNAPSHOT-jar-with-dependencies.jar:jmetal-problem/target/jmetal-problem-5.0-SNAPSHOT-jar-with-dependencies.jar:jmetal-algorithm/target/jmetal-algorithm-5.0-Beta-35-jar-with-dependencies.jar org.uma.jmetal.runner.multiobjective.NSGAIIRunner
本例使用默认参数执行NSGA-II。如果要解决给定的问题,必须将其类名作为参数提供。例如,要解决基准问题ZDT4
,命令如下:
java org.uma.jmetal.runner.multiobjective.NSGAIIRunner org.uma.jmetal.problem.multiobjective.zdt.ZDT4
输出为:
jul 27, 2015 6:48:27 PM org.uma.jmetal.runner.multiobjective.NSGAIIRunner main
INFORMACIÓN: Total execution time: 683ms
jul 27, 2015 6:48:27 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Random seed: 1438015706581
jul 27, 2015 6:48:27 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Objectives values have been written to file FUN.tsv
jul 27, 2015 6:48:27 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Variables values have been written to file VAR.tsv
如果问题具有已知的帕累托前沿(或帕累托前沿近似值),添加包含它的文件可以将质量评估指标应用于获得的前沿。这种情况下求解ZDT4的命令将是:
java org.uma.jmetal.runner.multiobjective.NSGAIIRunner org.uma.jmetal.problem.multiobjective.zdt.ZDT4 jmetal-problem/src/test/resources/pareto_fronts/ZDT4.pf
这种情况下将输出以下结果
jul 27, 2015 6:49:21 PM org.uma.jmetal.runner.multiobjective.NSGAIIRunner main
INFORMACIÓN: Total execution time: 598ms
jul 27, 2015 6:49:21 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Random seed: 1438015760471
jul 27, 2015 6:49:21 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Objectives values have been written to file FUN.tsv
jul 27, 2015 6:49:21 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printFinalSolutionSet
INFORMACIÓN: Variables values have been written to file VAR.tsv
jul 27, 2015 6:49:21 PM org.uma.jmetal.runner.AbstractAlgorithmRunner printQualityIndicators
INFORMACIÓN:
Hypervolume (N) : 0.6584874391103687
Hypervolume : 0.658491021119803
Epsilon (N) : 0.014508161683056214
Epsilon : 0.014508161681605389
GD (N) : 1.7281971372005978E-4
GD : 1.7281858245371445E-4
IGD (N) : 1.9833943989483466E-4
IGD : 1.9833851420211548E-4
IGD+ (N) : 0.00425088535021156
IGD+ : 0.004250860866635309
Spread (N) : 0.4449171015114183
Spread : 0.44491700055639544
R2 (N) : 0.13208551920620412
R2 : 0.13208472309027727
Error ratio : 1.0