我如何在MOEA框架中获得实时统计数据?

时间:2017-11-02 04:40:19

标签: asynchronous real-time evolutionary-algorithm moea-framework

我知道有Instrumenter类,但是此方法会在运行结束后输出数据。我想得到(接近)实时数据,比如演示中的符号回归。 看看它的代码,似乎我需要使用step方法并尝试模仿runSingleSeed中的Executor。有没有更好的办法?其他一些类如Instrumenter但是异步的。我无法在网上找到类似的东西。

2 个答案:

答案 0 :(得分:0)

只需在循环周围构建一个包装器(类似于下一个)并使其成为观察者模式中的主题。

observer pattern diagram

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]));
    }
    }
}

pareto front

答案 1 :(得分:0)

如果您使用的是多线程,则黑箭头指示的另一种选择是扩展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;
     }
 }

然后您在执行器上使用此Factory,例如:

    MyAlgorithmFactory af = new MyAlgorithmFactory();

    Executor executor = new Executor()
            .usingAlgorithmFactory(af)
            .withAlgorithm("NSGAII") //
            .withProblem(yourProblemHere) //
            .withMaxEvaluations(10000);

此后,您可以在单独的线程上启动Executor,并调用af.getGeneratedAlgorithm()以获取由Executor初始化的Algorithm实例。通过该算法,您可以在执行器仍运行时获得实际的NondominatedPopulation来计算统计数据。