在Java中,我试图以概率p执行一个动作。 p 是我的代码中的浮点变量。我想出了这种方法:
if( new Random().nextFloat() < p)
do action
我想确认这是否是正确的做法。
最后有一个TL;DR。
nextFloat()
的javadocs(我强调):
public float nextFloat()
返回下一个伪随机数,均匀分布浮点值 来自此随机数生成器序列的 0.0 和 1.0 之间。
如果您了解什么是均匀分布,那么了解
nextFloat()
对您来说就足够了。不过我要解释一下均匀分布。
在均匀分布中,U(a,b)区间[a,b]中的每个数字,以及[a,b]内相同长度的所有子区间都是等概率的,即它们具有相同的概率。
图中,左边是PDF,右边是均匀分布的CDF。
对于均匀分布,从分布中得到小于或等于n的数P(x<= n))的概率等于该数本身(看右图,这是均匀分布的累积分布函数)。是, P(x <= 0.5) = 0.5, P(x <= 0.9) = 0.9)。您可以从任何优秀的统计书籍或谷歌搜索中了解有关均匀分布的更多信息。
现在,使用
nextFloat()
生成的数字小于或等于 p 的概率等于 p,因为 nextFloat()
返回均匀分布的数字。因此,要使某个动作以等于 p 的概率发生,您所要做的就是:
if (condition that is true with a probability p) {
do action
}
从关于
nextFloat()
和均匀分布的讨论来看,结果是:
if(randObj.nextFloat() <= p) {
do action
}
P.S.:您不需要每次在条件中创建一个新的
Random
对象,您可以在循环之前创建一个新的 randObj
对象,然后在您想要生成随机数时调用其 nextFloat()
方法数字,正如我在代码中所做的那样。
看一下pjs对这个问题的评论,非常重要,说得很好。我引用:
不要每次都创建一个新的
Random
对象,PRNG 不是这样的 本来就是用来用的!单个Random
对象提供一系列值 具有良好的分布特性。创建了多个Random
对象 快速连续的情况是:1)计算量大,2)可能有 高度相关的初始状态,从而产生高度相关的 结果。Random
实际上,当您创建单个实例时效果最佳 每个程序并不断从中吸取教训,除非你真的真的知道 您正在做什么以及使用相关性的具体原因 诱导策略。
几乎正确的做法。只需在 <
之后添加等号(使其成为
<=
)就足够了,省略等号也没什么坏处!
Random().nextFloat()
将生成一个介于
0.0
和
1.0
之间的数字(不包括)。 因此,只要您的概率是在
0.0
和
1.0
范围内的浮点数,这is 就是正确的做法。 您可以在
此处阅读更多确切的
nextFloat()
文档。