3

我已经开始尝试使用 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)

我们可以清楚地看到具有最大适应度函数的基因型与所选基因型之间的差异。为什么?我知道我做错了什么,这可能是一个愚蠢的错误,但我似乎真的无法理解我做错了什么。你能帮帮我吗?

非常感谢!

4

1 回答 1

1

正如图书馆的创建者在这里发布的那样,答案是:

您违反了 Chromosome.newInstance(ISeq) 方法的合同。此方法必须返回一个新的染色体实例。修复此问题后

@Override
public Chromosome<CustomGene> newInstance(ISeq<CustomGene> iSeq) {
    return new CustomChromosome(iSeq);
}
于 2016-07-05T07:49:46.013 回答