如何修改此函数以计算数字分区的平均长度?

时间:2017-09-06 15:34:50

标签: python

我正在使用分区(数论)。我想编写一个函数来告诉我一个数字分区的平均长度。例如。数字4的分区是:

1+1+1+1
1+1+2
1+3
2+2
4

我从这里的另一个问题中借用了这个函数,它打印了你为给定数字添加数字列表的所有方法:

def subset_sum(numbers, target, partial=[]):
    s = sum(partial)

# check if the partial sum is equals to target
    if s == target:
        print "sum(%s)=%s" % (partial, target)
    if s >= target:
        return  # if we reach the number why bother to continue

    for i in range(len(numbers)):
        n = numbers[i]
        remaining = numbers[i+1:]
        subset_sum(remaining, target, partial + [n])

if __name__ == "__main__":
    subset_sum([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],15)

输出:

sum([3, 8, 4])=15
sum([3, 5, 7])=15
sum([8, 7])=15
sum([5, 10])=15

我修改了它以通过改变来重复:

remaining = numbers[i+1:]

为:

remaining = numbers[i:]

然后我在函数中添加了两个参数:

def subset_sum(numbers, target, length_twos=[0], partitions_with_twos=[0],
               partial=[]):

我在函数内添加说:

if s == target:
    if 2 in partial:
        length_twos[0]+=len(partial)
        partitions_with_twos[0]+=1

然后在最后我想找出包含2的分区的平均长度。但它没有给我正确的答案。知道为什么吗?例如,数字4的平均值应为2.5。

当然我还修改了函数中的subset_sum()以递归地包含参数。像这样。

for i in range(len(numbers)):
    n = numbers[i]
    remaining = numbers[i+1:]
    subset_sum(remaining, target, length_twos, partitions_with_twos,
               partial + [n])

2 个答案:

答案 0 :(得分:1)

使用@skovorodkin的优秀partition generator,可以创建长度列表。由此可以计算出平均长度:

def partitions(n, I=1):
    yield (n,)
    for i in range(I, n//2 + 1):
        for p in partitions(n-i, i):
            yield (i,) + p

partition_lengths = [len(p) for p in partitions(4) if 2 in p]

print partition_lengths
print sum(partition_lengths) / float(len(partition_lengths))

4提供以下输出:

[3, 2]
2.5

使用2 in生成的分区将是:

[(1, 1, 2), (2, 2)]

答案 1 :(得分:0)

正如我所说,我真的不明白你的问题。也就是说,也许您会发现以下代码片段非常有用:

def partition(n):
    """ Find partitions of integer 'n'.
        Simplification of https://stackoverflow.com/a/400796/355230
    """
    result = [[n]]

    for i in range(1, n):
        a = n-i
        for r in partition(i):
            if r[0] <= a:
                result.append([a] + r)

    return result

def subset_sum(target):
    """ Find average length of partitions of the target integer. """
    numbers = partition(target)
    return sum(map(len, numbers)) / float(len(numbers))

if __name__ == "__main__":
    target = 4
    numbers = partition(target)  # computed and printed here only for testing
    print('partitions of {}: {}'.format(target, numbers))
    print('average length of partitions: {}'.format(subset_sum(target)))

输出:

partitions of 4: [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
average length of partitions: 2.4