#java-stream #jenetics
#java-stream #jenetics
Вопрос:
В 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));
Результатом является поток, который не знает 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')
Итак, есть ли способ правильно применить несколько ограничений вне stream builder?
Ответ №1:
EvolutionStream.limit(Predicate)
Метод действительно возвращает an 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
.
Альтернативой может быть то, что ваш метод, который инициализирует EvolutionStream
, принимает Predicate
s извне.
@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)
);
Комментарии:
1. Спасибо. Как вы сказали, это сработало. Некоторая очистка кода сделала свое дело