Jenetics:如何在每一步访问进化结果(或统计数据)?
Jenetics: how do I access evolution result (or statistics) at each step?
我正在研究基于 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”是 class 个属性。
您可以使用 EvolutionStatistics class 来达到这个目的。
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
方法中更新 class,您将获得一些额外的统计数据。
我正在研究基于 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”是 class 个属性。
您可以使用 EvolutionStatistics class 来达到这个目的。
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
方法中更新 class,您将获得一些额外的统计数据。