java随机百分比

erw*_*erw 18 java random algorithm math

我需要生成n个百分比(0到100之间的整数),使得所有n个数字的总和加起来为100.

如果我只做了nextInt() n次,每次确保参数是100减去先前累积的总和,那么我的百分比是有偏差的(即第一个生成的数字通常是最大的等等).我如何以无偏见的方式做到这一点?

小智 12

一些答案建议选择随机百分比并采用它们之间的差异.正如Nikita Ryback所指出的那样,这不会给所有可能性带来均匀分布; 特别是,零比预期的频率低.

要解决这个问题,请考虑从100'百分比开始并插入分隔线.我将用10示例:

 % % % % % % % % % % 

我们可以在11个地方插入一个分隔符:在任意两个百分点之间或者在开头或结尾处.所以插入一个:

 % % % % / % % % % % % 

这表示选择四个和六个.现在插入另一个分隔符.这一次,有十二个地方,因为已经插入的分隔符创建了额外的一个.特别是,有两种方法可以获得

 % % % % / / % % % % % % 

在前一个分隔符之前或之后插入.您可以继续此过程,直到您拥有所需数量的分频器(比百分数少一个).

 % % / % / % / / % % % / % % % / 

这相当于2,1,1,0,3,3,0.

我们可以证明这给出了均匀分布.100到k部分的组成数是二项式系数100 + k-1选择k-1.那是(100 + k-1)(100 + k-2) ...... 101 /(k-1)(k-2)*...*2*1因此,选择任何特定成分的概率是这个的倒数.当我们一次插入一个分频器时,首先我们选择101个位置,然后选择102,103等,直到我们达到100 + k-1.因此任何特定插入序列的概率为1 /(100 + k-1)*...*101.多少插入序列产生相同的组合物?最终的组合物含有k-1分隔物.它们可以按任何顺序插入,所以有(k-1)!产生给定组成的序列.所以任何特定成分的概率都应该是它应该是的.

在实际代码中,您可能不会代表这样的步骤.你应该能够坚持数字,而不是百分比和分频器的序列.我没有想过这个算法的复杂性.


ata*_*lor 7

生成任意范围的n个随机整数(称之为a[1].. a[n]).总结你的整数并称之为b.你的百分比是[a[1]/b, ..., a[n]/b].

编辑:好点,将结果四舍五入到正好100是非繁琐的.一种方法是采取的地板a[x]/b用于x1..n为你的整数,然后分发耳提面命单位100-(sum of integers)随机.我不确定这是否会对结果产生任何偏见.

  • @Ben那个修补工具会使分配不均匀(某些组合会比其他组合更频繁地发生).但我同意,如果"任何范围"足够大,它就会非常接近. (2认同)

mik*_*era 6

您可能需要通过"偏见"来定义您的真正含义 - 但如果您关心的是数字的分布与其位置无关,那么您可以简单地以"偏向"的方式创建数字,然后将它们随机化位置.

另一种"无偏见"的方法是创建n-1个随机百分比,对它们进行排序(称为x1 x2 x3 ...),然后将最终的百分比定义为:

x1
x2 - x1
x3 - x2
...
100 - x(n-1)
Run Code Online (Sandbox Code Playgroud)

这样你就会得到n个随机数加100.

  • @Moron为什么我们要通过一个随机调用限制自己?我提到的问题(你正在争论,对吗?)是因为他没有正确生成多重集合:生成(1,2)多重集合将有两条"路径"(来自序列[1,2]]和[2,1]只有一种方式(1,1).所以,第一种方法的概率是原来的两倍. (2认同)

dre*_*ves 5

这个问题被称为单纯形式的统一抽样,维基百科给出了两种算法:

http://en.wikipedia.org/wiki/Simplex#Random_sampling

另见这些相关问题:


Ben*_*n S 0

使用您描述的方法选择数字后,请打乱数字的顺序。这样,最终的数字列表就会有更均匀的分布。

但是,请注意,无论您做什么,都无法获得完美均匀的分布,因为一旦您开始选择数字,您的随机试验就不是独立的。参见阿泰勒的回答。

另请注意,您描述的算法可能无法为您提供所需的输出。最后一个数字不能是随机的,因为它必须使总和等于 100。