2015-02-10 25 views
0

我似乎有一個關於使用回溯實現功率集算法的問題。我想要實現的是相當簡單的,生成任何給定數字的功率集: Ex。 [1 2 3] => [1] [2] [3]; [1,2] [1,3] [2,3]; [1,2,3]通過回溯算法設置Java功能

我的算法使用堆棧來放置數字,它將數字添加到堆棧併發送它們進行計算。代碼如下:

public int calculatePowerSet(int x, LinkedList<Integer> arr) 
{ 
    int size = 1; 
    int nrOfTimes=0; 
    int calculate =0; 
    boolean goOn=true; 
    Stack<Integer> stack = new Stack<Integer>(); 
    int k=0, len = arr.size(); 
    double temp=0.0f; 
    while(size<=len) 
    { 
     goOn=true; 
     stack.push(arr.get(0)); 
     k = arr.indexOf(stack.peek()); 
     temp = size; //ignore these as they are for calculating time 
     temp/=len;  //ignore these as they are for calculating time 
     temp*=100;  //ignore these as they are for calculating time 
     setPowerSetPrecentage((int)temp); 
     while(goOn) 
     { 
      if(isStopProcess())return 0; 
      if((k==len)&&(stack.size()==0)) goOn=false; 
      else if(stack.size()==size) 
      { 
       String sign = ""; 
       if((stack.size()%2)==0) sign="+"; 
       else sign="-"; 
       calculate =calculateSets(stack.toArray(), sign, calculate, x); 
       k = arr.indexOf(stack.pop())+1; 
      } 
      else if(k==len) 
       k = arr.indexOf(stack.pop())+1; 
      else 
      { 
       prepereStack(stack,arr.get(k)); 
       k++; 
      } 
     } 
     size++; 
    } 
    return calculate; 
} 

這裏是計算方法:

private int calculate(int[] arr2, int x) 
{ 
     int calc=1; 

     float rez = 0; 
     for(int i=0;i<arr2.length;i++) 
      calc*=arr2[i]; 
     rez = (float)(x/calc); 
     calc = (int) (rez+0.5d); 
     return calc; 
} 

代碼似乎所有數字婁20被完美的工作,但在那之後我似乎得到錯誤的結果。我無法通過數字手動檢查,因爲有數百種組合。例如,對於25個數字的一​​個輸入,我應該得到1229的結果,而不是我得到1249.我不確定我錯過了什麼,因爲我認爲該算法應該在理論上工作,所以如果有人有任何建議,將是偉大的。

+1

「對於25個數字的一​​個輸入,我應該得到1229的結果」? 25個不同項目的功率設置的大小是「2^25」,即>> 1229.謹慎解釋? – alfasin 2015-02-10 04:04:19

+0

是的,數字本身是從我在功率設定結束後執行的計算中得出的...例如,每個數字的組合將被數字x除。然而,問題仍然是功率集的產生。 – 2015-02-10 04:07:16

+0

因此總而言之,你的計算*將*不正確,因爲你無法正確生成功率設置?你有什麼證據證明1229是正確的,而不是1249? – 2015-02-10 04:15:56

回答

0

我會建議從你的計算中分離出發電機組的代。雖然有一些非常有效的發電機組算法,但我建議保持它非常簡單,直到您需要提高效率。

private void forEachSet(List<Integer> currentSet, List<Integer> rest) { 
    if (rest.isEmpty()) { 
     process(currentSet); 
    } else { 
     Integer nextInt = rest.remove(0); 
     forEachSet(currentSet, rest); 
     currentSet.add(nextInt); 
     forEachSet(currentSet, rest); 
     current.remove(nextInt); 
     rest.add(nextInt); 
    } 
} 

public forEachSet(List<Integer> set) { 
    forEachSet(new ArrayList<>(), new ArrayList<>(set)); 
} 
+0

雖然解決方案是一個很好的解決方案,但由於我正在使用大量數據,因此我將在套件內出現問題。如果我嘗試在這種性質中實現某些東西,那麼我將得到堆錯誤,因爲它在內存中的空間不足。這就是爲什麼我選擇與Stacks合作並儘可能保持簡單。 – 2015-02-12 15:01:40

+0

@DanutNiculae我不確定我是否理解你的評論。我的解決方案沒有集合內的集合:它只是維護兩個列表:當前的和其餘的。關於列表,沒有什麼比堆棧更低效。真正的主要區別是我的解決方案使用遞歸來維護狀態。 – sprinter 2015-02-12 20:13:50