在C中,如何获得 n 数字的数组(在我的情况下每个0x00-0xFF),其中总和在给定范围内0..k
?
几乎重复C++ multiple random numbers adding up to equal a certain number以特定金额为目标,但就我而言,总和可以是0..k
之间的任何值。
答案 0 :(得分:4)
您需要指定随机数的期望分布。
如果没有其他要求,我会建议以下之一:
(1)
如果您在随机数范围内有 m 的上限,请使用 min(ka [1] -... m)作为间隔的上限
缺点:你会得到很多小数字,只有几个大数字。
(2)
缺点:不太可能以这种方式获得大数字。如果需要整数,由于舍入误差,数字之和与 k 之间可能存在差距。
我认为您可以通过选项(2)获得“更好”的数字,但如上所述,它取决于要求。
答案 1 :(得分:3)
假设k
小于255 * n
,一个解决方案是将k / n
分配给数组的每个元素,然后随机地将值减去数组元素。
// for (int i = 0; i < n; i++) array[i] = k / n;
// for (int i = 0; i < n; i++) array[i] -= randbetween(0, array[i]);
for (int i = 0; i < n; i++) array[i] = randbetween(0, k / n);
预计总和为k / 2
。通过调整randbetween()
函数,您可以更改结果数组求和的概率。
答案 2 :(得分:1)
在范围[0, 255]
范围内创建一个数字很容易。
很容易确定k > 255*n
或k < 0
是否没有解决方案。
如果0 <= k <= 255*n
,则解决方案存在。在这里,我们只讨论n > 1
条件。
您已创建n-1
个随机数,n-1
个数字的总和为s1
,假设第n个数字为x
。因此s1 + x = k
和x应为[0, 255]
。 如果n-1
号码都在[0, a]
范围内,然后(n-1)*a + 255 >= k
,我们会获得a >= (k-255)/(n-1)
。
如果k > 255
,请让a = (k-255)/(n-1)
。这意味着s1
是[0, k-255]
。然后第n个x
可以是[0, 255]
中的任意随机数。
因此,解决方案是n-1
内的任意选择[0, (k-255)/(n-1)]
数字(您知道(k-255)/(n-1) <= 255
,因此它满足您的条件),并在[0, 255]
中选择一个随机数。
如果k <= 255
,n
内任意选择[0, k/n]
个数字(您知道k/n
在[0,255]内)。