遗传算法 - Java 交叉

Genetic Algorithm - Java Crossover

使用我的 GA 交叉方法,我在将母亲的后半部分连接到父亲的前半部分时不断收到 ArrayOutOfBounds 异常。 ArrayList 的大小都相同。为什么我妈妈一直试图访问我的对象列表中的第 10 个元素? MyPair 是一个具有随机方向和随机步数的对象。

我们目前正在我的 A.I 中学习这个主题。 class,所以我还不是 GA 方面的专家。欢迎对我的交叉算法进行任何其他评论。

public static class Chromosome{

        public ArrayList<MyPair> pairs;
        private double x, y;
        public double cost;

        public Chromosome(){
            this.pairs = new ArrayList<MyPair>();
            this.x = 100.0; this.y = 100.0;

//          not sure if I should do this or not
            for(int numPairs = 0; numPairs < 10; numPairs++)
                this.addToChromosome();
        }

        public void addToChromosome(){
            MyPair myPair = new MyPair();
            this.pairs.add(myPair);
        }

        public ArrayList<MyPair> getPairsList(){
            return this.pairs;
        }

        public Chromosome crossOver(Chromosome father, Chromosome mother){

            Chromosome replacement = new Chromosome();
            int pos1 = r.nextInt(father.getPairsList().size());

            while(pos1 >= 10)
                pos1 = r.nextInt(father.getPairsList().size());

            for(int i = 0; i < pos1; i++){
                MyPair tempPair = father.getPairsList().get(i);
                replacement.getPairsList().set(i, tempPair);
            }           

            for(int i = pos1; i < mother.getPairsList().size() - 1; i++){
                MyPair tempPair = mother.getPairsList().get(i);

                // ArrayList keeps trying to set out of bounds here
                replacement.getPairsList().set(i, tempPair);
            }

            return replacement;
        }

问题似乎是您构建的染色体包括 replacement 有 10 对,然后您将元素设置在位置 i,此时 i 可能为 10 或更大。

这有多种您可能没有预料到的效果。如果你将父母拼接在一起,使得母亲的数量少于 10 对,那么你最终还是会得到 10 对,而最后一对只是新的一对。如果母亲有超过 10 对,您将尝试设置不存在的 arraylist 元素,因此您会遇到异常。您可能还没有遇到的另一件事是您没有复制对中的信息,您复制了对的引用。这意味着如果您稍后通过更改对中的信息而不是替换对来给母亲突变,它将影响 child 和 child 的后代,这可能不是您想要的.

相反,从一个空的对列表开始染色体,然后添加来自父亲的对的副本,然后添加来自母亲的对的副本。

未经测试的代码:

public Chromosome crossOver(Chromosome father, Chromosome mother){

    Chromosome replacement = new Chromosome();
    replacement.getPairsList().clear(); // get rid of the original 10 pairs

    int pos1 = r.nextInt(father.getPairsList().size());

    while(pos1 >= 10)
        pos1 = r.nextInt(father.getPairsList().size());

        for(int i = 0; i < pos1; i++){
            MyPair tempPair = father.getPairsList().get(i);
            replacement.getPairsList().add(tempPair.makeCopy()); // appended copy instead of setting ith
        }           

        for(int i = pos1; i < mother.getPairsList().size() - 1; i++){
            MyPair tempPair = mother.getPairsList().get(i);

            // ArrayList keeps trying to set out of bounds here
            replacement.getPairsList().add(tempPair.makeCopy()); // append copy instead of setting ith
        }

        return replacement;
    }

您必须在您的 Pair class 中创建一个 makeCopy 方法,returns 具有相同信息的 Pair。还有其他方法可以做到这一点。