2014-09-30 36 views
-1

我在使用python中的算法時遇到了問題。 我有一個4值的數組[a,b,c,d],這些是百分比,所以在任何給定的時間a + b + c + d = 1。我需要一個循環遍歷所有可能的數字組合,步長爲0.1。例如:循環搜索數組中的所有可能組合

[0,0,0,1] 
[0,0,0.1,0.9] 
[0,0.1,0.1,0.8] 
[0.1,0.1,0.1,0.7] 
..... 
[0.1,0.1,0.2,0.6] 
[0.1,0.1,0.3,0.5] 
.... 
[1,0,0,0] 

我創建了一個代碼似乎溢出...任何幫助? TY我知道它的一個小白問題......

def frange(start, stop, step): 
    while start <= stop: 
     yield start 
     start += step 

def distribuir(p,array): 
    if len(array) == 3: 
     array.append(p) 
     print(Array) 
     return 
    for i in frange(0,1,0.1): 
     temp = [] 
     temp.append(array) 
     temp.append(i) 
     distribuir(p-i,temp) 
+0

那麼,你有什麼嘗試?如果你不知道如何從「0.0」到「1.0」以0.1的步長循環,考慮如果你使用'range(10)'並將每個值乘以'0.1',會發生什麼。一旦你有了,你應該知道如何寫下一個循環(提示:如果第一個值是'0.4',那麼下一個值只需要從'0.0'循環到'0.6'),然後下一個下一個。如果你遇到困難,你可以發佈你的代碼和你卡住的地方。 – abarnert 2014-09-30 00:09:46

+0

@abarnert:這是一個在Python中進行分區的實現。唯一的區別是縮放0.1。 – 2014-09-30 00:11:18

+0

@GregHewgill:但是這個問題是所有長度爲4的分區,而不是長度爲4,沒有'0',並且處理'1,1,1,7'和'7,1,1,1'作爲同一個分區,所有這些都與這裏所需的輸出不同。 – abarnert 2014-09-30 00:16:46

回答

0

了很多的優化空間一個天真的遞歸解決方案:

import itertools 

def possibilities(prefix, size, values, total):                                    
    if size == 0: 
     return [prefix] if sum(prefix) == total else [] 
    return itertools.chain(*map(
     lambda v: possibilities(prefix+[v], size-1, values, total), 
     values 
    )) 

例子:

list(
    map(
     lambda t: map(float, t), 
     possibilities(
      prefix=[], 
      size=3, 
      values=map(Decimal, ['0', '0.1', '0.2', '0.3']), 
      total=Decimal('0.4') 
     ) 
    ) 
)                    

輸出:

[[0.0, 0.1, 0.3], 
[0.0, 0.2, 0.2], 
[0.0, 0.3, 0.1], 
[0.1, 0.0, 0.3], 
[0.1, 0.1, 0.2], 
[0.1, 0.2, 0.1], 
[0.1, 0.3, 0.0], 
[0.2, 0.0, 0.2], 
[0.2, 0.1, 0.1], 
[0.2, 0.2, 0.0], 
[0.3, 0.0, 0.1], 
[0.3, 0.1, 0.0]]