这更像是一个数学/通用编程问题,但我使用PHP进行编程是有所作为的。
我认为最简单的解释方法是举例。
如果范围在1到10之间。
我想生成一个介于1和10之间的数字,但更可能低于高。
我能想到的唯一方法是生成一个数组,其中10个元素等于1,9个元素等于2,8个元素等于3 ..... 1元素等于10.然后生成一个基于的随机数元素数量。
问题是我可能会处理1 - 100000并且该数组会非常大。
那么如何做到最好?
答案 0 :(得分:25)
生成0到随机数之间的随机数!
答案 1 :(得分:11)
生成1和foo(n)之间的数字,其中foo在n上运行算法(例如,对数函数)。然后在结果上反转foo()。
答案 2 :(得分:4)
生成n
的数字0 <= n < 1
,将其自身乘以,乘以x
,在其上运行并添加1.抱歉我用了很久以前的php来编写代码在其中
答案 3 :(得分:3)
你可以做到
$rand = floor(100000 * (rand(0, 1)*rand(0, 1)));
或者沿着这些方向的东西
答案 4 :(得分:3)
基本上有两种(或更多?)方法可以将统一密度映射到任何分布函数:Inverse transformation sampling和Rejection sampling。我认为在你的情况下你应该使用前者。
答案 5 :(得分:3)
快速而简单:
rand(1, rand(1, n))
答案 6 :(得分:2)
我认为这可能是您正在寻找的:
答案 7 :(得分:0)
您需要做的是在更大的间隔(最好是浮点)上生成一个随机数,并以不均匀的方式将其映射到[1,10]。究竟是什么方式取决于如何您希望1比9或10更有可能。
对于C语言解决方案,请参阅these libraries。您可以找到this in PHP的用途。
答案 8 :(得分:0)
一般来说,看起来你想从Poisson distribution而不是[均匀分布](http://en.wikipedia.org/wiki/Uniform_distribution_(continuous))中抽取一个随机数。在上面引用的维基页面上有一节特别说明如何使用连续分布生成伪泊松分布... check it out。请注意,您可能希望测试不同的λ值,以确保分布按您的意愿工作。
答案 9 :(得分:0)
这取决于您想要具有什么样的分布,即,应该以什么概率出现的数字。
例如,对于偶数n,您可以执行以下操作:在1和n / 2之间生成一个整数随机数x,并生成介于1和n + 1之间的第二个数字。如果y> x你生成x,否则你生成n-x + 1。这应该为您提供示例中的分发。
答案 10 :(得分:0)
我认为这应该提供所要求的分发:
生成1 .. x范围内的随机数。生成1 .. x + 1范围内的另一个。 返回两者中的最小值。
答案 11 :(得分:0)
让我们考虑一下你的数组想法如何改变概率。通常,从1到n的每个元素具有1 / n的概率,因此具有相同的可能性。
由于n有1个n-1个条目,n ... 1条目为2 ... 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]
现在我们有了这个累积分布,生成一个从0到1的数字i(一个double,而不是一个int。我们可以检查我是否介于0和c [0]之间,如果i介于c [0]之间,则返回1. 1]和c [2]返回2 ...一直到neg
for(j=0; j < n=1;j++)
if(i %lt;= c[j]) return i+1
这将根据您计算的概率分配整数。
答案 12 :(得分:-1)
<?php
//get random number between 1 and 10,000
$random = mt_rand(1, 10000);
?>