【问题标题】:How do you generate a random number with equal probability using Math.random() in Java [duplicate]如何在 Java 中使用 Math.random() 生成具有相等概率的随机数 [重复]
【发布时间】:2013-10-28 06:13:39
【问题描述】:

我目前正在进行一项练习,我需要生成一个随机数,该随机数可以是 4 个值之一。 (注意我只能使用 Math.random())

0 1 2 或 3

目前我正在使用这个:randno = (int) (Math.random()*4); // range 0-3

但是,结果必须具有相同的概率。到目前为止,我的测试(尽管缺少该方法)表明 3 的出现次数远远少于其他数字。

这是巧合吗?还是我的生成器的概率不相等。

谢谢!

【问题讨论】:

  • 您参加了多少次测试?应该是一样的。
  • @felixfritz 练习的测试方法不是很好。它的工作方式是分配一个方向,3 向前,2 向后。我将它设置在走廊中,它似乎向后退(又名 2 生成)远远超过它前进(3)。不过这可能是巧合,所以我的方法对吗?
  • @weston 这并不是真正的重复,只是关于数字出现频率的问题。

标签: java random numbers equals probability


【解决方案1】:

使用随机数,您可以随机获取看似非随机的内容。不能保证所有序列都是随机的。 http://vanillajava.blogspot.com/2011/10/randomly-no-so-random.html

对于正确的随机种子,您可能会得到一个非随机序列,但这些与其他任何序列一样可能。

Random random = new Random(441287210);
for (int i = 0; i < 10; i++)
    System.out.print(random.nextInt(10)+" ");
}

打印

1 1 1 1 1 1 1 1 1 1

Random random = new Random(-6732303926L);
for(int i = 0; i < 10; i++)
    System.out.println(random.nextInt(10)+" ");
}

打印

0 1 2 3 4 5 6 7 8 9

最后

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();
}

打印

hello world

【讨论】:

    【解决方案2】:

    为了进行比较,我将您的方法放在this 旁边。

    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);
                }
            }
        }
    

    输出:

    选项一:
    0 199853
    1 200118
    2 200136
    3 199893

    选项二:
    0 199857
    1 200214
    2 199488
    3 200441

    结论:你的方法有效。也许您的样本量不够?

    【讨论】:

    • 我建议你使用 400k 或 800k 以获得更清晰的结果(又名 0000)
    • @MaximShoustin:好主意,改了。
    【解决方案3】:

    您的代码运行良好:

       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);
    
    
        }
    

    输出:

    Zero: 99683
    One: 99793
    Two: 100386
    Three: 100138
    

    【讨论】:

    • 你可以用一组计数器减少很多:)
    • 太棒了,只是想确定一下!感谢您的帮助。
    • @sje397 你的意思是“array[randno]++”?
    • @felixfritz 是的,然后循环打印它们
    猜你喜欢
    • 2013-07-10
    • 2017-10-01
    • 2012-02-11
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 2015-10-16
    • 2011-03-07
    相关资源
    最近更新 更多