在Python中设置最大大小为n的有序分区

时间:2017-08-22 14:18:56

标签: python arrays combinatorics

我遇到的问题类似于以下但不完全相同: Set partitions in Python

所以我希望得到与其他问题相同的结果,但我想阻止最大分区数为n,并且只获得有序分区。此外,分区中的值应该是唯一的。例如,问题中的示例为range(1,5)

产生了以下分区
1 [[1, 2, 3, 4]]
2 [[1], [2, 3, 4]]
3 [[1, 2], [3, 4]]
4 [[1, 3, 4], [2]]
5 [[1], [2], [3, 4]]
6 [[1, 2, 3], [4]]
7 [[1, 4], [2, 3]]
8 [[1], [2, 3], [4]]
9 [[1, 3], [2, 4]]
10 [[1, 2, 4], [3]]
11 [[1], [2, 4], [3]]
12 [[1, 2], [3], [4]]
13 [[1, 3], [2], [4]]
14 [[1, 4], [2], [3]]
15 [[1], [2], [3], [4]]

在我的情况下,我只想获得以下内容:

1 [[1, 2, 3, 4]]
2 [[1], [2, 3, 4]]
3 [[1, 2], [3, 4]]
4 [[1], [2], [3, 4]]
5 [[1, 2, 3], [4]]
6 [[1], [2, 3], [4]]
7 [[1, 2], [3], [4]]
8 [[1], [2], [3], [4]]

此外,我希望能够将分区数量阻为数字n。如果我举一个n=2的例子,则需要产生以下内容:

1 [[1, 2, 3, 4]]
2 [[1], [2, 3, 4]]
3 [[1, 2], [3, 4]]
4 [[1, 2, 3], [4]]

请记住,我将要处理的最终阵列的大小将超过1,000,因此我希望算法有效,但能够阻止它到n分区

1 个答案:

答案 0 :(得分:2)

comments中所述,n个不同的元素和k块或切片,只需生成k-1n-1分隔符的选择就足够了可能的位置:

from itertools import combinations

def segmentations(a, k):
    n = len(a)
    assert 1 <= k <= n, (n, k)

    def split_at(js):
        i = 0

        for j in js:
            yield a[i:j]
            i = j

        yield a[i:]

    for separations in combinations(range(1, n), k - 1):
        yield list(split_at(separations))

这会在k个部分生成分段,修改它以生成最多 k个部分非常简单。它还清楚地表明,结果中确实有C(n-1, k-1)个元素用于k部分。现在,C(1000, 8)24,115,080,524,699,431,125。可能更好地尝试不同的方法吗?