Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/251.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中创建一个指定数量的随机值,这些值都等于一个指定的数字?_Php_Random - Fatal编程技术网

如何在PHP中创建一个指定数量的随机值,这些值都等于一个指定的数字?

如何在PHP中创建一个指定数量的随机值,这些值都等于一个指定的数字?,php,random,Php,Random,例如,假设我输入'10'作为值的数量,输入'10000'作为总数 脚本将需要随机分配10个不同的数字,所有这些数字都等于10000。不多也不少 但它也需要是动态的。如中所示,有时我可能会输入'5'或'6'甚至'99'作为值的数量,输入任何数字(最多10亿或更高)作为总数 我该怎么做呢 编辑:我还应该提到,所有数字都必须是正整数 更新:@joeblow有一个完美的答案。我的答案有一个特殊的特点,就是生成大小大致相同(或者至少相差不超过(10000/10))的块,并将其保留在适当的位置 我想到的最简

例如,假设我输入'10'作为值的数量,输入'10000'作为总数

脚本将需要随机分配10个不同的数字,所有这些数字都等于10000。不多也不少

但它也需要是动态的。如中所示,有时我可能会输入'5'或'6'甚至'99'作为值的数量,输入任何数字(最多10亿或更高)作为总数

我该怎么做呢

编辑:我还应该提到,所有数字都必须是正整数

更新:@joeblow有一个完美的答案。我的答案有一个特殊的特点,就是生成大小大致相同(或者至少相差不超过(10000/10))的块,并将其保留在适当的位置

我想到的最简单、最快的方法是:

  • 将10000除以10,并将值存储在数组中。(10倍于值
    10000

  • for
    循环中遍历10个元素中的每一个

  • 从每个元素中减去(10000/10)之间的随机数

  • 将该数字添加到以下元素中

这将为您提供一些随机值,当添加这些值时,将产生最终值(忽略浮点问题)

应该是容易实现的一半


不过,您将在某个时候达到PHP的最大整数限制。不确定这能在多大程度上用于10亿及以上的数值。

可能是这样的:

将最大剩余金额设置为目标数量

循环1到所需的值数-1

获取一个从0到最大剩余量的随机数

将新的最大剩余金额设置为旧的最大剩余金额减去当前随机数

重复循环


您将得到一个“余数”,因此最后一个数字由剩余的数字决定,以构成原始总数。

生成10个随机数,直到10000个。 从大到小排序:g0到g9

g0 = 10000 - r0
g1 = r0 - r1
...
g8 = r8 - r9
g9 = r9

这将在整个范围内产生10个随机数,总计10000个。

这里的正确答案非常简单

想象一条白线,比如说1000个单位长

您希望使用红色标记将线分成十部分

非常简单,选择九个随机数,在每个点上画一个红色标记

就这么简单。你完了

因此,算法是:

(1) 选择9个介于0和1000之间的随机数 (2) 将九个数字、一个零和一个1000放入一个数组中 (3) 对数组进行排序 (4) 使用减法获得数组值之间的十个“距离”

你完了

(显然,如果您想在最后一个集合中没有零,在第(1)部分中,如果发生冲突,只需重新选择另一个随机数。)

理想情况下,作为程序员,我们可以在头脑中“看到”这样的可视化算法——无论我们做什么,都要尝试进行可视化思考


脚注-对于任何阅读本文的非程序员,请注意,这就像“学习计算机科学时你学到的第一件事!”也就是说,我没有得到任何学分,我只是在页面上无意中输入了答案。我没有荣誉

记录在案的是,另一种常见的方法(取决于期望的结果,无论你是处理实数还是整数,以及其他限制)也非常“啊哈!”优雅。你要做的就是:得到10个随机数。把它们加起来。非常简单,只是:将它们全部乘以或除以某个数字,这样,总数就是所需的总数!就这么简单

相关:

看这个。它附带了一个文件,其中包含实现背后的理论


该函数生成随机、均匀分布的向量x=[x1,x2,x3,…,xn]',这些向量有一个指定的和s,我们有一个我相信@JoeBlow提供的答案基本上是正确的,但前提是所需的“随机性”需要均匀分布。在对该答案的评论中,@Artefactor说:

It may be simple but it does not generate uniformly distributed numbers... 
Itis biased in favor of numbers of size 1000/10 (for a sum of 1000 and 10 numbers).
这就引出了前面提到的关于这些数字的理想分布的问题。JoeBlow的方法确实确保元素1和元素2有相同的机会成为数字x,这意味着它必须偏向大小为Max/n的数字。在这个问题上,OP是希望更可能的射击接近最大值的单个元素,还是希望均匀分布还不清楚。[抱歉-从术语角度看,我不确定这是否构成“统一分布”,因此我仅以外行的术语提及]

总之,说元素的“随机”列表必然是均匀分布的是不正确的。如上文其他评论所述,缺少的元素是所需的分布

为了证明这一点,我提出了以下解决方案,其中包含随机分布模式的顺序随机数。如果第一个元素在0-N之间的任何数字上有相等的机会,并且每个后续数字在0-[剩余总数]之间的任何数字上有相等的机会,则此解决方案将非常有用:

[Pseudo code]:
Create Array of size N
Create Integer of size Max
Loop through each element of N Except the last one
    N(i) = RandomBetween (0, Max)
    Max = Max - N(i)
End Loop
N(N) = Max

可能有必要在创建这些元素后,根据它们的使用方式将其顺序随机化[否则,每个元素的平均大小会随着每次迭代而减小]。

我想我知道你的意思,但我不确定。我将在此基础上尝试一些事情,并向您汇报。同时,任何额外的帮助都将不胜感激。@Joe Blow well,这或多或少就是这些步骤所做的-它们提供的块大小彼此之间的偏差不会超过(10000/10)。通过减少调用随机数发生器时的限制,可以使块的大小越来越相似。但这不是OP所要求的,所以微调这是另一天的问题@
[Pseudo code]:
Create Array of size N
Create Integer of size Max
Loop through each element of N Except the last one
    N(i) = RandomBetween (0, Max)
    Max = Max - N(i)
End Loop
N(N) = Max