一尘不染

生成固定长度整数分区的所有唯一置换的算法?

algorithm

我正在寻找一种算法,该算法可生成整数的固定长度分区的所有排列。顺序无所谓。

例如,对于n = 4和长度L = 3:

[(0, 2, 2), (2, 0, 2), (2, 2, 0),
 (2, 1, 1), (1, 2, 1), (1, 1, 2),
 (0, 1, 3), (0, 3, 1), (3, 0, 1), (3, 1, 0), (1, 3, 0), (1, 0, 3),
 (0, 0, 4), (4, 0, 0), (0, 4, 0)]

我对整数分区+长度小于L的分区的排列感到困惑;但那是太慢了,因为我在同一个分区中多次得到了(因为[0, 0, 1]可能的排列[0, 0, 1];-)

任何帮助表示赞赏,不,这不是功课-个人利益:-)


阅读 211

收藏
2020-07-28

共1个答案

一尘不染

好的。首先,忽略排列,仅生成长度为L的分区(如@Svein
Bringsli所建议)。请注意,对于每个分区,可以对元素强加一个顺序,例如>。现在只需“计数”即可保持您的订购。对于n = 4,k = 3:

(4, 0, 0)
(3, 1, 0)
(2, 2, 0)
(2, 1, 1)

那么,如何实现呢?它看起来像:在从位置i减去1并将其添加到下一个位置的同时保持我们的顺序,从位置i减去1,在位置i +
1处加1并移动到下一个位置。如果我们处于最后位置,请退后一步。

这是一个小蟒蛇,它就是这样做的:

def partition_helper(l, i, result):
    if i == len(l) - 1:
        return 
    while l[i] - 1 >= l[i + 1] + 1:
        l[i]        -= 1
        l[i + 1]    += 1
        result.append(list(l))
        partition_helper(l, i + 1, result)

def partition(n, k):
    l = [n] + [0] * (k - 1)
    result = [list(l)]
    partition_helper(l, 0, result)
    return result

现在,您有了一个列表列表(实际上是一个多集列表),并且生成列表中每个多集的所有排列都会为您提供解决方案。我将不去赘述,这里有一个递归算法,该算法基本上说,对于每个位置,选择多重集中的每个唯一元素,并追加从多重集中删除该元素所产生的多重集合的置换。

2020-07-28