问题
I'm currently working through an exercise where I am required to generate a random number which can be one of 4 values. (note I'm only allowed to use Math.random())
0 1 2 or 3
Currently I am using this: randno = (int) (Math.random()*4); // range 0-3
However, the outcome MUST have equal probability. My tests so far (although the method is lacking) shows that 3 occurs far less than the other numbers.
Is this coincidence? Or does my generator not have equal probability.
Thanks!
回答1:
Your code works well:
public static void main(String[] args) {
int countZero = 0;
int countOne = 0;
int countTwo = 0;
int countThree = 0;
for(int i=0; i<400000; i++){
int randno = (int)(Math.random() * ((3) + 1));
if(randno == 0){
countZero++;
}
else if(randno == 1){
countOne++;
}
else if(randno == 2){
countTwo++;
}
else if(randno == 3){
countThree++;
}
}
System.out.println("Zero: " + countZero);
System.out.println("One: " + countOne);
System.out.println("Two: " + countTwo);
System.out.println("Three: " + countThree);
}
Output:
Zero: 99683
One: 99793
Two: 100386
Three: 100138
回答2:
Just to make the comparison, I've put your approach next to this one.
public class Test {
private static int min = 0;
private static int max = 3;
private static Map<Integer, Integer> count = new HashMap<>();
public static void main(String[] args) {
OptionOne();
System.out.println("Option One: ");
for (Entry<Integer, Integer> entry : count.entrySet()) {
System.out.println(entry.getKey() + "\t " + entry.getValue());
}
count = new HashMap<Integer, Integer>();
OptionTwo();
System.out.println("\nOption Two:");
for (Entry<Integer, Integer> entry : count.entrySet()) {
System.out.println(entry.getKey() + "\t " + entry.getValue());
}
}
private static void OptionOne() {
for (int i = 0; i < 800000; i++) {
int number = min + (int) (Math.random() * ((max - min) + 1));
if (count.containsKey(number)) {
int sofar = count.get(number) + 1;
count.put(number, sofar);
} else {
count.put(number, 1);
}
}
}
private static void OptionTwo() {
for (int i = 0; i < 800000; i++) {
int number = (int) (Math.random() * 4);
if (count.containsKey(number)) {
int sofar = count.get(number) + 1;
count.put(number, sofar);
} else {
count.put(number, 1);
}
}
}
Output:
Option One:
0 199853
1 200118
2 200136
3 199893Option Two:
0 199857
1 200214
2 199488
3 200441
Conclusion: your method works. Maybe your sample size wasn't enough?
回答3:
With random numbers, you can random get what appears to be non random. There is no guarantee that all sequences appear random. http://vanillajava.blogspot.com/2011/10/randomly-no-so-random.html
For the right random seed you can appear to get a non-random sequence, but these are just as likely as any other.
Random random = new Random(441287210);
for (int i = 0; i < 10; i++)
System.out.print(random.nextInt(10)+" ");
}
prints
1 1 1 1 1 1 1 1 1 1
and
Random random = new Random(-6732303926L);
for(int i = 0; i < 10; i++)
System.out.println(random.nextInt(10)+" ");
}
prints
0 1 2 3 4 5 6 7 8 9
Lastly
public static void main(String ... args) {
System.out.println(randomString(-229985452)+' '+randomString(-147909649));
}
public static String randomString(int seed) {
Random rand = new Random(seed);
StringBuilder sb = new StringBuilder();
for (int i = 0; ; i++) {
int n = rand.nextInt(27);
if (n == 0) break;
sb.append((char) ('`' + n));
}
return sb.toString();
}
prints
hello world
来源:https://stackoverflow.com/questions/19465963/how-do-you-generate-a-random-number-with-equal-probability-using-math-random-i