有趣的。到目前为止,这个 C 程序似乎给出了预期的结果。它首先对数据进行排序,然后对于n 个容器,立即将n 个最高的数字存储在每个容器中。(实际上,您可以省略该步骤。)然后,从最大剩余数字到最小,它找到添加该数字与最佳平均值产生最小差异的容器。因为这是从高到低,每个数字都被放入最佳容器中——所有其他数字都较低,因此它们的差异甚至会更大。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int sort_numeric (const void *a, const void *b)
{
return *((int *)a) - *((int *)b);
}
int main (int argc, char **argv)
{
int list[] = { 10, 30, 503, 23, 1, 85, 355 };
int i,j, nnumber, ncontainer, total, avgPerContainer, nextError, smallestError, containerForSmallest;
int *containers, *errors;
ncontainer = 3;
nnumber = sizeof(list)/sizeof(list[0]);
qsort (list, nnumber, sizeof(list[0]), sort_numeric);
containers = (int *)malloc(ncontainer * sizeof(int));
for (i=0; i<ncontainer; i++)
containers[i] = 0;
errors = (int *)malloc(ncontainer * sizeof(int));
for (i=0; i<ncontainer; i++)
errors[i] = 0;
printf ("input:");
for (i=0; i<nnumber; i++)
{
printf (" %d", list[i]);
}
printf ("\n");
// how much is to be in each container?
total = 0;
for (i=0; i<nnumber; i++)
total += list[i];
// this will result in a fraction:
// avgPerContainer = total/ncontainer;
// so instead we'll use 'total' and *keeping in mind*
// that the number needs to be divided by ncontainer
avgPerContainer = total;
printf ("per container: ~%d\n", (2*avgPerContainer+ncontainer)/(2*ncontainer) );
// start by putting highest values into each container
for (i=0; i<ncontainer; i++)
containers[i] += list[nnumber-ncontainer+i];
// .. remove from list ..
nnumber -= ncontainer;
// print current totals
for (i=0; i<ncontainer; i++)
{
errors[i] = containers[i]*ncontainer - avgPerContainer;
printf ("#%d: %d, error = %d/%d ~ %+d\n", i, containers[i], errors[i], ncontainer, (2*errors[i]+ncontainer)/(2*ncontainer) );
}
printf ("remaining:");
for (i=0; i<nnumber; i++)
{
printf (" %d", list[i]);
}
printf ("\n");
// add the remainders
for (i=nnumber-1; i>=0; i--)
{
smallestError = INT_MAX;
containerForSmallest = 0;
for (j=0; j<ncontainer; j++)
{
nextError = (containers[j] + list[i]) - avgPerContainer;
if (nextError < smallestError)
{
containerForSmallest = j;
smallestError = nextError;
printf ("error for %d, %d + %d, is %+d\n", j, containers[j], list[i], smallestError);
}
}
printf ("we put %d into #%d\n", list[i], containerForSmallest);
containers[containerForSmallest] += list[i];
}
for (i=0; i<ncontainer; i++)
{
printf ("#%d: %d, error = %d/%d ~ %+d\n", i, containers[i], containers[i]*ncontainer - avgPerContainer, ncontainer, (2*(containers[i]*ncontainer - avgPerContainer)+ncontainer)/(2*ncontainer) );
}
return 0;
}