问题:
如何指定itertools.permutations对象,使其仅包含列表中给定的以一个开头的排列(巨蟒3.5)
故事:
我有一个谜题,有36个谜题元素,理论上是4e+41的可能性。如果我用itertools.permutations检查这个,它将永远计算。因此,我试着检查哪些块适合第一个位置,然后只寻找第二个位置与第一个位置,这是可能的。
例如,块2首先不适合,然后是itertools。置换(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循环仍然会爆炸。我想指定itertools对象,这样它就没有所有的可能性,只有那些可能性,它们以array/tuple/list中的某个开始:
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

每次我做一个“精确步骤”,我就用
combs = itertools.permutations(mylist,n+1)

所以我的问题是:如何指定itertools.permutations对象,以便它只包含列表中给定的以一个开头的排列?

最佳答案

在任何级别上,您都希望有一个函数来查看每个开始序列,从一组可能性中删除开始序列的元素,然后排列其余的元素。
这里有一个发电机可以做到这一点:

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)

如果你想用你的第一个例子试试这个,试试这个。(请注意,如果您打印出来,因为您的全套是如此之大,您可能会有一段时间为了测试的目的,您可能需要将它减少到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)

10-04 21:59
查看更多