【问题标题】:Jenetics: how do I access evolution result (or statistics) at each step?Jenetics:我如何在每一步访问进化结果(或统计数据)?
【发布时间】:2018-08-31 20:21:42
【问题描述】:

我正在开发基于 Jenetics 框架 (link to jenetics.io) 的优化引擎。我有一个进化引擎定义如下:

final Thread engineStream = new Thread(() -> {
final MinMax<EvolutionResult<DoubleGene, Double>> best = MinMax.of();

_scannerEngine.stream()
    .limit(byPopulationConvergence(convergenceCriterion))
    .limit(result -> !Thread.currentThread().isInterrupted())                              
    .limit(maxGenerations)
    .peek(best).forEach(evolutionResult -> {
        waiting();
        if (callback != null) {
            callback.accept(evolutionResult, best.getMax());
        }
        final String generationCounter = String.valueOf(evolutionResult.getGeneration());
       _callingInstance.doOnAlgorithmCallback(new String("****** finished generation: " + generationCounter + " ****"));
    });
}

engineStream.start();

目前,我正在一个进化周期(通过人口的一次迭代)结束时通过

向我的 UI 推送一条消息
peek(best).forEach(
    ...
    _callingInstance.doOnAlgorithmCallback(...)
)

我想做的是推动进化的当前状态(理想情况下是一些包含当前适应度平均值、最小值、最大值等的统计数据)在执行每个适应度步骤之后,所以用户可以看到优化过程的当前状态。

有什么想法吗?


基于 Franz Wilhelmstötter 的建议的最终实施:

final Thread engineStream = new Thread(() -> {
    final MinMax<EvolutionResult<DoubleGene, Double>> best = MinMax.of();

    try {
        _scannerEngine.stream() //
        // stop stream if fitness average across the population is smaller than % of best fitness
        .limit(byFitnessConvergence(5, 20, convergence%)) //
        .limit(interrupted -> !Thread.currentThread().isInterrupted()) //
        .limit(_geneticScanParameters.getMaxGenerationsLimit()) // maximum number of generations
        .peek(best) //
        .peek(_statistics) //
        .forEach(evolutionResult -> {
            waiting();
            if (callback != null) {
                MessageLogger.logError(getClass(), best.getMax().toString());
                if (_geneticScanParameters.getOptimizationStrategy() == Optimize.MAXIMUM) {
                    callback.accept(evolutionResult, best.getMax());
                } else if (_geneticScanParameters.getOptimizationStrategy() == Optimize.MINIMUM) {
                    callback.accept(evolutionResult, best.getMin());
                }
            }
            MessageLogger.log(getClass(), _statistics.toString());
            final String generationCounter = String.valueOf(evolutionResult.getGeneration());
            _callingInstance.doOnAlgorithmCallback(new String("****** finished generation: " + generationCounter + " ****"));
        });

        MessageLogger.log(getClass(), "\n" + _statistics.toString());
    } catch (final Exception ex) {
    MessageLogger.logError(getClass(), Thread.currentThread(), ex);
    }
    _callingInstance.doOnAlgorithmFinished();
});
engineStream.start();
_engineStream = engineStream;

请注意,我使用“_variable”是类属性的约定。

【问题讨论】:

    标签: java frameworks genetic-algorithm genetic-programming jenetics


    【解决方案1】:

    您可以为此目的使用EvolutionStatistics 类。

    final Engine<DoubleGene, Double> engine = ...
    final EvolutionStatistics<Double, DoubleMomentStatistics> statistics =
        EvolutionStatistics.ofNumber();
    
    final Phenotype<DoubleGene, Double> result = engine.stream()
        .limit(bySteadyFitness(7))
        .limit(100)
        .peek(statistics)
        .collect(toBestPhenotype());
    
    System.println(statistics);
    

    如果您在peek 方法中更新类,您将获得一些额外的统计信息。

    【讨论】:

    • 您好,Franz,感谢您的帮助,但这不是我想要的。您提供的代码片段在优化的结束处提供了进化统计信息。我想监控每一步的过程,最好是在个人的每一个价值观设置。也许我应该提到我运行引擎单线程,每次调用 ftness 函数之间有几秒钟。
    • 抱歉,我的意思是你可以对EvolutionStatisticsMinMax 对象做同样的事情:在peek 方法中更新它并在Stream.forEach 中调用doOnAlgorithmCallback 方法.
    猜你喜欢
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2012-09-28
    • 2019-11-28
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多