2016-07-20 4 views
-3

유전자 알고리즘을 사용하여 다중 시퀀스 정렬을 만들기 위해 자바 프로그램을 만들고 있습니다. 처음에는 인스턴스가 너무 많아서 JavaHeap 오류가 발생했습니다. 그래서 List에 clear() 메서드를 사용하여 객체를 다시 사용하여 문제를 해결하려고했습니다. 그러나 clear()을 사용하면 다른 변수가 null이됩니다. 다음은 제 코드입니다.List.clear() 다른 손대지 않은 변수에 영향을 미침

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가 null이됩니다. 변수 (K1, K2)의 범위의 어떠한 변경이 없을 PRINT1 및 PRINT2 사이 반면

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][] 

다음은 예이다. 이 변경하면이 오류가 사라집니다.

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 오류가 발생했습니다.

갱신 1 :

public int getPOP(int p) { 
     return popSIZE - p - 1; 
    } 

int maxLength = pop.get(getPOP(p1)).maxLength; 만 반대 방향으로 번호를 반환 : 이것은 getPop 방법에있어서, 전용 번호를 반환한다. 예를 들어 popSIZE=10p=3 인 경우 maxLength는 pop.get(6) .maxLength를 선택합니다. maxLength는 Individualu 객체의 속성입니다. maxLength가 할당 된 행입니다.

k는 두 번 (내 경우 1.2)이고 f는 시퀀스 데이터베이스입니다.

pop은 ArrayList : List<Individu> pop = new ArrayList<>();입니다. 따라서 이러한 목록을 호출하는 방법은 get입니다.

또한 1 세대에서는 k1과 k2가 잘 작동하고 2 세대에서는 오류가 표시됩니다. 그리고이 방법으로 k2 만 호출하면 k2를 호출하는 다른 방법이 없다는 것을 검색했습니다. 나는 이것을 밤새 풀려고했는데 오류를 표시하는 올바른 줄입니다 (오류를 클릭하면 오류 줄에 직접 표시되기 때문에). 어쩌면 NetBeans에서 오류를 지적하는 것이 잘못 될 수 있습니까?

UPDATE2 : 최대 길이는 항상 27이 경우이기 때문에, 나는 그것이 int maxLength = 27; 될 변경했는데, 그것은 여전히 ​​오류를 보여줍니다.

당신은 여기에 전체 코드를 다운로드 할 수 있습니다 https://www.dropbox.com/sh/ish2lxh4jzro8zq/AADJfobUR8GUW7nzXtcpjyINa?dl=0

+1

_ "clear()를 사용하면 다른 변수가 null이됩니다."_ _ 아니요, null이되는 증거가 없습니다. 오류는 목록이 비어있는 것과 관련이 있습니다. 전역 변수를 사용하기 때문에 pop.get() 또는 getPOP() 중 하나에 부작용이있을 수 있습니다. 해당 메소드에 대한 코드를 표시하십시오. –

+0

@ JimGarrison 모든 로깅이 루프 내에서 발생하는 것처럼 보입니다. 따라서 "글로벌 변수"에서 발생한다고 생각하지 않습니다.솔직히 말해서 실제 코드가 실행되고 있는지 또는 올바른 라인인지 확실치 않습니다. – Dici

+1

PRINT1과 PRINT2 사이에는'int maxLength = pop.get (getPOP (p1)) .maxLength;'가 있습니다. 두 방법 모두'k2'를 지울 수 있습니다. –

답변

-1

당신은 K2에 get을 수행하는 최초의 크기를 확인하지 않고. 목록이 전달하는 색인보다 작 으면 (또는 목록이 비어있는 경우 더 극단적 인 경우) 예상 할 수 있습니다.

+0

왜 이것이 downvoted 이유를 설명하기 위해? 나는 ** 당신이 원래 ** 질문을 많이 수정했음을 알지만, 내 대답은 여전히 ​​유효합니다. k2가 비어 있고 그것에'get (0)'을 수행하면 ArrayIndexOutOfBoundsException이 항상 생깁니다. – nasukkin

+0

나는 downvoted하지 않았다. 내 업데이트는 Jim Garrison과 Dici의 설명에 대한 설명입니다. PRINT1과 PRINT2 사이에는 k2의 수정이 없지만 k2의 PRINT2 크기는 0이되어 그 부분을 혼란스럽게합니다. – ceeri

관련 문제