如果您需要将 100 除以 2,最大距离为 N,则组合中的最小值为
100 / 2 - N / 2
如果您需要将 100 除以 3 个最大距离为 N 的值,这将变得更加棘手。 3个值的平均值将是100/3,但是如果其中一个值远低于这个平均值,那么另一个值只能比这个平均值稍大,这意味着最小值不是平均值减去最大距离除以两个,但可能
100 / 3 - 2N / 3
一般有 M 值,这就变成了
100 / M - (M-1)N / M
可以简化为
(100 - (M-1)N) / M
同样我们可以计算出可能的最高值:
(100 + (M-1)N) / M
这为您提供了组合的第一个值的范围。
要确定第二个值的范围,您必须考虑以下约束:
- 第一个值的距离(不应高于您的最大距离)
- 我们还能达到总和 (100)
第一个约束不是问题。第二个是。
假设我们使用 10 的倍数将 100 除以 3,最大距离为 30
如前所述,最小值为:
(100 - (3-1)30) / 3 --> 13 --> 舍入到 10 的下一个倍数 --> 20
最大值为
(100 + (3-1)30) / 3 --> 53 --> 四舍五入到前一个 10 的倍数 --> 50
所以对于第一个值,我们应该迭代 20、30、40 和 50。
假设我们选择 20。剩下 80 用于其他 2 个值。
同样,我们可以将 80 分布在 2 个值上,最大距离为 30,这给出:
最小值:(80 - (2-1)30) / 2 --> 25 --> 四舍五入 --> 30
最大值:(80 + (2-1)30) / 2 --> 55 --> 四舍五入 --> 50
第二个约束是我们不希望与第一个值相比距离大于 30。这给出了最小值 -10 和最大值 50。
现在取两个域之间的交集 --> 30 到 50,第二个值迭代 30、40、50。
然后对下一个值重复此操作。
编辑:
我在伪代码中添加了算法以使其更清晰:
calculateRange (vector, remainingsum, nofremainingvalues, multiple, maxdistance)
{
if (remaingsum==0)
{
// at this moment the nofremainingvalues should be zero as well
// found a solution
print vector
return;
}
minvalueaccordingdistribution = (remainingsum-(nofremainingvalues-1)*maxdistance)/nofremaingvalues;
maxvalueaccordingdistribution = (remainingsum+(nofremainingvalues-1)*maxdistance)/nofremaingvalues;
minvalueaccordingdistance = max(values in vector) - maxdistance;
maxvalueaccordingdistance = min(values in vector) + maxdistance;
minvalue = min (minvalueaccordingdistribution, minvalueaccordingdistance);
maxvalue = max (minvalueaccordingdistribution, minvalueaccordingdistance);
for (value=minvalue;value<=maxvalue;value+=multiple)
{
calculaterange (vector + value, remainingsum - value, nofremainingvalues-1, multiple, maxdistance);
}
}
main()
{
calculaterange (emptyvector, 100, 2, 20);
}