2012-03-05 43 views
3

我已經更新了這個問題(發現最後一個問題還不清楚,如果你想參考它,查看反轉歷史)。目前的答案到目前爲止不起作用,因爲我沒有清楚地解釋我的問題(對不起,第二次嘗試)。如何將算法縮減爲更小的部分以便我可以縮放它?

目標

試圖採取一組數字的(正或負,從而需要邊界限制特定變量的生長),並發現可用於獲得到一個特定的總和它們的線性組合。例如,去利用的總和10 [2,4,5]我們得到:

5*2 + 0*4 + 0*5 = 10 
3*2 + 1*4 + 0*5 = 10 
1*2 + 2*4 + 0*5 = 10 
0*2 + 0*4 + 2*5 = 10 

如何創建一個算法中是可擴展的大量的變量和target_sums?如果給出算法,我可以自己編寫代碼,但如果有庫可用,我可以使用任何庫,但更喜歡使用java。

+0

隨着你所提供的信息,它是唯一可能ŧ o確定你所做的是正確/快速還是錯誤。如果你想要一個替代算法,你將不得不提供整個問題陳述。希望你得到我想說的。 – noMAD 2012-03-05 17:37:45

+0

另外,如果'T [z-c * x_i] [i-1]'是真的,你是什麼意思?什麼樣的數組是'T [] []'? – noMAD 2012-03-05 17:40:14

+0

@noMAD到目前爲止,我正在尋找一種方法來打破這個算法,但如果我沒有得到任何答覆或這是不可能的規模,我可能會重新發佈一個問題來改善整個算法。我發佈了一個具體的例子,但老實說,我想我會再次遇到類似的問題,所以我寧願理解一般原則,所以我可以適用於其他情況..T只是一個鍵/ val表T [0] [ 0]或者T [10] [2]等。 – 2012-03-05 17:41:21

回答

2

一個想法是打出來的循環,一旦你設置T[z][i]true,因爲你只修改基本上這裏T[z][i],如果它確實成爲true,它永遠不會被再次修改。

for i = 1 to k 
    for z = 0 to sum: 
     for j = z-x_i to 0: 
      if(T[j][i-1]): 
       T[z][i]=true; 
       break; 

EDIT2:另外,如果我得到它的權利,T[z][i]取決於陣列T[z-x_i..0][i-1]上。 T[z+1][i]取決於T[z+1-x_i..0][i-1]。因此,一旦知道T[z][i]是否爲true,則只需檢查一個附加元素(T[z+1-x_i][i-1])即可知道T[z+1][i-1]是否爲true

假設您代表T[z][i]是否由變量changed更新。那麼,你可以簡單地說T[z][i] = changed && T[z-1][i]。所以你應該用兩個循環而不是三個來完成。這應該使它快得多。

現在,它的規模 - 現在,T[z,i]T[z-1,i]T[z-1-x_i,i-1]依賴,所以填充T[z,i],你並不需要等待整個(i-1)列被填充到。一旦填入所需的值,您就可以開始使用T[z,i]。我不能在不知道細節的情況下實現它,但是您可以嘗試這種方法。

+0

I有點理解你做了什麼(但不知道如何縮放它,說我使用了一百萬個變量和一百萬的總和),但我試圖將算法分解成多個較小的部分,以便可以跨多個核心。我用代碼更新了問題以及我所看到的。 – 2012-03-05 18:23:54

+0

您是否瞭解我添加的第二部分(EDIT2)..我無法爲此編寫僞代碼,因爲我不瞭解您如何填充T [0] [i]。至於縮放,困難在於每列都依賴於前一個,所以它很難適用分而治之。 – 2012-03-05 18:36:16

+0

我想我明白了,它就像一個雞/蛋問題,我無法弄清楚T [z ] [我]不知道T [z + 1-x_i..0] [i-1] ..我用我正在測試的代碼更新了答案。我仍然不明白如何在多個CPU上擴展。你認爲我可能在看這個錯誤嗎?可能不是考慮如何將T [z + 1-x_i..0] [i-1]的最終結果轉換爲T [z] [i],我應該試圖將T [z] [i]到T [z + 1-x_i..0] [i-1]? – 2012-03-05 18:55:06

0

我認爲這是無限的揹包嗎?完全可以免除c的循環。

for i = 1 to k 
    for z = 0 to sum 
     T[z][i] = z >= x_i cand (T[z - x_i][i - 1] or T[z - x_i][i]) 
+0

我的回答有什麼問題? – 2012-03-07 18:27:25

0

根據您所提供的評論部分(有界)(術語的線性組合)和您給我的回答原來的數據。例如,將一個強力的辦法行不通?

c0x0 + c1x1 + c2x2 +...+ cnxn = SUM 

我猜我失去了一些重要的東西,但在這裏它是無論如何:

蠻力分而治之:

  • 主控制器爲說,一半係數這些術語(或者很多可能有意義的)
  • 然後它將固定係數的每個部分集合發送到工作隊列
  • 一名工人拿起一個局部組固定係數,並且進行到蠻力通過剩餘的組合強制我行我素
  • 它不會使用太多的記憶力,因爲它的工作順序在每個組有效係數
  • 可能是優化忽略等同組合和可能很多其他的方式

爲僞多處理

class Controller 
    work_queue = Queue 
    solution_queue = Queue 
    solution_sets = [] 
    create x number of workers with access to work_queue and solution_queue 
    #say for 2000 terms: 
    for partial_set in coefficient_generator(start_term=0, end_term=999): 
     if worker_available(): #generate just in time 
      push partial set onto work_queue 
     while solution_queue: 
      add any solutions to solution_sets 
     #there is an efficient way to do this type of polling but I forget 

class Worker 
    while true: #actually stops when a stop work token is received 
     get partial_set from the work queue 
     for remaining_set in coefficient_generator(start_term=1000, end_term=1999): 
      combine the two sets (partial_set.extend(remaining_set)) 
      if is_solution(full_set): 
       push full_set onto the solution queue 
+0

非常感謝Yakiimo,抽出時間回答。我將致力於實現您的僞代碼,以瞭解它的工作原理。它有點不清楚,是強制解決方案還是查找表生成?我明白最後的結果依賴於以前的所有解決方案,但我試圖將表生成器與該需求分離。我用另一種方法(如果它提供任何想法)更新我的答案來建立表格。 – 2012-03-07 14:58:07

+0

我想這就是我懶惰的地方,並沒有試圖解釋你的其他信息。在原始問題定義中,除了可能爲了優化目的,我沒有看到每個解決方案都依賴於以前解決方案的任何原因。這就是爲什麼我的僞代碼係數集產生,計算和丟棄。沒有任何大型數據集的建立。最大的項目將是這組解決方案。我們在哪裏斷開連接? – KobeJohn 2012-03-07 15:23:20

+0

對不起,我沒有直接回答你的問題:它試圖通過嘗試所有可能的係數組​​來強制解決方案。給定值(x0,x1,...,xn)可能是某處的數據,僅在「is_solution()」中使用。 「coefficient_generator()」實際上是一個發生器,一次產生一個係數置換(c_start,...,c_end)。製作這兩部分應該很簡單。這是否回答你所問的?我的解決方案中沒有生成表格。 – KobeJohn 2012-03-07 15:27:26

相關問題