正态分布的随机整数?
有没有一种很好的方法来获得随机生成的正态分布整数?
我想到的第一个方法是:
int rndi = (int)Math.floor(random.nextGaussian()*std);
有没有更好的方法?
Is there a nice way to get randomly generated integers with normal distribution?
The first method which come to my mind:
int rndi = (int)Math.floor(random.nextGaussian()*std);
Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
严格来说,你不可能有正态分布的整数。也许您想要的是按桶分类的正态分布的输出。在这种情况下,您可能希望根据数组的大小来移动和缩放正态分布。如果您仅从标准正态分布(均值 = 0 且小数位数 = 1)中获取样本,则大约 99% 的情况下您将获得 -2 到 2 之间的样本。
假设您想要从大小为 N 的数组中随机采样。您希望中间的条目比末尾的样本更频繁地被选择,但您希望靠近末端的样本偶尔出现,比如 1% 的时间。然后你可能想要计算类似 N/2 + N*z/4 的东西,其中 z 是你的标准法线,然后将这些数字转换为整数。如果这样做,您偶尔会得到数组外部的索引。只需测试一下,并在发生这种情况时获得新值。
Strictly speaking, you can't have normally distributed integers. Maybe what you want is the output of a normal distribution sorted into buckets. In that case, you probably want to shift and scale your normal distribution according to the size of your array. If you just take samples from a standard normal distribution (mean = 0 and scale = 1), you'll get samples between -2 and 2 around 99% of the time.
Suppose you want random samples from an array of size N. You want the entries in the middle to be chosen more often than the samples at the end, but you want the samples near the ends to come up occasionally, say 1% of the time. Then you may want to compute something like N/2 + N*z/4 where z is your standard normal then cast those numbers to an integer. If you do this, you'll occasionally get an index outside your array. Just test for that and get a new value when that happens.
您应该更新问题以明确您的用例到底是什么。
根据您的评论,您根本不应该使用正态分布。相反,请尝试许多离散分布之一,因为您希望末尾有整数。有很多,但我推荐一个 - 非常简单。它使用随机向量作为离散概率分布。
这是示例实现:
You should update the question to make clear what's exactly your use case.
According to your comment, you shouldn't be using normal distribution at all. Instead try one of many discrete distributions, since you want integers at the end. There are a lot of those, but I'd recommend one - very simple. It uses stochastic vector as the discrete probability distribution.
Here's example implementation:
这取决于您尝试如何处理这些随机数。
java.util.Random
有一些缺陷。如 JavaDoc 中所述,nextGaussian()
方法使用 Box Muller 变换。它取决于使用线性同余生成器实现的Random.nextDouble()
。正如错误修复提案中所述,该实现并不是最好的:因此,如果您对高统计质量感兴趣,您确实应该避免使用Sun 的实现。看看这个“不是那么随机”小程序,直观地证明它有多糟糕。
如果您关心统计质量,您能做的最好的事情就是使用一些外部 PRNG 库。
That depends on what you are trying to do with those random numbers.
The
java.util.Random
has some flaws. As stated in JavaDoc, thenextGaussian()
method uses Box Muller Transform. It depends onRandom.nextDouble()
which is implemented using Linear Congruential generator. And the implementation is not the best one, as stated in a bugfix proposal:So if you are interested in high statistical quality you should really avoid Sun's implementation. Take a look at this "Not so random" applet for visual proof of how bad it is.
If statistical quality is a concern to You, the best you can do is use some external PRNG library.
您可以预先计算“随机”整数列表,然后手动调整该列表以获得您想要的分布。
然后,当您想要一个“随机”数字时,只需从列表中提取下一个可用的数字...
这样您就可以确保分布,从而确保选择特定项目的概率。为了好玩,您可以在需要时“混合”您的列表。
You can precompute a list of "random" integers, then hand tweak that list to get the distribution you want.
Then when you want a "random" number, just pull the next available one from the list...
This way you ensure the distribution and therefore the probability of a particular item being selected. For fun, you can just "mix up" your list whenever you need.