遗传算法 - Java Crossover

时间:2015-03-02 05:30:23

标签: java arraylist indexoutofboundsexception genetic-algorithm crossover

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

我们目前正在A.I.中学习这个主题。上课,所以我还不是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;
        }

1 个答案:

答案 0 :(得分:1)

问题似乎是你正在构建染色体,包括replacement有10对,然后你将元素设置在位置i,当我可能是10或更大。

这有多种你可能没想过的效果。如果你把母亲和父亲拼接在一起,使母亲少于10对,你最终会得到10对,最后一对只是新对。如果母亲有超过10对,你试图设置不存在的arraylist的元素,因此你得到一个例外。您可能还没有遇到的另一件事是您没有复制对中的信息,您复制了对的引用。这意味着如果你以后通过改变一对中的信息而不是替换一对来给母亲一个突变,它将影响孩子和孩子的后代,这可能不是你想要的。

相反,用空列表对开始染色体,然后从父亲那里添加对的副本,然后从母亲那里添加对的副本。

未经测试的代码:

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。还有其他方法可以做到这一点。