1

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

我们目前正在我的 AI 课上学习这个主题,所以我还不是 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;
        }
4

1 回答 1

1

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

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

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

未经测试的代码:

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 类中创建一个 makeCopy 方法,该方法返回具有相同信息的 Pair。还有其他方法可以做到这一点。

于 2015-03-02T05:50:13.253 回答