数学:对整数分区函数和算法的更多控制

时间:2016-08-20 13:36:46

标签: python math integer partition

整数分区是一个非常有趣的主题。创建给定整数的所有分区几乎都很简单,例如以下代码:

def aP(n):
    """Generate partitions of n as ordered lists in ascending
    lexicographical order.

    This highly efficient routine is based on the delightful
    work of Kelleher and O'Sullivan."""

    a = [1]*n
    y = -1
    v = n
    while v > 0:
        v -= 1
        x = a[v] + 1
        while y >= 2 * x:
            a[v] = x
            y -= x
            v += 1
        w = v + 1
        while x <= y:
            a[v] = x
            a[w] = y
            yield a[:w + 1]
            x += 1
            y -= 1
        a[v] = x + y
        y = a[v] - 1
        yield a[:w]

寻找一种方法来获得对该功能的更多控制,例如为了仅生成N大小的分区,这个解决方案看起来更好:

def sum_to_n(n, size, limit=None):
    """Produce all lists of `size` positive integers in decreasing order
    that add up to `n`."""
    if size == 1:
        yield [n]
        return
    if limit is None:
        limit = n
    start = (n + size - 1) // size
    stop = min(limit, n - size + 1) + 1
    for i in range(start, stop):           
        for tail in sum_to_n(n - i, size - 1, i):
            yield [i] + tail

但是它们都会生成给定数字的所有可能分区,第一个是每个大小,第二个是给定大小。如果我只想要给定数字的一个特定分区怎么办? 以下代码生成给定分区的下一个分区:

def next_partition(p):
  if max(p) == 1:
    return [sum(p)]
  p.sort()
  p.reverse()
  q = [ p[n] for n in range(len(p)) if p[n] > 1 ]
  q[-1] -= 1
  if (p.count(1)+1) % q[-1] == 0: 
    return q + [q[-1]]*((p.count(1)+1) // q[-1])
  else:
    return q + [q[-1]]*((p.count(1)+1) // q[-1]) + [(p.count(1)+1) % q[-1]]

但仍有问题,您必须知道分区请求之前的分区是什么。

假设现在需要一个整数N的给定分区,你只知道分区的编号;例如:

4的分区是:

n.1 4
n.2 3+1
n.3 2+2
n.4 2+1+1
n.5 1+1+1+1

如何创建仅给出整数(4)和序列号(2)的分区号2(3 + 1)?所有这些都没有创建所有分区? 我已经阅读过某个可能的数学公式,但我不知道如何。

0 个答案:

没有答案