java - Jenetics 定制基因/染色体

标签 java genetic-algorithm genetic jenetics

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

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

非常感谢!

最佳答案

由库的创建者发布here ,答案是:

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

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

关于java - Jenetics 定制基因/染色体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38196545/

相关文章:

java - 如何在一个 bndtools 工作区中使用多个 git 存储库

java - 如何使用 avro 和 kafka 发送对象列表

python - 如何更改字符串中的字母,知道它在 Python 中的位置?

c - 遗传算法实现中的奇怪事件

java - 在 JSP 中上传文件 - 如何更改上传文件的默认路径

algorithm - 什么是遗传算法/遗传编程解决方案的好例子?

r - 优化/向量化 R 中从输入向量的范围生成随机数的循环?

algorithm - 如何使用遗传算法找到位于多边形边界内的最大圆?

algorithm - 特定遗传算法代价函数

java - java中的排序方法