Jenetics定制基因/染色体

时间:2016-07-05 06:27:20

标签: java genetic-algorithm genetic

我已经开始尝试使用Jenetics库,但是我在尝试制作一个非常简单的#34; custom&#34;一组基因/染色体。 我试图做的是创建一个自定义染色体,里面有不同(随机)数量的自定义基因。基因只是为了简单起见,只包含一个整数值。同样简单,基因的内容只能是0到9之间的数字,只有当Gene不包含数字9时,Gene才被认为是有效的(再次,简单,但我只想让它们自定义)< / p>

这是我的代码:

CustomGene:

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;
    }
}

CustomChromosome:

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)

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

非常感谢!

1 个答案:

答案 0 :(得分:0)

由图书馆here的创建者发布,答案是:

你违反了Chromosome.newInstance(ISeq)方法的合同。此方法必须返回新的染色体实例。修好后

@Override
public Chromosome<CustomGene> newInstance(ISeq<CustomGene> iSeq) {
    return new CustomChromosome(iSeq);
}