我使用的是IntegerChromosome,它是针对实际问题的编码。为了确定适合度,我必须将IntegerChromosome或更多的IntegerGene值解码为优化问题的实际基类型。因此,例如,IntegerGene值0表示具有值A的Class类型的实例,1表示具有值B的Class类型的实例,依此类推。因此,01233210将转换为ABCDDCBA。只有后者我才能评估。我在运行时在FitnessInput类中获取此信息。
因此,我需要通过FitnessInput来确定适应度函数。查看一个简单的example,我发现在示例中的eval()方法中,适应度的确定是在一个静态方法中进行的。有没有一个概念和相关的例子,如何将运行时对象传递给适应度的确定,而不是覆盖实现fitness()的类中的静态变量?
第二个问题与适应度确定问题有关。我发现了一些使用简单数据类型Integer、Double来确定适应度的示例。虽然这当然是合理的,但我希望将一个对象返回给用户,以获得最佳表型,其中包含用于确定其适合性的所有中间结果。我猜如果我的返回对象实现Comparable,这应该是可能的。我如何使用,例如,使用Function接口来实现它?
发布于 2020-12-14 16:17:01
您可能会看到Codec接口。此接口负责将问题域的对象转换为Genotype。如果我正确理解了您的问题,可能的编码可能如下所示:
static final List<String> OBJECTS = List.of("A", "B", "C", "D");
static final int LENGTH = 10;
static final Codec<List<String>, IntegerGene> CODEC = Codec.of(
// Create the Genotype the GA is working with.
Genotype.of(IntegerChromosome.of(0, OBJECTS.size() - 1, LENGTH)),
// Convert the Genotype back to your problem domain.
gt -> gt.chromosome().stream()
.map(IntegerGene::allele)
.map(OBJECTS::get)
.collect(Collectors.toList())
);
// Calculate the fitness function in terms of your problem domain.
static double fitness(final List<String> objects) {
return 0;
}
static final Engine<IntegerGene, Double> ENGINE = Engine
.builder(Main::fitness, CODEC)
.build();Codec创建一个由长度为10的Genotype组成的IntegerChromosome,并将其转换回您的问题域。
我不确定我是否正确理解了你的第二个问题。但如果您还想收集中间结果,则可以使用Stream::peek方法。
public static void main(final String[] args) {
final List<Phenotype<IntegerGene, Double>> intermediateResults = new ArrayList<>();
final var bestPhenotype = ENGINE.stream()
.limit(Limits.bySteadyFitness(25))
.peek(er -> intermediateResults.add(er.bestPhenotype()))
.collect(EvolutionResult.toBestPhenotype());
}https://stackoverflow.com/questions/65281775
复制相似问题