具有重复项的列表的排列

时间:2019-10-20 03:18:35

标签: python algorithm list generator permutation

我正在尝试制作一个整数分区生成器,其中顺序很重要,并且所有部分都小于k(例如,如果k = 10且n = 100,则[5, 95]不会是有效,因为95> = 10)。我已经从this website复制了一个生成器(并对其进行了修改),其中顺序无关紧要,现在我正在尝试制作一个通过每个分区排列的生成器。

我的主要问题是创建一个接受列表(分区)并有效输出该列表排列的函数。我已经通过使用itertools排列实现了此版本的低效率版本,其中包括:

set(itertools.permutations(partition))

这是非常低效的。当partition具有重复项时,它将遍历所有重复项。例如,当partition = [1, 1, 1, 1, 1, 1, 1]时,itertools将遍历所有7个!当只有一个唯一排列时= 5040个分区。

如何提高效率?我将考虑n的值在10 ^ 10或更高的数量级,因此效率非常重要。

如果有帮助,请注意分区的所有部分都小于k。

编辑:我想我(主要是)知道了。不过有一个错误。

def helper(current, index, available, freqList):
    if index >= len(freqList) or available == []:
        yield current
        return
    else:
        if freqList[index] != 0:
            for combo in itertools.combinations(available, freqList[index]):
                yield helper(new(current, index, combo), index + 1, delete(available, combo), freqList)
        else:
            yield helper(current, index + 1, available, freqList)
def permutations(partition, k):
    #returns permutations of partition

    length = len(partition)
    freqList = [partition.count(i) for i in range(k)]

    available = [i for i in range(length)]
    return helper([0]*length, 1, available, freqList)

delete(L, T)返回L的副本,不含T中的元素。new(L, i, T)返回L的副本,但T中的所有索引均被i替换。

这基本上是通过组合每个数字可以到达的位置来进行迭代。假设分区中有10 1s,5 2s和7 3s。迭代1可能经过的空间。然后,假设1占用其他空间,它将遍历2可以经过的空间。最后,在1和2占据其空间的情况下,对3可以经过的空间进行迭代。

此代码有错误。出于某种原因,permutations返回生成器的生成器,其中生成器...嵌套m次,其中m是partition中的最大元素。例如,如果partition = [1, 1, 1, 3, 3, 3],我将不得不

for gen1 in permutations(partition, k):
    for gen2 in gen1:
        for gen3 in gen2:
            for partition in gen3:
                #something else

以访问分区。

我不知道如何解决这个问题,但我认为这是个问题。

编辑2:戴维斯·赫林(Davis Herring)在评论中提到,我可以简单地yield from (helper(...)来解决此问题。我不知道我能做到这一点,而且它奏效了。我现在对这一解决方案的其他解决方案或优化很感兴趣。

0 个答案:

没有答案