我如何在 MOEA Framework 中获取实时统计数据?
How I get real time statistics in MOEA Framework?
我知道有 Instrumenter
class,但是此方法在 完成后 输出数据。我想获得(接近)实时数据,例如演示中的符号回归。
看它的代码,好像要用step
的方法,尽量模仿Executor
中的runSingleSeed
。有没有更好的办法?其他一些 class 类似于 Instrumenter
但异步。我真的无法在网上找到类似的东西。
只需围绕循环构建一个包装器(类似于下一个)并使其成为观察者模式中的主题。
import java.util.Properties;
import java.util.Arrays;
import java.text.DecimalFormat;
import org.moeaframework.core.Algorithm;
import org.moeaframework.core.Solution;
import org.moeaframework.core.Problem;
import org.moeaframework.core.Population;
import org.moeaframework.core.NondominatedPopulation;
import org.moeaframework.core.variable.EncodingUtils;
import org.moeaframework.core.spi.AlgorithmFactory;
import org.moeaframework.problem.misc.Kursawe;
public class Main{
public static void main(String[] args){
String algorithmName = "NSGAII";
Properties properties = new Properties();
properties.setProperty("populationSize", "100"); // to change properties
Problem problem = new Kursawe();
Algorithm algorithm = AlgorithmFactory.getInstance()
.getAlgorithm(algorithmName, properties, problem);
int maxGenerations = 100;
int generation = 0;
while( generation < maxGenerations ){
if( generation % 10 == 1 ){
System.out.println("Generation " + generation);
NondominatedPopulation paretoFront = algorithm.getResult();
// metrics
System.out.print("One of the pareto front: ");
System.out.println(toString(paretoFront.get(0)));
}
algorithm.step();
generation++;
}
algorithm.terminate();
System.out.println("Parento Front:");
for(Solution solution: algorithm.getResult()){
System.out.println(toString(solution));
}
export(algorithm.getResult());
}
private static String toString(Solution solution){
StringBuilder out = new StringBuilder();
double[] variables = EncodingUtils.getReal(solution);
double[] objectives = solution.getObjectives();
out.append("f");
out.append(doubleArrayToString(variables));
out.append(" = ");
out.append(doubleArrayToString(objectives));
return out.toString();
}
private static String doubleArrayToString(double[] array){
DecimalFormat format = new DecimalFormat("+#,##0.00;-#");
StringBuilder out = new StringBuilder();
out.append("[");
for(int i = 0; i < array.length-1; i++){
out.append(format.format(array[i]));
out.append(", ");
}
out.append(format.format(array[array.length-1]));
out.append("]");
return out.toString();
}
private static void export(Population population){
System.out.println();
for(Solution solution: population){
double[] objectives = solution.getObjectives();
System.out.println(String.format("%.3f,%.3f", objectives[0], objectives[1]));
}
}
}
如果您使用多线程,黑箭头指示的另一种选择是扩展 AlgorithmFactory。例如:
public class MyAlgorithmFactory extends AlgorithmFactory {
private static Algorithm algorithm;
public Algorithm getGeneratedAlgorithm() {
return this.algorithm;
}
@Override
public Algorithm getAlgorithm(String name, Properties properties, Problem problem){
this.algorithm = super.getAlgorithm(name, properties, problem);
return algorithm;
}
}
然后你在你的执行器上使用这个工厂,例如:
MyAlgorithmFactory af = new MyAlgorithmFactory();
Executor executor = new Executor()
.usingAlgorithmFactory(af)
.withAlgorithm("NSGAII") //
.withProblem(yourProblemHere) //
.withMaxEvaluations(10000);
在此之后,您可以在单独的线程上启动执行器,并调用 af.getGeneratedAlgorithm() 以获取由执行器初始化的算法实例。从这个算法你可以得到,当执行者仍然是 运行 时,实际的 NondominatedPopulation 来计算统计数据。
我知道有 Instrumenter
class,但是此方法在 完成后 输出数据。我想获得(接近)实时数据,例如演示中的符号回归。
看它的代码,好像要用step
的方法,尽量模仿Executor
中的runSingleSeed
。有没有更好的办法?其他一些 class 类似于 Instrumenter
但异步。我真的无法在网上找到类似的东西。
只需围绕循环构建一个包装器(类似于下一个)并使其成为观察者模式中的主题。
import java.util.Properties;
import java.util.Arrays;
import java.text.DecimalFormat;
import org.moeaframework.core.Algorithm;
import org.moeaframework.core.Solution;
import org.moeaframework.core.Problem;
import org.moeaframework.core.Population;
import org.moeaframework.core.NondominatedPopulation;
import org.moeaframework.core.variable.EncodingUtils;
import org.moeaframework.core.spi.AlgorithmFactory;
import org.moeaframework.problem.misc.Kursawe;
public class Main{
public static void main(String[] args){
String algorithmName = "NSGAII";
Properties properties = new Properties();
properties.setProperty("populationSize", "100"); // to change properties
Problem problem = new Kursawe();
Algorithm algorithm = AlgorithmFactory.getInstance()
.getAlgorithm(algorithmName, properties, problem);
int maxGenerations = 100;
int generation = 0;
while( generation < maxGenerations ){
if( generation % 10 == 1 ){
System.out.println("Generation " + generation);
NondominatedPopulation paretoFront = algorithm.getResult();
// metrics
System.out.print("One of the pareto front: ");
System.out.println(toString(paretoFront.get(0)));
}
algorithm.step();
generation++;
}
algorithm.terminate();
System.out.println("Parento Front:");
for(Solution solution: algorithm.getResult()){
System.out.println(toString(solution));
}
export(algorithm.getResult());
}
private static String toString(Solution solution){
StringBuilder out = new StringBuilder();
double[] variables = EncodingUtils.getReal(solution);
double[] objectives = solution.getObjectives();
out.append("f");
out.append(doubleArrayToString(variables));
out.append(" = ");
out.append(doubleArrayToString(objectives));
return out.toString();
}
private static String doubleArrayToString(double[] array){
DecimalFormat format = new DecimalFormat("+#,##0.00;-#");
StringBuilder out = new StringBuilder();
out.append("[");
for(int i = 0; i < array.length-1; i++){
out.append(format.format(array[i]));
out.append(", ");
}
out.append(format.format(array[array.length-1]));
out.append("]");
return out.toString();
}
private static void export(Population population){
System.out.println();
for(Solution solution: population){
double[] objectives = solution.getObjectives();
System.out.println(String.format("%.3f,%.3f", objectives[0], objectives[1]));
}
}
}
如果您使用多线程,黑箭头指示的另一种选择是扩展 AlgorithmFactory。例如:
public class MyAlgorithmFactory extends AlgorithmFactory {
private static Algorithm algorithm;
public Algorithm getGeneratedAlgorithm() {
return this.algorithm;
}
@Override
public Algorithm getAlgorithm(String name, Properties properties, Problem problem){
this.algorithm = super.getAlgorithm(name, properties, problem);
return algorithm;
}
}
然后你在你的执行器上使用这个工厂,例如:
MyAlgorithmFactory af = new MyAlgorithmFactory();
Executor executor = new Executor()
.usingAlgorithmFactory(af)
.withAlgorithm("NSGAII") //
.withProblem(yourProblemHere) //
.withMaxEvaluations(10000);
在此之后,您可以在单独的线程上启动执行器,并调用 af.getGeneratedAlgorithm() 以获取由执行器初始化的算法实例。从这个算法你可以得到,当执行者仍然是 运行 时,实际的 NondominatedPopulation 来计算统计数据。