【问题标题】:Get random boolean in Java在Java中获取随机布尔值
【发布时间】:2012-07-13 04:05:35
【问题描述】:

好的,我在我的代码中实现了这个 SO 问题:Return True or False Randomly

但是,我有一个奇怪的行为:我需要同时运行十个实例,每个实例每次运行只返回一次 true 或 false。令人惊讶的是,无论我做什么,每次我得到的只是false

有什么可以改进的方法,所以我至少有大约 50% 的机会获得true


为了更容易理解:我将我的应用程序构建为 JAR 文件,然后通过批处理命令运行

 java -jar my-program.jar
 pause

程序的内容 - 使其尽可能简单:

public class myProgram{

    public static boolean getRandomBoolean() {
        return Math.random() < 0.5;
        // I tried another approaches here, still the same result
    }

    public static void main(String[] args) {
        System.out.println(getRandomBoolean());  
    }
}

如果我打开 10 个命令行并运行它,我每次都会得到false 的结果...

【问题讨论】:

  • 为什么不使用Random r = new Random(); r.nextBoolean();

标签: java random boolean


【解决方案1】:

我推荐使用Random.nextBoolean()

话虽如此,Math.random() &lt; 0.5 你也用过。这是我机器上的行为:

$ cat myProgram.java 
public class myProgram{

   public static boolean getRandomBoolean() {
       return Math.random() < 0.5;
       //I tried another approaches here, still the same result
   }

   public static void main(String[] args) {
       System.out.println(getRandomBoolean());  
   }
}

$ javac myProgram.java
$ java myProgram ; java myProgram; java myProgram; java myProgram
true
false
false
true

不用说,无法保证每次都能获得不同的值。然而,在你的情况下,我怀疑

A) 你没有使用你认为的代码,(比如编辑错误的文件)

B) 你在测试时没有编译你的不同尝试,或者

C) 您正在使用一些非标准的损坏实现。

