2011-12-28 17 views
3

產量子組合,我與Python 3.我正在使用該功能的工作如下:與限制

def sub_combinations(segment): 
    if len(segment) == 1: 
    yield (segment,) 
    else: 
    for j in sub_combinations(segment[1:]): 
     yield ((segment[0],),)+j 
     for k in range(len(j)): 
     yield (((segment[0],)+j[k]),) + (j[:k]) +(j[k+1:]) 

了一個版本的功能:

Yielding sub combinations

(1,2,3,4,5)的輸出如下:

((1,), (2,), (3,), (4,), (5,)) 
((1, 2), (3,), (4,), (5,)) 
((1, 3), (2,), (4,), (5,)) 
((1, 4), (2,), (3,), (5,)) * 
((1, 5), (2,), (3,), (4,)) * 
((1,), (2, 3), (4,), (5,)) 
((1, 2, 3), (4,), (5,)) 
((1, 4), (2, 3), (5,)) * 
((1, 5), (2, 3), (4,)) * 
((1,), (2, 4), (3,), (5,)) 
((1, 2, 4), (3,), (5,)) 
((1, 3), (2, 4), (5,)) 
((1, 5), (2, 4), (3,)) * 
((1,), (2, 5), (3,), (4,)) * 
((1, 2, 5), (3,), (4,)) * 
((1, 3), (2, 5), (4,)) * 
((1, 4), (2, 5), (3,)) * 
((1,), (2,), (3, 4), (5,)) 
((1, 2), (3, 4), (5,)) 
((1, 3, 4), (2,), (5,)) 
((1, 5), (2,), (3, 4)) * 
((1,), (2, 3, 4), (5,)) 
((1, 2, 3, 4), (5,)) 
((1, 5), (2, 3, 4)) * 
((1,), (2, 5), (3, 4)) * 
((1, 2, 5), (3, 4)) * 
((1, 3, 4), (2, 5)) * 
((1,), (2,), (3, 5), (4,)) 
((1, 2), (3, 5), (4,)) 
((1, 3, 5), (2,), (4,)) 
((1, 4), (2,), (3, 5)) * 
((1,), (2, 3, 5), (4,)) 
((1, 2, 3, 5), (4,)) 
((1, 4), (2, 3, 5)) * 
((1,), (2, 4), (3, 5)) 
((1, 2, 4), (3, 5)) 
((1, 3, 5), (2, 4)) 
((1,), (2,), (3,), (4, 5)) 
((1, 2), (3,), (4, 5)) 
((1, 3), (2,), (4, 5)) 
((1, 4, 5), (2,), (3,)) * 
((1,), (2, 3), (4, 5)) 
((1, 2, 3), (4, 5)) 
((1, 4, 5), (2, 3)) * 
((1,), (2, 4, 5), (3,)) 
((1, 2, 4, 5), (3,)) 
((1, 3), (2, 4, 5)) 
((1,), (2,), (3, 4, 5)) 
((1, 2), (3, 4, 5)) 
((1, 3, 4, 5), (2,)) 
((1,), (2, 3, 4, 5)) 
((1, 2, 3, 4, 5),) 

問題是,如果我工作機智h較大的元組時,函數sub_combinations會返回大量數據,並且計算時間過長。爲了解決這個問題,我想通過添加一個額外的參數來限制返回的數據量。例如,sub_combinations((1,2,3,4,5),2)應該返回上面的數據,但沒有標有星號的元組。因爲元組中的連續值之間的偏移量大於2,所以這些被刪除。例如,包含(1,4),(1,5)或(2,5)等的行(1,2,5)被丟棄。要調整

for k in range(len(j)) 

需要刪除這些行,但我還沒有想出如何。有什麼建議麼?

巴里

回答

1

我想在下面的輸出變化的結果,你正在尋找:

def sub_combinations(segment, max_offset=None): 
    data = tuple([e] for e in segment) 
    def _sub_combinations(segment): 
     if len(segment) == 1: 
     yield (segment,) 
     else: 
     for j in _sub_combinations(segment[1:]): 
      yield ((segment[0],),)+j 
      for k in range(len(j)): 
       if max_offset and data.index(j[k][0]) - data.index(segment[0]) > max_offset: 
        break 
       yield (((segment[0],)+j[k]),) + (j[:k]) +(j[k+1:]) 
    for combination in _sub_combinations(data): 
     yield tuple(tuple(e[0] for e in t) for t in combination) 

這裏的想法是,你跳出k循環,而不是產生一個元組將有大於max_offset的偏移量。

+0

(1,2,3,4,5)只是一個例子。 (「H」,「E」,「L」,「P」)也是這個函數的有效參數,它不會與你的代碼一起工作。 – Baz 2011-12-29 09:54:47

+0

只要將每個字母視爲其ASCII碼的十進制形式(將所有字母標準化爲大寫或小寫之後),並且該代碼仍然可以工作。 – 2011-12-29 18:08:14

+0

@Baz - 它現在應該可以處理任意輸入,但它也有點複雜。 – 2011-12-29 18:08:47