我有一组数字。我正在设置66,但它可以是任何大小设置,可以分为两个相等的集合(例如每个33)
这些数字不是连续的,也不是相互关联的。可能有重复。
我需要一个数学算法来确定是否有任何方法在两组之间分配数字,以便一组33中的一些等于另一组33中的一些。
实施例。 1,8,5,12 = 8,8,8,2(两侧等于26)。
我知道这些是平等的。如果它存在,我需要算法来找到这个分布。
答案 0 :(得分:3)
排序数字。
从最高点开始并添加下一个数字以设置具有较低总和的数据。
例如,对于数字9 7 3 3 2:
S0 = S1 = 0
9到S0,S0 = 9,S1 = 0
7至S1,S0 = 9,S1 = 7
3至S1,S0 = 9,S1 = 10
3至S0,S0 = 12,S1 = 10
2至S1,S0 = 12,S1 = 12
此算法将为您提供两组尽可能低的差异。
答案 1 :(得分:1)
我猜这是一个直接的背包问题
1)总结所有数字,让我们说S。
2)使用所有数字作为重量,尝试装入尺寸为>> 1的袋子
答案 2 :(得分:1)
您的任务是熟知分区问题。 你可以在wiki上找到它的相关信息: http://en.wikipedia.org/wiki/Partition_problem
这是NP的全部任务。如果你可以使用近似算法,那么你可以使用@Ari的变体。但它并不总是给出正确的答案。样品:13,12,5,5,5,5,5
可以使用伪多项式复杂度O(n * s)的动态规划建立最佳解决方案,其中n - 所有数字的计数,s - 它们的总和。
让你有P数组的数组。然后确切的解决方案是:
bool hasSolution(long n, long *P, long sum)
{
long A[SIZE][SIZE] = {{0}};
for (long i = 1; i <= n; i++)
for (long j= 1; j <= sum / 2; j++)
if (j-P[i]>=0)
A[i][j] = MAX (A[i-1][j] , A[i-1][j-P[i - 1]] + P[i - 1])
else
A[i][j] = A[i-1][j];
bool hasSolution = (A[n][sum / 2] == sum / 2);
return hasSolution;
}