简体   繁体   English

java中生成特定随机数的概率

[英]Probability of generating a specific random number in java

If I have a random number generator that generates numbers 0-1, is there a way that I can increase the probability of it generating certain numbers?如果我有一个生成数字 0-1 的随机数生成器,有没有办法增加它生成某些数字的概率? Say that the values .5+ on the random number generator are equal to the color blue and numbers lower are equal to red.假设随机数生成器上的值 0.5+ 等于蓝色,而较低的数字等于红色。 Can I make it so that the user can enter a number as a percentage in order to increase/decrease the likelihood of generating the color red?我可以让用户输入一个百分比的数字,以增加/减少生成红色的可能性吗?

From your question it sounds like you're working with Math.random() .从您的问题来看,您似乎正在使用Math.random()

Stop doing that;别那样做; modifying the 0-1 range to a uniform selection of limited choices, for example by:将 0-1 范围修改为有限选择的统一选择,例如:

int fairDie = 1 + (int) (Math.random() * 6)

Because that is not truly fair.因为这并不真正公平。

Instead, use this:相反,使用这个:

Random r = new Random(); // do this only once for the app.
int fairDie = 1 + r.nextInt(6);

The above is truly fair.以上确实公平的。

If you want to pick from a limited selection and want some in the selection to occur more often, the simplest way is to make a list of the choices, duplicating entries as much as you need to get to the right odds.如果您想从有限的选择中进行选择并希望选择中的一些更频繁地出现,最简单的方法是列出选择,尽可能多地重复条目以获得正确的赔率。 For example, if the choices are red, green, and blue, and they are to be chosen in a 1:2:3 arrangement, try:例如,如果选项是红色、绿色和蓝色,并且要以 1:2:3 的排列选择它们,请尝试:

List<String> colors = new ArrayList<String>(List.of("red", "green", "green", "blue", "blue", "blue"));
Collections.shuffle(colors);
System.out.println("Chosen: " + colors.get(0));

This uses shuffle, which under the hood uses the proper kind of random (it's fair and uniform).这使用了 shuffle,它在幕后使用了适当的随机类型(它是公平和统一的)。 Another option is to simply create ranges: [0-1) is red, [1, 3) is green, [3, 6) is blue, and then rnd.nextInt(6) .另一种选择是简单地创建范围:[0-1) 是红色,[1, 3) 是绿色,[3, 6) 是蓝色,然后是rnd.nextInt(6)

wait, why is that 'unfair'?等等,为什么这“不公平”?

We can prove this with the pigeon hole principle.我们可以用鸽巢原理来证明这一点。

Math.random() returns a double. Math.random()返回一个双Math.random()值。 A computer is not magical;计算机并不神奇; doubles are represented by 64 bits, and because math, that can represent at most 2^64 different numbers. doubles 由 64 位表示,并且由于数学原因,它最多可以表示2^64不同的数字。 That's a lot of numbers, but it gets down to a little less because doubles can also represent numbers outside of the 0-1 range, but Math.random() will never return them.这是很多数字,但它会减少一点,因为双打也可以表示 0-1 范围之外的数字,但Math.random()永远不会返回它们。

The key is, there is a limited amount of numbers that Math.random() could possibly return.关键是, Math.random()可能返回的数字数量有限。 It's a very large number to be sure, but limited.可以肯定的是,这是一个非常大的数字,但数量有限。 Let's say it's 1239235915810453815 different options.假设有 1239235915810453815 个不同的选项。

And you want to fairly choose from between 6 options, uniformly.并且您希望从 6 个选项中公平地进行选择,统一。

The problem is, 6 does not evenly divide into 1239235915810453815. That means it is impossible to do this fairly.问题是,6 并没有平均分成 1239235915810453815。这意味着不可能公平地做到这一点。 Imagine that Math.random() returns 9 different numbers, and you're using this to roll a fair die.想象一下Math.random()返回 9 个不同的数字,并且您正在使用它来掷骰子。 Well, 6 of those 9 go for 1-6 on the die, and the remaining 3 go to.. what?嗯,这 9 个中的 6 个在骰子上投 1-6 分,剩下的 3 个投向……什么? 2, 4, and 6? 2、4 和 6? Now 2/4/6 are twice as likely as 1/3/5.现在 2/4/6 的可能性是 1/3/5 的两倍。 You can't get to a fair result.你不能得到一个公平的结果。

rnd.nextInt(5) addresses this and guarantees fairness, which is why you should use it. rnd.nextInt(5)解决了这个问题并保证了公平性,这就是你应该使用它的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM