我使用的是IntegerChromosome
,它是针对实际问题的编码。为了确定适合度,我必须从IntegerChromosome
或更多的IntegerGene
值解码为优化问题的实际基本类型。因此,例如,IntegerGene
值0表示值为A
的类型为Class
的实例,1表示值为B
的类型为Class
的实例,依此类推。因此,01233210将转换为ABCDCBA。只有后者我可以评估。我在运行时在类FitnessInput
中获得这些信息。
因此,我需要通过FitnessInput
来确定适应度函数。看一个简单的例子,我发现在例子中的eval()
方法中,适合度的确定是在静态方法中进行的。在实现fitness()
的类中,是否存在如何将运行时对象传递给适合度的确定而不是覆盖静态变量的概念和相关示例?
第二个问题与适应度确定问题有关。我发现了使用简单数据类型Integer
、Double
来确定适合度的示例。虽然这当然是合理的,但我想将一个对象返回给用户以获得最佳表型,其中包含用于确定其适合性的所有中间结果。我想如果我的返回对象实现Comparable
,这应该是可能的。例如,我如何使用Function
接口?
您可能会看到编解码器接口。该接口负责将问题域的对象转换为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的IntegerChromosome
组成的Genotype
,并将其转换回您的问题域。
我不确定我是否正确理解了你的第二个问题。但是,如果您也想收集中间结果,可以使用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());
}