2011-02-18 2 views
1

약간의 문맥을 위해 프로젝트 오일러 problem 31을 우수하다고 사용하여 해결하려고합니다. GParsPool Fork/Join support. 이를 위해GParsPool의 ConcurrentException/NullPointerException runForkJoin

, 내가 foolowing 코드를 작성했습니다 :

import groovyx.gpars.* 
import groovy.util.GroovyCollections 

@Grab(group="org.codehaus.gpars", module="gpars", version="0.11") 
def getMatchingCombos(target) { 
    combos = [200, 100 /*, 50, 20, 10, 5, 2, 1*/] 
    GParsPool.withPool(1) { pool -> 
     combos = combos.collectParallel { n -> 
      ((0..(target/n)).step(1) as TreeSet).collect { p -> p*n } 
     } 
     return GParsPool.runForkJoin(combos, 0, 0, target) { usableCombos, comboIndex, sum, targetSum -> 
      def offset = "\t"*comboIndex 
      def results = 0 
      if(sum<=targetSum) { 
       if(comboIndex<combos.size()) { 
        usableCombos[comboIndex].each { n -> 
         println offset+"now trying with $comboIndex element value $n (curent sum is $sum)" 
         results += forkOffChild(usableCombos, comboIndex+1, sum+n, targetSum) 
        } 
       } else { 
        if(sum==targetSum) { 
         results +=1 
         println offset+"sum is target ! so we have $results" 
        } 
       } 
      } 
      return results; 
     } 
    } 
} 

println getMatchingCombos(200) 

불행히도, 나는 이것을 실행하려고 할 때마다, 나는 다음과 같은 스택 추적 얻을 : 나는이

now trying with 0 element value 0 (curent sum is 0). Known combos are [[0, 200], [0, 100, 200]] and target is 200 
     now trying with 1 element value 0 (curent sum is 0). Known combos are [[0, 200], [0, 100, 200]] and target is 20 
0 
Caught: java.util.concurrent.ExecutionException: java.lang.NullPointerException 
     at groovyx.gpars.GParsPool.runForkJoin(GParsPool.groovy:305) 
     at probleme_31$_getMatchingCombos_closure1.doCall(probleme_31.groovy:18) 
     at groovyx.gpars.GParsPool$_withExistingPool_closure1.doCall(GParsPool.groovy:170) 
     at groovyx.gpars.GParsPool$_withExistingPool_closure1.doCall(GParsPool.groovy) 
     at groovyx.gpars.GParsPool.withExistingPool(GParsPool.groovy:169) 
     at groovyx.gpars.GParsPool.withPool(GParsPool.groovy:141) 
     at groovyx.gpars.GParsPool.withPool(GParsPool.groovy:117) 
     at probleme_31.getMatchingCombos(probleme_31.groovy:9) 
     at probleme_31.run(probleme_31.groovy:41) 

을 이해 내가 재귀 "평면화"메커니즘으로 포크/조인을 이용하려는 방식과 관련이 있지만, 여기서 내가하는 오류는 무엇입니까?

답변

3

getChildrenResults()를 사용하여 수행해야하는 반면 fork 결과는 forkOffChild() 메서드에서 반환 값으로 잘못 읽으려고합니다.

 return GParsPool.runForkJoin(combos, 0, 0, target) { usableCombos, comboIndex, sum, targetSum -> 
     def offset = "\t"*comboIndex 
     def results = 0 
     if(sum<=targetSum) { 
      if(comboIndex<combos.size()) { 
       usableCombos[comboIndex].each { n -> 
        println offset+"now trying with $comboIndex element value $n (curent sum is $sum)" 
        forkOffChild(usableCombos, comboIndex+1, sum+n, targetSum) 
       } 
      } else { 
       if(sum==targetSum) { 
        results +=1 
        println offset+"sum is target ! so we have $results" 
       } 
      } 
     } 
     results += getChildrenResults().sum(0) 
     return results; 
    } 
+0

멋지다! getChildrenResults는 GPars Fork/Join 페이지에 문서화되어 있지 않지만 Google은 블로그 (http://www.jroller.com/vaclav/entry/parallel_recursion)에서이 메소드에 대한 참조를 찾았지만, – Riduidel