【jmetal】多目标进化算法框架使用

JMetal四部分介绍:

  • core包:要在项目中使用JMetal,您至少需要引入该包,它提供了用于实现JMetal算法的各种组件;
  • algorithm包:JMetal附带了已经实现的各种算法,您可以通过添加该包来获得这些算法;
  • problem包:如果您对自己的算法更感兴趣,您可以添加该包来获得要解决的各种问题;
  • exec包:该包附带了各种实用程序,允许您运行和评估不同的组合来。

这里,提供一个JMetal的一个官方API地址:https://jmetal.github.io/jMetal/apidocs/index.html。

使用时,可能会报如下错误

java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream。

解决方案:从以下的common下载地址,下载common.jar文件。

利用Jmetal求解实际问题时,最简单的方法是利用algorithm包中已经定义的算法,因此,这里我们只需要定义好我们自己的problem,就可以在主方法里面调用已经存在的algorithm求解我们的problem了。

这里,给出整个的jar包地址:jmetal.jar、jmetal-src.jar、common.jar,另外还包括官方的文档,具体如下所示。

【jmetal】多目标进化算法框架使用_第1张图片

1. 问题介绍

我们知道,JMetal是一个多目标进化算法的框架,但是,为了简化问题,这里笔者采用一个单目标优化的例子向大家介绍一下该框架的使用方法。

如题:求函数y=x*2+1/x的最小值,决策变量x的取值为0~1。

需要注意的是,在JMetal或者其他多目标进化算法中,常常默认优化的目标是求最小值,而非求最大值。若需要求最大值,只需要目标函数取反即可。

2. 求解过程

我们知道,当我们决定使用智能进化算法求解实际问题时,第一步要做的就是设计解的编码。然而,解的编码表示很大程度上取决于问题。 

在上面这个问题中,很明显,只有一个决策变量x,同时也只有一个优化目标y。因此,编码也就确定了,我们仅仅需要一个长度为1的数组即可。在决策变量多于1时,这个数组的长度就不是1了。总之,数组的长度等于决策变量的总个数。

2.1 导入jar包

导入jmetal的jar包,可以从本站前面的链接下载,或者按照【jmetal 】java多目标进化算法框架环境搭建,自己生成。

【jmetal】多目标进化算法框架使用_第2张图片

2.2 问题定义

  1. 首先,我们定义一个自定义问题CustomProblem,它继承自AbstractDoubleProblem。注意,我标记的Double,是因为我们求解时决策变量取的是浮点型的数值,如果是整数值呢?当然需要AbstractIntegerProblem啦,详细的可以参考上面的API介绍;
  2. 接着,设置决策变量的取值范围;
  3. 最后,实现evaluate方法,计算解的适应度值。
package com.jmetal;

import java.util.ArrayList;
import java.util.List;

import org.uma.jmetal.problem.impl.AbstractDoubleProblem;
import org.uma.jmetal.solution.DoubleSolution;

public class CustomProblem extends AbstractDoubleProblem {

	private static final long serialVersionUID = 1L;

	/**
	 * Creates a new instance of problem.
	 */
	public CustomProblem() {
		setNumberOfVariables(1);// 决策变量个数
		setNumberOfObjectives(1);// 目标函数个数
		setName("test");// 问题名

		// 设置定义域
		List lowerLimit = new ArrayList<>(getNumberOfVariables());
		List upperLimit = new ArrayList<>(getNumberOfVariables());
		for (int i = 0; i < getNumberOfVariables(); i++) {
			lowerLimit.add(0.0);
			upperLimit.add(1.0);
		}
		setLowerLimit(lowerLimit);
		setUpperLimit(upperLimit);
	}

	/**
	 * 计算解的适应度,Algorithm.evlataionPopulation()会调用这个方法
	 */
	@Override
	public void evaluate(DoubleSolution solution) {
		// 获取决策变量值
		double x = solution.getVariableValue(0);
		// 计算适应度
		double y = x * 2 + 1 / x;
		// 设置解的适应度值
		solution.setObjective(0, y);
	}
}

2.3 主函数实现 

这里,我们采用NSGAII进行问题求解,具体步骤如下:

  1. 新建问题对象;
  2. 算法参数设置,我们这里利用的包括种群规模、交叉算子、变异算子和选择算子的选择;
  3. 组件注册于运行;
  4. 获取结果并输出。

具体实现如下所示。

package com.jmetal;

import java.util.List;

import org.uma.jmetal.algorithm.Algorithm;
import org.uma.jmetal.algorithm.multiobjective.nsgaii.NSGAIIBuilder;
import org.uma.jmetal.operator.CrossoverOperator;
import org.uma.jmetal.operator.MutationOperator;
import org.uma.jmetal.operator.SelectionOperator;
import org.uma.jmetal.operator.impl.crossover.SBXCrossover;
import org.uma.jmetal.operator.impl.mutation.PolynomialMutation;
import org.uma.jmetal.operator.impl.selection.BinaryTournamentSelection;
import org.uma.jmetal.problem.Problem;
import org.uma.jmetal.solution.DoubleSolution;
import org.uma.jmetal.util.AlgorithmRunner;
import org.uma.jmetal.util.JMetalLogger;
import org.uma.jmetal.util.comparator.RankingAndCrowdingDistanceComparator;

public class Main {
	public static void main(String[] args) {
		Problem problem;
		Algorithm> algorithm;
		CrossoverOperator crossover;
		MutationOperator mutation;
		SelectionOperator, DoubleSolution> selection;
		String referenceParetoFront = "";// 真实PF,用于计算指标值,只在多目标中有用。

		// 定义优化问题
		problem = new CustomProblem();

		// 种群规模
		int popSize = 50;
		// 配置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(
				new RankingAndCrowdingDistanceComparator());

		// 将组件注册到algorithm
		algorithm = new NSGAIIBuilder(problem, crossover, mutation, popSize)
				.setSelectionOperator(selection).setMaxEvaluations(25000).build();
		// 用AlgorithmRunner运行算法
		AlgorithmRunner algorithmRunner = new AlgorithmRunner.Executor((Algorithm) algorithm).execute();

		// 获取结果集
		List population = algorithm.getResult();
		// 输出结果
		long computingTime = algorithmRunner.getComputingTime();
		JMetalLogger.logger.info("Total execution time: " + computingTime + "ms");
		printFinalSolutionSet(population);
		if (!referenceParetoFront.equals("")) {
			printQualityIndicators(population, referenceParetoFront);
		}
	}

	/**
	 * 输出最后的种群中的各个解的适应度
	 * 
	 * @param population
	 */
	private static void printFinalSolutionSet(List population) {
		for (DoubleSolution p : population) {
			System.out.println(p.getObjectives()[0]);
		}
	}

	/**
	 * 输出指标值
	 * 
	 * @param population
	 * @param referenceParetoFront
	 */
	private static void printQualityIndicators(List population, String referenceParetoFront) {
		// TODO Auto-generated method stub

	}
}

求解结果:

 

你可能感兴趣的:(【jmetal】多目标进化算法框架使用)