2013-06-04 2 views
2

클래스 유형 BBNode의 우선 순위 대기열을 구현하려고하지만 예상대로 새 노드를 분류하지 않는 것 같습니다. 가장 작은 큐를 대기열의 헤드 (현재의 작동 방식)보다 오히려 가장 큰 큐에 넣고 싶지만이 작업을 수행하는 방법을 알 수는 없습니다. 여기 내 BBNode 클래스가 있습니다.Java 우선 순위 대기열이 제대로 정렬되지 않음

public class BBNode implements Comparable<BBNode>{ 
    public int level; //level on the tree 
    public int value; //value up to that node 
    public int weight; //weight up to that node 
    public double bound; //bound of that node 

    //...constructors 
    public int compareTo(BBNode node){ 
     if(this.bound > node.bound) return -1; 
     if(this.bound < node.bound) return 1; 
     return 0; 
    } 
} 

그리고 여기에 PQ를 사용합니다.

PriorityQueue<BBNode> pq = new PriorityQueue<BBNode>(); 
//..other variables 
while(pq.peek() != null){ 
    v = pq.poll(); 
    //System.out.println(v.weight + " " + v.value + " " + v.bound); 
    if(v.bound >= bestVal && v.level < sortedItems.length-1){ 
    //left branch: take the next item 
    u.level = v.level+1; 
    u.weight = v.weight + sortedItems[u.level].weight; 
    u.value = v.value + sortedItems[u.level].value; 
    u.bound = bound(u); 
    //System.out.println(u.bound); 
    if(u.bound > bestVal){ 
     pq.add(u); 
     System.out.println("adding " + u.bound); 
     System.out.println("top of pq is " + pq.peek().bound); 
    } 
    if(u.weight <= maxWt && u.value > bestVal){ 
     bestVal = u.value; 
     bestWt = u.weight; 
     //System.out.println(bestVal + " " + bestWt); 
     takeList[arrIdx++] = sortedItems[u.level].item+1; 
    } 
    //right branch: don't take the next item 
    u.weight = v.weight; 
    u.value = v.value; 
    u.bound = bound(u); 
    if(u.bound > bestVal){ 
     pq.add(u); 
     System.out.println("adding " + u.bound); 
     System.out.println("top of pq is " + pq.peek().bound); 
    } 
    } 
} 

마지막 서식을 죄송합니다. 마지막 괄호는 while 루프에 해당합니다.

또한 비교 방법에서 -1과 1 주위를 전환 해 보았습니다. 또한 비교기를 구현하려고했지만 동일한 결과를 얻었습니다.

어떤 도움에 감사드립니다 :)

+1

귀하의 BBNode가 정확하며 우선 순위 대기열에 그것들을 삽입하면 가장 잘 작동합니다 (가장 큰 바운드가 먼저 발생 함). 그런데 왜 잘못 생각하나요? 삽입 한 값의 일부가 올바르게 삽입되지 않은 것은 무엇입니까? – greedybuddha

+0

'u'를 설정 한 코드 섹션을 추가 할 수 있습니까? – sharakan

+1

인용 된 코드에서 각 반복에서 다른 객체를 가리 키도록 u를 지정하지 않고 u 참조하는 객체의 필드 만 변경합니다. 이것이 실제 코드의 경우라면 오직 하나의 객체 만 추가되고 그 값은 최신 v를 기준으로 변경됩니다. –

답변

3

는 무엇 가능성이 일어나고있는 것은 당신이 u.bound = bound(u); 등의 작업을 수행 할 때 현재 PriorityQueue에있는 인스턴스의 bound을 수정하는 것입니다. 루프를 처음으로 실행하면 u.bound를 설정하고 넣습니다. 다음 번에 u.bound를 다시 큐를 끄지 않고 다시 변경합니다.

당신이 (등 HashSet/Map, TreeSet/Map, PriorityQueue) 조직 컬렉션을 사용하는 경우 당신은 컬렉션이, 당신이 수집되는 가정을 깨고 어떻게 구성되어 있는지에 영향을하는 방식에서 요소 값을 변경 조직되고 다양한 흥미로운 방법으로 실패 할 것입니다. 그게 여기서 일어난 것 같아. 다른 콜렉션 유형에 대한 얘기

몇 가지 질문 :

+0

이것은 정확히 그랬습니다. PQ를 넣기 전에 각각의 새로운 객체를 인스턴스화하자마자 작동했습니다!재미있는 점은이 "포인터"논리가 C++ 프로그램에서 한 달 전에 문제를 일으켰다는 것입니다. 그러나 이것은 나에게 문제가되지 않을 수도 있습니다. ( –

0

는 또한 PriorityQueue 인 (자바 1.6) 최선의 노력을 정렬 나타납니다 있습니다.
동일한 Comparator를 사용하는 동안 PriorityQueue 및 ConcurrentSkipListSet을 사용하여 단위 테스트에서이 사실을 발견했습니다.
PriorityQueue는 새로 추가 된 항목의 올바른 위치를 찾으려고 시도합니다. 노드를 걷는 것처럼 보이지만 이전 항목이 모두 작아지면 항목이 커지고 그 반대의 경우에는 항목이 보이지 않고 항목이 마지막으로 검사 됨).
배열의 이진 검색 알고리즘과 비교할 때 검색 중 상한 및 하한 경계가 올바른 지점으로 가까워 지지만 간격이 남아있는 것처럼 보입니다. 동일한 비교자를 사용하여 ConcurrentSkipListSet을 사용하여 동일한 테스트를 반복하면 세트가 실제로 올바르게 정렬됩니다!