Php 生成一个介于1和x之间的随机数,其中较低的数字比较高的数字更有可能

Php 生成一个介于1和x之间的随机数,其中较低的数字比较高的数字更有可能,php,math,random,Php,Math,Random,这更像是一个数学/通用编程问题,但我用PHP编程,这会有所不同 我认为最简单的解释方法是举个例子 如果范围在1和10之间 我想生成一个介于1和10之间的数字,但很可能低于高 我能想到的唯一方法是生成一个数组,其中10个元素等于1,9个元素等于2,8个元素等于3…1个元素等于10。然后根据元素的数量生成一个随机数 问题是我可能要处理1-100000个数组,而这个数组会大得离谱 那么如何才能最好地做到这一点呢?生成一个介于1和foo(n)之间的数字,其中foo在n上运行一个算法(例如对数函数)。然后

这更像是一个数学/通用编程问题,但我用PHP编程,这会有所不同

我认为最简单的解释方法是举个例子

如果范围在1和10之间

我想生成一个介于1和10之间的数字,但很可能低于高

我能想到的唯一方法是生成一个数组,其中10个元素等于1,9个元素等于2,8个元素等于3…1个元素等于10。然后根据元素的数量生成一个随机数

问题是我可能要处理1-100000个数组,而这个数组会大得离谱


那么如何才能最好地做到这一点呢?

生成一个介于1和foo(n)之间的数字,其中foo在n上运行一个算法(例如对数函数)。然后在结果上反转foo()

生成编号
n
,这是
0您可以做的

$rand = floor(100000 * (rand(0, 1)*rand(0, 1)));

或者沿着这些线,你需要做的是在更大的间隔(最好是浮点)上生成一个随机数,并以非均匀的方式将其映射到[1,10]。确切的方法取决于你希望1比9或10的可能性更大


有关C语言解决方案,请参阅。你可能会发现它的用处

生成一个介于0和随机数之间的随机数

将均匀密度映射到任何分布函数基本上有两种(或更多?)方法:和。我认为在你的情况下,你应该使用前者。

一般来说,看起来你想从a而不是[uniform distribution]中抽取一个随机数(.在上面引用的wiki页面上,有一节专门说明了如何使用连续分布生成伪泊松分布……请注意,您可能需要测试λ的不同值,以确保分布按您所希望的方式工作。

快速简单:

rand(1, rand(1, n))

这取决于你想要的确切分布,也就是说,什么数字应该以什么概率出现


例如,对于偶数n,您可以执行以下操作:生成一个介于1和n/2之间的整数随机数x,并生成第二个介于1和n+1之间的数。如果y>x,则生成x,否则生成n-x+1。这应该给出示例中的分布。

我认为这应该给出所请求的分布:

在1..x范围内生成一个随机数。在1..x+1范围内生成另一个随机数。
返回二者中的最小值。

让我们考虑一下你的数组想法是如何改变概率的。通常,从1到n的每个元素的概率都是1/n,因此可能性相等

因为1有n个条目,2有n-1个条目…n有1个条目,那么你的条目总数就是一个算术数列。从1到n的算术数列之和是n(1+n)/2。所以现在我们知道每个元素的概率都应该用它作为分母

元素1有n个条目,所以它的概率是n/n(1+n)/2。元素2是n-1/n(1+n)/2…n是1/n(1+n)/2。这给出了一个分子的一般公式,即n+1-i,其中i是你正在检查的数字。这意味着我们现在有一个任意元素的概率函数,即n-i+1/n(1+n)/2.根据定义,所有概率都在0到1之间,总和为1,这是下一步的关键

我们如何使用此函数来扭曲元素出现的次数?使用连续分布(即双倍而不是整数)会更容易,但我们可以做到。首先,让我们制作一个概率数组,将其称为c,并生成它们的运行和(cumsum),然后将其存储回c。如果这没有意义,它就像一个循环


for(j=0; j < n-1; j++)
   if(j) c[j]+=c[j-1]

对于(j=0;j
现在我们有了这个累积分布,生成一个从0到1的数字i(一个双精度,而不是整数。我们可以检查i是否在0和c[0]之间,返回1。如果i在c[1]和c[2]之间,返回2…一直到n。

对于(j=0;j

这将根据您计算的概率分布整数。


<?php 
//get random number between 1 and 10,000
$random = mt_rand(1, 10000); 
?>

@Zano,因为他正在对一个小于1的数字进行平方运算,该数字组位于数字的下端range@murgatroid99:当然,我没有注意到<1。自我提示:在评论时不要和婴儿玩耍,所以回答:不,这不会违背目的。他只是想将均匀密度映射到另一个分布,这是不存在的蒙地卡罗应用程序中的一个常见问题。@OP:你能提供一个分布函数吗?@Woot:你对“随机”的理解是什么?随机变量有一个分布函数。而且分布很少是线性的。他不是“强迫的”但是,任何一个结果。他只是比其他人更容易得出某些结果。这样想:我有一个包,里面有15张牌。五张牌上写着“1”,四张牌上写着“2”,三张“3”,两张“4”,一张“5”。我从包中随机抽取一张牌。结果仍然是随机的,但我得到1(一个低数字)的可能性是五倍因为我要得到一个5(高的数字)。我没有强迫任何结果,但我确实对随机结果进行了更重的加权。或者只是掷一对骰子。你得到7(概率6/36)的可能性是得到1或12(概率1/36)的六倍,但这在一些应用中被认为是随机的。:-)当你掷两个骰子时,不是不可能得到1吗?这是一个很好的简单解决方案…但我发现它有时会得到0。它应该是rand(1,rand(1,n)。谢谢:)但它效率很低。它需要生成两个随机数;@nikic:你在1到n之间生成一个随机数两次,这意味着2log(n)随机性位。对于问题中的分布,这是最优的,因为2log(n)=log(n^2)。这确实会给出下降的概率,但它与qu中提出的算法产生的概率不同
<?php 
//get random number between 1 and 10,000
$random = mt_rand(1, 10000); 
?>