我如何在 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 来计算统计数据。