Operator
接口
启发式算法的基础是通过应用不同的算子,从现有的个体solution
中修改或生成新的个体solution
。例如,EAs使用交叉、变异和选择操算子修改解决方案。在jMetal中,任何改变或生成solution
(或solution
集合)的操作都会实现或扩展Operator
接口:
package org.uma.jmetal.operator;
/**
* Interface representing an operator
*
* @author Antonio J. Nebro <antonio@lcc.uma.es>
* @version 0.1
* @param <Source> Source Class of the object to be operated with
* @param <Result> Result Class of the result obtained after applying the operator
*/
public interface Operator<Source, Result> {
/**
* @param source The data to process
*/
public Result execute(Source source) ;
}
本接口中的泛型用于指示算子将被应用于Source
并且将结果以Result
类型返回
框架已经引入了一系列的算子,他们可以被分为四类
- 交叉算子:表示启发式算法中使用的复合或交叉运算符。下文实例中的算子分别可以模拟二进制(SBX)交叉以及实数和二进制编码的单点交叉。
- 变异算子:表示启发式算法中所使用的变异算子。包含实数编码的多项式变异以及二进制编码的位反转变异等
- 选择算子. 在许多启发式算法中,这种算子用于执行选择过程。选择算子的一个示例是二进制竞赛。
- 本地搜索算子. 此类用于表示本地搜索过程。它包含一种方法,用于咨询应用后执行了多少次评估。
下面就来叙述这些算子的接口和实现类
交叉算子
CrossoverOperator
接口可以作为 jMetal 5中交叉算子的代表:
package org.uma.jmetal.operator;
/**
* Interface representing crossover operators. They will receive a list of solutions and return
* another list of solutions
*
* @author Antonio J. Nebro <antonio@lcc.uma.es>
*
* @param <S> The class of the solutions
*/
public interface CrossoverOperator<S extends Solution<?>> extends Operator<List<S>,List<S>> {
}
这个接口简单地说明了交叉点有一个solution
对象的列表作为源,并返回另一个solution
对象的列表作为结果。让我们看一下这个接口的两个实现,一个用于实数类型,另一个用于二进制类型。
模拟二进制交叉(SBX)是许多多目标进化算法(如NSGA-II、SPEA2、SMS-EMOA、MOCell等)中的默认交叉算子。SBXCrossover
类的方案如下所示:
package org.uma.jmetal.operator.impl.crossover;
/**
* This class allows to apply a SBX crossover operator using two parent solutions (Double encoding).
* A {@link RepairDoubleSolution} object is used to decide the strategy to apply when a value is out
* of range.
*
* The implementation is based on the NSGA-II code available in
* <a href="http://www.iitk.ac.in/kangal/codes.shtml">http://www.iitk.ac.in/kangal/codes.shtml</a>
*
* @author Antonio J. Nebro <antonio@lcc.uma.es>
* @author Juan J. Durillo
*/
public class SBXCrossover implements CrossoverOperator<DoubleSolution> {
/** EPS defines the minimum difference allowed between real values */
private static final double EPS = 1.0e-14;
private double distributionIndex ;
private double crossoverProbability ;
private RepairDoubleSolution solutionRepair ;
private JMetalRandom randomGenerator ;
/** Constructor */
public SBXCrossover(double crossoverProbability, double distributionIndex) {
this (crossoverProbability, distributionIndex, new RepairDoubleSolutionAtBounds()) ;
}
/** Constructor */
public SBXCrossover(double crossoverProbability, double distributionIndex, RepairDoubleSolution solutionRepair) {
if (crossoverProbability < 0) {
throw new JMetalException("Crossover probability is negative: " + crossoverProbability) ;
} else if (distributionIndex < 0) {
throw new JMetalException("Distribution index is negative: " + distributionIndex);
}
this.crossoverProbability = crossoverProbability ;
this.distributionIndex = distributionIndex ;
this.solutionRepair = solutionRepair ;
randomGenerator = JMetalRandom.getInstance() ;
}
/** Execute() method */
@Override
public List<DoubleSolution> execute(List<DoubleSolution> solutions) {
if (null == solutions) {
throw new JMetalException("Null parameter") ;
} else if (solutions.size() != 2) {
throw new JMetalException("There must be two parents instead of " + solutions.size()) ;
}
return doCrossover(crossoverProbability, solutions.get(0), solutions.get(1)) ;
}
...
未完待续????