1

在jenetics中有几种可能性来设置终止限制EvolutionStream,请参阅文档

这些限制通常直接应用于stream,例如

Phenotype<IntegerGene,Double> result = engine.stream()
    .limit(Limits.bySteadyFitness(10))
    .collect(EvolutionResult.toBestPhenotype());

或者

Phenotype<IntegerGene,Double> result = engine.stream()
    .limit(Limits.byFixedGeneration(10))
    .collect(EvolutionResult.toBestPhenotype());

或结合使用,请参见示例

Phenotype<IntegerGene,Double> result = engine.stream()
    .limit(Limits.bySteadyFitness(10))
    .limit(Limits.byFixedGeneration(10))
    .collect(EvolutionResult.toBestPhenotype());

在我的优化问题中,我想让用户决定分配给问题的限制。我不知道预先设置的限制。它可能是多个限制。因此,我必须在运行时分配限制类型。

我试图EvolutionStream通过

EvolutionStream<IntegerGene, Double> evolutionStream = engine.stream();

并在 上分配限制evolutionStream

Stream<EvolutionResult<IntegerGene, Double>> limit = evolutionStream.limit(Limits.byFixedGeneration(10));

结果是一个Stream,它不知道EvolutionStream具体的限制方法。因此,如果定义了多个限制,我将无法应用它。试图投

evolutionStream = (EvolutionStream<IntegerGene, Double>)evolutionStream.limit(Limits.byFixedGeneration(10));

导致错误:

java.lang.ClassCastException: class java.util.stream.SliceOps$1 cannot be cast to class io.jenetics.engine.EvolutionStream (java.util.stream.SliceOps$1 is in module java.base of loader 'bootstrap'; io.jenetics.engine.EvolutionStream is in unnamed module of loader 'app')

那么,有没有办法在流构建器之外正确应用多个限制?

4

1 回答 1

1

EvolutionStream.limit(Predicate)方法确实返回一个EvolutionStream.

EvolutionStream<IntegerGene, Double> stream = engine.stream();
stream = stream
    .limit(Limits.byFixedGeneration(10))
    .limit(Limits.bySteadyFitness(5))
    .limit(Limits.byExecutionTime(Duration.ofMillis(100)));

因此,您给出的示例看起来不错,应该可以工作。但是该EvolutionStream.limit(Predicate)方法是唯一可以让您返回EvolutionStream.

另一种方法是初始化s 的方法从外部EvolutionStream获取s 。Predicate

@SafeVarargs
static EvolutionStream<IntegerGene, Double>
newStream(final Predicate<? super EvolutionResult<IntegerGene, Double>>... limits) {
    final Engine<IntegerGene, Double> engine = Engine
        .builder(a -> a.gene().allele().doubleValue(), IntegerChromosome.of(0, 100))
        .build();

    EvolutionStream<IntegerGene, Double> stream = engine.stream();
    for (var limit : limits) {
        stream = stream.limit(limit);
    }

    return stream;
}    
    
final var stream = newStream(
    Limits.byFixedGeneration(100),
    Limits.byExecutionTime(Duration.ofMillis(1000)),
    Limits.bySteadyFitness(10)
);
于 2020-12-07T14:17:04.507 回答