在Java中,我试图以概率p进行操作。 p是我代码中的float变量。我想出了这样做的方法:
if( new Random().nextFloat() < p)
do action
我想确认这是否是正确的做法。
答案 0 :(得分:1)
是。这是正确的(从纯概率的角度来看)。 Random().nextFloat()
会生成0.0
和1.0
之间的号码。因此,只要您的概率为0.0
和1.0
范围内的浮点数,此就是正确的方法。
您可以阅读更多精确的nextFloat()
文档here。
答案 1 :(得分:1)
最后有一个 TL; DR 。
来自nextFloat()
的javadocs(我强调):
<强>
public float nextFloat()
强>返回下一个伪随机数,均匀分布的浮点值 从这个随机数生成器的序列开始,介于0.0和1.0之间。
如果您了解统一分布是什么,了解nextFloat()
对您来说就足够了。然而,我将稍微解释一下均匀分布。
在uniform distribution, 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
}
你所做的几乎是按照你的意图行事的正确方法。只需在<
之后添加等号即可,只要省略等号就不会有太大的伤害!
PS:您不需要每次在条件中创建一个新的Random
对象,您可以创建一个,在循环之前说randObj
,然后调用它nextFloat()
方法,无论何时你想生成一个随机数,就像我在我的代码中所做的那样。
通过pjs查看有关问题的评论,这非常重要且说得好。我引用:
不每次创建一个新的
Random
对象,这不是PRNG的方式 意在使用!单个Random
对象提供一系列值 具有良好的分布特性。创建了多个Random
个对象 快速连续1)计算上昂贵,2)可能有 高度相关的初始状态,从而产生高度相关 结果。创建单个实例时,Random
实际上效果最佳 每个程序并继续使用它,除非你真的知道 您正在做什么,并有使用相关性的具体原因 诱导策略。
你所做的是几乎正确的做法。只需在<
之后添加等号(使其成为<=
)就可以了,只要省略等号就不会有太大的伤害!