我正在制作一个java程序,使用遗传算法进行多序列比对。起初,我遇到了JavaHeap错误,因为我创建了太多实例。所以我尝试通过使用list的clear()方法重用对象来修复它。但是,当我使用clear()时,它会影响另一个变量变为null。这是我的代码片段:
private void crossover() throws Exception {
Collections.shuffle(p);
p1 = p.pop();
p2 = p.pop();
System.out.println("CROSSOVER antara " + p1 + " dan " + p2);
p.add(p1);
p.add(p2);
Collections.shuffle(cutPoint);
cp = cutPoint.pop();
cutPoint.add(cp);
k1 = pop.get(getPOP(p1)).getKromosom();
k2 = pop.get(getPOP(p2)).getKromosom();
System.out.println("k1 [" + k1.size() + "]" + k1.toString()); //PRINT1
System.out.println("k2 [" + k2.size() + "]" + k2.toString()); //PRINT1
c1.clear();
c2.clear();
c1a.clear();
c2a.clear();
c1b.clear();
c2b.clear();
int maxLength = pop.get(getPOP(p1)).maxLength;
int kromosomSize = k1.size();
int point = -1;
for (int i = 0; i < kromosomSize; i++) {
System.out.println("k1 [" + k1.size() + "]" + k1.toString()); //PRINT2
System.out.println("k2 [" + k2.size() + "]" + k2.toString()); //PRINT2
System.out.println("");
if (k1.get(i) == maxLength) {
point++;
}
if (point < cp) {
c1a.add(k1.get(i));
c2a.add(k2.get(i)); //ERROR
} else {
c1b.add(k1.get(i));
c2b.add(k2.get(i));
}
}
c1.addAll(c1a);
c1.addAll(c2b);
c2.addAll(c2a);
c2.addAll(c1b);
Individu C1 = new Individu(c1, "f.fasta");
Individu C2 = new Individu(c2, "f.fasta");
C1.calculateFitness();
pop.add(C1);
C2.calculateFitness();
pop.add(C2);
}
当我运行程序时,它在某些时候运行。几代之后就会产生错误:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
at java.util.LinkedList.get(LinkedList.java:476)
at SKRIPSI.GA.crossover(GA.java:120)
at SKRIPSI.GA.siklusGA(GA.java:224)
at SKRIPSI.GA.main(GA.java:249)
Java Result: 1
GA.java:120 pointed at c2a.add(k2.get(i));
然后我尝试在PRINT1和PRINT2处打印k1和k2变量。当错误发生时,在PRINT2处,k2变为空。这是一个例子:
PRINT1
k1 [27][5, 4, 11, 6, 16, 9, 13, 10, 2, 15, 8, 17, 2, 10, 7, 15, 9, 11, 4, 3, 12, 6, 17, 0, 1, 7, 17]
k2 [27][0, 11, 13, 1, 10, 8, 15, 16, 14, 7, 3, 17, 16, 11, 8, 10, 13, 14, 4, 3, 15, 9, 17, 12, 3, 9, 17]
PRINT2
k1 [27][5, 4, 11, 6, 16, 9, 13, 10, 2, 15, 8, 17, 2, 10, 7, 15, 9, 11, 4, 3, 12, 6, 17, 0, 1, 7, 17]
k2 [0][]
在PRINT1和PRINT2之间没有变量k1和k2的修改。如果我改为这个错误,那么这个错误就会消失:
List<Integer> k1 = pop.get(getPOP(p1)).getKromosom();
List<Integer> k2 = pop.get(getPOP(p2)).getKromosom();
List<Integer> c1 = new LinkedList<>();
List<Integer> c2 = new LinkedList<>();
List<Integer> c1a = new LinkedList<>();
List<Integer> c2a = new LinkedList<>();
List<Integer> c1b = new LinkedList<>();
List<Integer> c2b = new LinkedList<>();
但是我收到了JavaHeap错误,因为我制作的实例太多了。
UPDATE1: 这是getPop方法,只返回数字:
public int getPOP(int p) {
return popSIZE - p - 1;
}
int maxLength = pop.get(getPOP(p1)).maxLength;
仅反向返回数字。例如popSIZE=10
和p=3
,则maxLength将选择pop.get(6)
。maxLength。 maxLength是个人对象内的属性。这是指定maxLength的行:
int temp = 0;
for (int i = 0; i < f.size(); i++) {
if (temp < f.getSequence(i).length()) {
temp = f.getSequence(i).length();
}
}
maxLength = (int) (Math.ceil((double) (temp * k)));
k是一些双(在我的情况下为1.2),f是序列数据库。
pop是一个ArrayList:List<Individu> pop = new ArrayList<>();
,所以get是调用那些列表的方法。
此外,在第一代k1和k2工作正常,第二代错误显示。并且只在这个方法中调用k2,我搜索没有其他方法调用k2。我试图在一夜之间解决这个问题,这是显示错误的正确行(因为当我点击错误时它会直接将我带到错误行)。也许NetBeans指向错误可能是错的?
UPDATE2:
因为在这种情况下maxLength总是27,所以我尝试将其更改为int maxLength = 27;
,但仍然显示错误。
您可以在此处下载完整代码:https://www.dropbox.com/sh/ish2lxh4jzro8zq/AADJfobUR8GUW7nzXtcpjyINa?dl=0
答案 0 :(得分:-1)
您在k2上执行get
而不先检查其大小。如果列表小于您传递的索引(或者 - 更极端的情况 - 如果列表为空),那就是预期的。