1

我使用的IntegerChromosome是实际问题的编码。为了确定适合度,我必须从IntegerChromosome或更多IntegerGene值解码为优化问题的实际基本类型。因此,例如,IntegerGene值 0 表示具有值的类型实例ClassA1 表示具有值的类型实例,Class依此B类推。因此,01233210 将转换为 ABCDDCBA。只有后者我可以评价。我在运行时在类中获取此信息FitnessInput

因此我需要传递FitnessInput适应度函数的确定。看一个简单的例子,我发现在eval()例子中的方法中,适应度的确定是在静态方法中进行的。是否有一个概念和相关示例如何将运行时对象传递给适应度的确定,而不是在fitness()实现的类中覆盖静态变量?


第二个问题与适应度确定问题有关。我发现了简单数据类型用于确定适合度的Integer示例。Double虽然这当然是合理的,但我想将一个对象返回给用户以获得最佳表型,其中包含确定其适合度的所有中间结果。我想如果我的返回对象实现了这应该是可能的Comparable。例如,我如何利用该Function界面?

4

1 回答 1

1

您可能会查看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创建Genotype由长度为 10的a 组成的 aIntegerChromosome并将其转换回您的问题域。

我不确定我是否正确理解了您的第二个问题。但是如果你也想收集中间结果,你可以使用该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());
}
于 2020-12-14T08:17:01.403 回答