因为毕业设计做水库多目标调度相关,对多目标优化算法有需求,使用版本为 jMetal-master-5.4。
也是刚接触Java,一开始焦头烂额,特此做一下记录。
0. Maven镜像仓库配置
jMetal从5.0版本开始使用了maven依赖,使用IDEA导入maven项目时从中央仓库下载依赖慢的心慌。
可在maven安装目录下conf\settings.xml内添加国内镜像,问题解决。
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<mirrorOf>*</mirrorOf>
</mirror>
1. jMetal-master使用初探
对照源码中的实例,自己进行了尝试,大体上掌握了jMetal的基本使用方法。以NSGAII算法应用于ZDT1测试问题为例进行总结。
首先声明
Problem<DoubleSolution> problem;//问题
Algorithm<List<DoubleSolution>> algorithm;//算法
CrossoverOperator<DoubleSolution> crossover;//交叉算子
MutationOperator<DoubleSolution> mutation;//变异算子
SelectionOperator<List<DoubleSolution>, DoubleSolution> selection;//选择算子
定义优化问题
problem = new ZDT1();
进行参数设置
//配置SBX交叉算子
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>());
创建NSGAIIBuilder对象,调用build()方法构建算法
//设置进化次数为25000,种群规模为100
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();
printFinalSolutionSet(population);
结果集FUN.tsv和VAR.tsv存储在当前project目录下,FUN.tsv存储的是目标函数值,VAR.tsv存储的是变量值。
2. 结果集的处理
针对于ZDT1这一目标函数个数为2的问题,使用pandas和matplotlib对解集进行可视化处理。python第三方库安装的问题的解决,记录在上一篇博客。
首先导入
import pandas as pd
import matplotlib.pyplot as plt
对FUN.tsv中的数据进行读取
file_path = 'E:/Python/NSGAII_pycharm/FUN.tsv'
file = open(file_path)
data = []
for i in file.readlines():
data.append(i)
file.close()
此时可选择在控制台进行输出,观察数据的存储格式。仔细观察可以发现数据的存储格式为
'2.711890521173155E-10 1.0010893732314614 \n'
即两个函数值之间分隔符为空格' '
,但在最后的换行符之前也有一个空格' '
,这就给后面直接应用pd.csv_reader()
带来了一些问题。为了解决这个问题,直接将将尾部的空格去掉。
处理数据并存储到new_FUN.tsv
new_file_path = 'E:/Python/NSGAII_pycharm/new_FUN.tsv'
new_file = open(new_file_path, 'w')
new_file.write('fun1 fun2\n')
for row in data:
# 去掉每行数据尾部的空格
tmp = row.strip('\n').rstrip() + '\n'
new_file.write(tmp)
new_file.close()
最后,使用pandas将数据存入为数组并绘图
array_data = pd.read_csv(new_file_path, sep=' ')
plt.plot(array_data['fun1'], array_data['fun2'], 'ro')
plt.show()
得到的Pareto前沿如图