现在我有
return 'Heads' if Math.random() < 0.5
有更好的方法吗?
谢谢
编辑:请忽略返回值,“更好”意味着精确的 50-50 概率。
总有最简单的事情
硬币 = 兰特(1);
在许多脚本语言中,这会给你一个介于 0 和你的 arg 之间的随机整数,因此传递 1 会给你 0 或 1(正面或反面)。
C 中的数字食谱 表示在重要时不要相信内置的随机数生成器。您可能可以将书中所示的算法实现为函数 ran1(),它声称该函数通过了所有已知的随机性统计测试(1992 年),调用次数少于大约 108。
ran1()算法背后的基本思想是向随机数生成器的输出添加洗牌以减少低阶序列相关性。他们使用计算机编程艺术第 2 卷第 3.2-3.3 节中的 Bays-Durham shuffle,但我猜您也可以使用 Fisher-Yates shuffle。
如果您需要更多的随机值,同一文档还提供了一个生成器(ran2),它应该适合至少 1017 值(我的猜测基于 2.3 x 1018 的周期)。它还提供了一个函数(ran3),它使用不同的方法来生成随机数,以防线性同余生成器给您带来某种问题。
您可以将这些功能中的任何一个与您的 < 0.5 test to be more confident that you are getting a uniform distribution.
向 xkcd 致敬:
string getHeadsOrTails {
return "heads"; //chosen by fair coin toss,
//guaranteed to be random
}
你所拥有的就是我会做的方式。 如果 0.0 <= Math.random() < 1.0, as is standard, then (Math.random() < 0.5) is going to give you heads when Math.random() is between 0.0 and 0.4999..., and tails when it's between 0.5 and 0.999... That's as fair a coin flip as you can get.
当然,我假设 Math.random() 有一个很好的实现。
在 Linux 系统上,您可以从 /dev/random 读取位以获得“更好”的随机数据,但是像 Math.Random() 这样的几乎随机的方法几乎适用于您能想到的几乎所有应用程序,除了严肃的密码学工作。
尝试区分奇数和偶数。另外,返回一个枚举值(或布尔值),而不是字符串。
我无法评论人们的帖子,因为我没有声誉,但仅供参考 <= vs. < topic addressed in Bill The Lizard's comment: Because it can be effectively assumed that random is generating any number between 0-1 (which isn't technically the case due to limitations on the size of a floating point number, but is more or less true in practice) there won't be a difference in num <= .5 or num < .5 because the probability of getting any one particular number in any continuous range is 0. IE: P(X=.5) = 0 when X = a random variable between 0 and 1.
这个问题唯一真正的答案是你无法“保证”概率。如果你想一想,真正的硬币抛掷并不能保证 50/50 的概率,这取决于硬币、抛硬币的人,以及硬币是否掉落并滚过地板。 ;)
重点是它“足够随机”。如果您正在模拟抛硬币,那么您发布的代码就非常好。
return 'Heads' if Math.random() * 100 mod 2 = 0
我真的不知道你使用的是什么语言,但如果随机数可以被二整除,那么它是正面,如果不是,那么它是反面。