【讨论】:

    【解决方案2】:

    你试过查看Java Documentation吗?

    从该随机数生成器的序列中返回下一个伪随机、均匀分布的布尔值...truefalse 的生成概率(大约)相等。

    例如:

    import java.util.Random;
    
    Random random = new Random();
    random.nextBoolean();
    

    【讨论】:

      【解决方案3】:

      你也可以试试nextBoolean()-Method

      这是一个例子:http://www.tutorialspoint.com/java/util/random_nextboolean.htm

      【讨论】:

      • 更多,我什至尝试了 nextBoolean 并得到了相同的结果。 (连续 10 个错误)。显然程序比我写的要复杂得多,所以要么我真的很幸运,要么真的很愚蠢的程序员:)
      • @Pavel Janicek 然后连续 10 个错误?还是你总是假的?我曾经在我写的一个 c# 项目中遇到过同样的问题,我在初始化部分做错了。我也得到了同样的结果,每次开始。你也可以发布你的初始化代码吗?!
      • 好的,有问题了!我没有正确初始化该值:) 至少对此表示赞成... ;)
      【解决方案4】:

      Java 8:使用与当前线程隔离的随机生成器:ThreadLocalRandom nextBoolean()

      与 Math 类使用的全局 Random 生成器一样,ThreadLocalRandom 使用内部生成的种子进行初始化,否则该种子可能不会被修改。如果适用,在并发程序中使用 ThreadLocalRandom 而不是共享 Random 对象通常会遇到更少的开销和争用。

      java.util.concurrent.ThreadLocalRandom.current().nextBoolean();
      

      【讨论】:

        【解决方案5】:

        为什么不使用Random 类,它有一个方法nextBoolean

        import java.util.Random;
        
        /** Generate 10 random booleans. */
        public final class MyProgram {
        
          public static final void main(String... args){
        
            Random randomGenerator = new Random();
            for (int idx = 1; idx <= 10; ++idx){
              boolean randomBool = randomGenerator.nextBoolean();
              System.out.println("Generated : " + randomBool);
            }
          }
        }
        

        【讨论】:

          【解决方案6】:

          您可以使用以下方法获得公正的结果:

          Random random = new Random();
          //For 50% chance of true
          boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;
          

          注意: random.nextInt(2) 表示数字 2 是界限。计数从 0 开始。所以我们有 2 个可能的数字(0 和 1),因此概率是 50%!

          如果你想让你的结果更有可能是真(或假),你可以调整上面的如下!

          Random random = new Random();
          
          //For 50% chance of true
          boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;
          
          //For 25% chance of true
          boolean chance25oftrue = (random.nextInt(4) == 0) ? true : false;
          
          //For 40% chance of true
          boolean chance40oftrue = (random.nextInt(5) < 2) ? true : false;
          

          【讨论】:

            【解决方案7】:

            初始化随机数生成器最简单的方法是使用无参数构造函数,例如

            Random generator = new Random();
            

            但是,在使用此构造函数时,您应该认识到算法随机数生成器并不是真正随机的,它们实际上是生成固定但看起来随机的数字序列的算法。

            您可以通过为 Random 构造函数提供 'seed' 参数来使其看起来更“随机”,您可以动态构建该参数,例如使用以毫秒为单位的系统时间(始终不同)

            【讨论】:

            • Erm,无参数构造函数正是这样做的(大多数情况下,至少)。除非您知道自己在做什么,否则您很少需要直接设置种子。这几乎从不适用于这类问题。而且它不会使序列看起来“更随机”。那么它只是一个不同的序列(绑定到种子)。
            【解决方案8】:

            你可以得到你的clock()值并检查它是奇数还是偶数。不知道是不是真的%50

            您可以自定义创建随机函数:

            static double  s=System.nanoTime();//in the instantiating of main applet
            public static double randoom()
            {
            
            s=(double)(((555555555* s+ 444444)%100000)/(double)100000);
            
            
                return s;
            }
            

            数字 55555.. 和 444.. 是获得广泛功能的大数字 请忽略那个Skype图标:D

            【讨论】:

            • 您可能无法获得真正的 cpu 周期,但可以获得低分辨率的时钟周期。那么你有一个错误范围,每次你得到一个时钟()值时你都有随机点。如果误差范围是对称的,则统计上必须为 %50
            • 他并没有要求双生成器,因此您发布的代码 sn-p 非常无关紧要。其次,检查当前时间是否是偶数不是一个好主意,原因有几个。 System.nanoTime() 不能保证具有纳秒级的精度。我的只有微秒精度。因此,它总是偶数 --> 总是正确的。其次,如果要在间隔很短的时间内多次调用随机函数,则生成的随机值将取决于先前的值。如果您使用 currentTimeMillis() 并调用随机生成器 100 次/毫秒,生成器将连续产生 100 个真值。
            • 如果它总是正确的,那么它没有偏差。位=(布尔值)s;如果你需要随机性,你将需要随机误差范围。错误是意外行为,就像随机事物一样。这就是为什么我故意给 System.nanoTime() 以获得错误范围。但是您对 System.nanoTime() 的缓慢性是正确的,这就是它被用作“种子”的原因。然后 random() 以尽可能快的速度使用计算机
            • 我的观点是,尽管它不符合我之前评论的字数限制,但最好使用 Java 内置的随机函数,而不是基于未经调查的特定随机实现假设。
            • 以防他不喜欢图书馆。也许他的java版本有一些错误或损坏。我不知道。我只说我知道的
            【解决方案9】:

            您还可以制作两个随机整数并验证它们是否相同,这样可以更好地控制概率。

            Random rand = new Random();
            

            声明一个范围来管理随机概率。 在这个例子中,有 50% 的可能性是真实的。

            int range = 2;
            

            生成 2 个随机整数。

            int a = rand.nextInt(range);
            int b = rand.nextInt(range);
            

            然后简单地比较返回值。

            return a == b; 
            

            我还有一个你可以使用的课程。 RandomRange.java

            【讨论】:

              【解决方案10】:

              文本中的单词总是随机的来源。给定一个单词,无法推断出下一个单词。对于每个单词,我们可以取其字母的 ASCII 码,将这些码相加形成一个数字。这个数字的奇偶性是随机布尔值的一个很好的候选。

              可能的缺点:

              1. 此策略基于使用文本文件作为词源。在某一点, 将到达文件的末尾。但是,您可以估计调用 randomBoolean() 的次数 从您的应用程序中运行。如果你需要调用它大约 100 万次,那么一个 100 万字的文本文件就足够了。 作为修正,您可以使用来自在线报纸等实时来源的数据流。

              2. 对一种语言中的常用短语和习语进行一些统计分析,可以估计一个短语中的下一个单词, 给定短语的第一个单词,并具有一定程度的准确性。但从统计上看,这些情况很少见,当我们可以准确地 预测下一个单词。因此,在大多数情况下,下一个单词独立于前面的单词。

                包p01;

                导入 java.io.File; 导入 java.nio.file.Files; 导入 java.nio.file.Paths;

                公共类主{

                String words[];
                int currentIndex=0;
                
                public static String readFileAsString()throws Exception 
                  { 
                    String data = ""; 
                    File file = new File("the_comedy_of_errors");
                    //System.out.println(file.exists());
                    data = new String(Files.readAllBytes(Paths.get(file.getName()))); 
                    return data; 
                  } 
                
                public void init() throws Exception
                {
                    String data = readFileAsString(); 
                    words = data.split("\\t| |,|\\.|'|\\r|\\n|:");
                }
                
                public String getNextWord() throws Exception
                {
                    if(currentIndex>words.length-1)
                        throw new Exception("out of words; reached end of file");
                
                    String currentWord = words[currentIndex];
                    currentIndex++;
                
                    while(currentWord.isEmpty())
                    {
                        currentWord = words[currentIndex];
                        currentIndex++;
                    }
                
                    return currentWord;
                }
                
                public boolean getNextRandom() throws Exception
                {
                    String nextWord = getNextWord();
                    int asciiSum = 0;
                
                    for (int i = 0; i < nextWord.length(); i++){
                        char c = nextWord.charAt(i);        
                        asciiSum = asciiSum + (int) c;
                    }
                
                    System.out.println(nextWord+"-"+asciiSum);
                
                    return (asciiSum%2==1) ;
                }
                
                public static void main(String args[]) throws Exception
                {
                    Main m = new Main();
                    m.init();
                    while(true)
                    {
                        System.out.println(m.getNextRandom());
                        Thread.sleep(100);
                    }
                }
                

                }

              在 Eclipse 中,在我的项目的根目录中,有一个名为“the_comedy_of_errors”(无扩展名)的文件 - 使用 File> New > File 创建,我从这里粘贴了一些内容:http://shakespeare.mit.edu/comedy_errors/comedy_errors.1.1.html

              【讨论】:

                【解决方案11】:

                对于灵活的布尔随机化器:

                public static rbin(bias){
                    bias = bias || 50;
                    return(Math.random() * 100 <= bias);
                    /*The bias argument is optional but will allow you to put some weight
                      on the TRUE side. The higher the bias number, the more likely it is
                      true.*/
                }
                

                确保使用数字0 - 100,否则您可能会降低偏差并获得更常见的false 值。

                PS:我对Java一无所知,除了它与JavaScript有一些共同的特性。我使用我的 JavaScript 知识和我的推理能力来构建这段代码。期望我的回答不起作用。你们都可以编辑这个答案来解决我不知道的任何问题。

                【讨论】:

                  猜你喜欢
                  • 2011-10-13
                  • 2013-10-13
                  • 2012-01-15
                  • 2017-09-05
                  • 2016-08-13
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-11-27
                  相关资源
                  最近更新 更多