java - 遗传算法-Java交叉

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

最佳答案

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

这会产生多种您可能没有想到的效果。如果将母亲和父亲拼接在一起,使得母亲的数量少于 10 对,那么最终会得到 10 对,而最后的只是新的对。如果 mother 有超过 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 类中创建一个 makeCopy 方法,该方法返回具有相同信息的 Pair。还有其他方法可以做到这一点。

关于java - 遗传算法-Java交叉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28803222/

相关文章:

java - JAX-RS 客户端线程是否安全

java - Collections.sort 有什么问题?

c# - 二维数组中的索引超出范围异常 (C#)

Java StringTokenizer 超出 .CSV 文件范围

java - binarySearch 方法产生 "ArrayIndexOutOfBounds"异常

java - 使用 JavascriptExecutor 检查页面源时出现空指针异常

java - 使用泛型将类类型从一个方法传递到另一个方法

java - 打印行 ArrayList

java - 数组列表中最长的数字序列

java - 无法在 Apache Commons Mail 上将套接字转换为 TLS