如何找到获取整数n的所有方法作为m个整数的总和(无顺序)?

时间:2017-01-24 19:34:24

标签: algorithm number-theory

我正在寻找一种能够找到将整数n表示为m(非负)整数之和的所有方法的算法。我特别感兴趣的是m = 6和n⩽20。什么是找到所有可能性的最快方法(使用计算机,而不是手动)。如果可能,我想只查看六个整数的组合,顺序不相关(即[1,2,0,0,0,0]和[2,1,0,0,0,0] ]被算作1组合。)

最简单的方法是简单地尝试6个小于或等于20的整数的所有排列,并且只将总和为20的那些加到我们的结果中(如果我们不想查看排序,则删除双精度) 。这似乎需要花费很长时间,因为20 ^ 6种可能性需要花费很长时间来检查。

解决这个问题的更有效方法是什么?

2 个答案:

答案 0 :(得分:3)

您可以通过以单调递增的顺序生成数字来避免重复(每个数字等于或大于前一个数字)。

对于给定的count(例如6),您可以通过为第一个数字生成所有可能的值来递归地定义问题,然后递归地生成所有count - 1个数字的列表,这些数字总和为原始总和减去第一个数字,第一个数字是列表中其余数字的最小值。

因为数字需要增加,所以你不能太早地达到峰值" - 您可以通过将总和除以计数来计算最大值(因为所有剩余值必须等于或大于此值)。

这是Java中的一个简单实现:

public static void outputSums(String start, int sum, int count, int min)
{
    // if there is just one value, it's just the sum:
    if(count == 1)
    {
        System.out.println(start + " " + sum);
        return;
    }

    int max = sum / count;  // calculate maximum value
    for(int i = min; i <= max; i++)
    {
        outputSums(start + " " + i,  // append each number to the list
            sum - i,  // recursively find numbers that sum to the remainder
            count - 1,   // with a count of one less
            i);   // equal to or greater to this one (i.e. increasing order)
    }
}

start包含到目前为止输出的部分列表。首次调用该函数时它将为空。

Demo

答案 1 :(得分:2)

前一种方法的另一种方法是从最大到最小计算它。

这是一个Python实现,使用迭代器,以便以编程方式使用。

def partition (count, total, maximum = None) :
    if maximum is None or total < maximum:
        maximum = total
    if 0 == count:
        yield []
    else:
        while total <= count * maximum:
            for part in partition(count - 1, total - maximum, maximum):
                yield part + [maximum]
            maximum = maximum - 1

以下是如何以编程方式使用它来打印输出的示例:

for part in partition(6, 10):
    print(part)