2017-08-10 43 views
2

問題: 如何指定我的itertools.permutations對象,以便它只包含在列表中給出的一個開頭的排列? (Python 3.5)如何指定只允許某些第一組合的itertools排列?

故事: 我有一個難題,有36個益智元素,所以理論上4e + 41的可能性。如果我用itertools.permutations檢查它,它會永遠計算。因此,我嘗試檢查首先放置哪些方塊,然後只查找第一個地方的第二個地方,這是可能的。

例如塊2不適合在第一個地方,然後和itertools.permutations(MYLIST,2)不應該再包含像(2,1)(2,2)(2,3)等等

mylist = [0,1,2,3]  # ..,34,35 - contains all puzzle blocks 
begin = [(1,2),(1,3)] # this is the list of possible first blocks, so itertools should only give me combinations, that begin with one of this possibillities 

combs = itertools.permutations(mylist,3) # --- THIS IS THE LINE OF THE QUESTION --- 

組合在現在,我這樣做使用:

for thisposs in combs: 
    if thisposs[0:2] in begin: 
     checkblock(thisposs)  # check if thisposs is a combination that solves the puzzle 

但這種方式的for循環仍爆炸。我想指定迭代工具對象,以便它不具有所有的可能性,但只有那些與東西是數組/元組/列表內開始:

begin = [(1,2),(1,3)]    # only one of these should be allowed in first two slots 

該數組我每次增加時間重新計算一個準確的步驟,所以在優化過程中,可能需要像值:

begin = [1,3,4,5,6]    # after permutations(mylist,1) - still a lot beginnings are possible 
begin = [(1,6),(1,7),(5,1),(6,7)] # after permutations(mylist,2) - some combinations didn't work further 
begin = [(5,1,2),(5,1,6),(5,1,7)] # after permutations(mylist,3) - the solution can for sure only begin with 5-2-??? 
# and so on 

每次我做了一個「精度一步」,我提出一個新的itertools對象與

combs = itertools.permutations(mylist,n+1) 

所以我的問題是:如何指定我的itertools.permutations對象,以便它只包含列表中給出的一個開始的排列?

+1

不要使用'itertools.permutations'。自己實施回溯搜索。 – user2357112

+0

是的,這絕對沒有內置的支持。 –

回答

1

在任何級別,您都希望有一個函數可以查看每個開始序列,從一組可能性中移除開始序列的元素,然後對其餘部分進行置換。

這裏有一臺發電機,將做到這一點:

def find_permutations(begin_sequences, full_set): 
    for begin_sequence in begin_sequences: 
     remaining_set = full_set - set(begin_sequence) 
     for ending in itertools.permutations(remaining_set): 
      yield begin_sequence + list(ending) 

如果你想與你的第一個例子來試試這個,試試這個。 (請注意,如果你打印出來,因爲你full_set這麼大,你可能有一段時間,您可能希望將其降低到像8用於測試目的。):

full_set = set(range(1,37)) 
for p in find_permutations([[1], [3], [4], [5], [6]], full_set): 
    print(p) 

您的最終示例將如下所示:

for p in find_permutations([[5,1,2], [5,1,6], [5,1,7]], full_set): 
    print(p)