我已经开始尝试使用 Jenetics 库,但是在尝试制作一组非常简单的“自定义”基因/染色体时遇到了一些问题。我试图做的是创建一个自定义染色体,其中包含不同(随机)数量的自定义基因。为了简单起见,基因只包含一个整数值。出于同样的简单性,基因的内容只能是从 0 到 9 范围内的数字,并且只有不包含数字 9 的基因才被认为是有效的(再次,迟钝的简单,但我只是想让它们自定义)
这是我的代码:
自定义基因:
public class CustomGene implements Gene<Integer, CustomGene> {
private Integer value;
private CustomGene(Integer value) {
this.value = value;
}
public static CustomGene of(Integer value) {
return new CustomGene(value);
}
public static ISeq<CustomGene> seq(Integer min, Integer max, int length) {
Random r = RandomRegistry.getRandom();
return MSeq.<CustomGene>ofLength(length).fill(() ->
new CustomGene(random.nextInt(r, min, max))
).toISeq();
}
@Override
public Integer getAllele() {
return value;
}
@Override
public CustomGene newInstance() {
final Random random = RandomRegistry.getRandom();
return new CustomGene(Math.abs(random.nextInt(9)));
}
@Override
public CustomGene newInstance(Integer integer) {
return new CustomGene(integer);
}
@Override
public boolean isValid() {
return value != 9;
}
}
自定义染色体:
import org.jenetics.Chromosome;
import org.jenetics.util.ISeq;
import org.jenetics.util.RandomRegistry;
import java.util.Iterator;
import java.util.Random;
public class CustomChromosome implements Chromosome<CustomGene> {
private ISeq<CustomGene> iSeq;
private final int length;
public CustomChromosome(ISeq<CustomGene> genes) {
this.iSeq = genes;
this.length = iSeq.length();
}
public static CustomChromosome of(ISeq<CustomGene> genes) {
return new CustomChromosome(genes);
}
@Override
public Chromosome<CustomGene> newInstance(ISeq<CustomGene> iSeq) {
this.iSeq = iSeq;
return this;
}
@Override
public CustomGene getGene(int i) {
return iSeq.get(i);
}
@Override
public int length() {
return iSeq.length();
}
@Override
public ISeq<CustomGene> toSeq() {
return iSeq;
}
@Override
public Chromosome<CustomGene> newInstance() {
final Random random = RandomRegistry.getRandom();
ISeq<CustomGene> genes = ISeq.empty();
for (int i = 0; i < length; i++) {
genes = genes.append(CustomGene.of(Math.abs(random.nextInt(9))));
}
return new CustomChromosome(genes);
}
@Override
public Iterator<CustomGene> iterator() {
return iSeq.iterator();
}
@Override
public boolean isValid() {
return iSeq.stream().allMatch(CustomGene::isValid);
}
}
主要的:
import org.jenetics.Genotype;
import org.jenetics.Optimize;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionResult;
import org.jenetics.util.Factory;
import org.jenetics.util.RandomRegistry;
import java.util.Random;
public class Main {
private static int maxSum = - 100;
private static Integer eval(Genotype<CustomGene> gt) {
final int sum = gt.getChromosome().stream().mapToInt(CustomGene::getAllele).sum();
if(sum > maxSum)
maxSum = sum;
return sum;
}
public static void main(String[] args) {
final Random random = RandomRegistry.getRandom();
Factory<Genotype<CustomGene>> g =
Genotype.of(CustomChromosome.of(CustomGene.seq(0, 9, Math.abs(random.nextInt(9)) + 1)));
Engine<CustomGene, Integer> engine = Engine
.builder(Main::eval, g)
.optimize(Optimize.MAXIMUM)
.populationSize(100)
.build();
Genotype<CustomGene> result = engine.stream().limit(10000)
.collect(EvolutionResult.toBestGenotype());
System.out.println(eval(result));
result.getChromosome().stream().forEach(i -> {
System.out.print(i.getAllele() + " ");
});
System.out.println();
System.out.println(maxSum);
}
}
我不明白为什么我会得到这个输出:
13 (evaluated result)
1 8 0 4 (all the alleles form the genes of the chosen chromosome)
32 (the actual maximum fitness found)
我们可以清楚地看到具有最大适应度函数的基因型与所选基因型之间的差异。为什么?我知道我做错了什么,这可能是一个愚蠢的错误,但我似乎真的无法理解我做错了什么。你能帮帮我吗?
非常感谢!