我正在寻找一种能够找到将整数n表示为m(非负)整数之和的所有方法的算法。我特别感兴趣的是m = 6和n⩽20。什么是找到所有可能性的最快方法(使用计算机,而不是手动)。如果可能,我想只查看六个整数的组合,顺序不相关(即[1,2,0,0,0,0]和[2,1,0,0,0,0] ]被算作1组合。)
最简单的方法是简单地尝试6个小于或等于20的整数的所有排列,并且只将总和为20的那些加到我们的结果中(如果我们不想查看排序,则删除双精度) 。这似乎需要花费很长时间,因为20 ^ 6种可能性需要花费很长时间来检查。
解决这个问题的更有效方法是什么?
答案 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
包含到目前为止输出的部分列表。首次调用该函数时它将为空。
答案 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)