在Java中获取随机布尔值


72

好的,我在代码中实现了这个SO问题:随机返回True或False

但是,我的行为很奇怪:我需要同时运行十个实例,每个实例每次运行仅返回一次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每次都会得到结果...



13
为什么不使用Random r = new Random(); r.nextBoolean();
Thomas Jungblut 2012年

Answers:


110

我建议使用 Random.nextBoolean()

话虽如此,Math.random() < 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)您正在使用一些非标准的无效实现。


33

您也可以尝试nextBoolean()-Method

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


2
而且,我什至尝试了nextBoolean并得到了相同的结果。(连续10个错误)。显然,该程序比我写的要复杂得多,所以我要么是一个非常幸运的人,要么是一个愚蠢的程序员:)
Pavel Janicek 2012年

@Pavel Janicek在那10个连续错误之后?还是会得到虚假的错误?我曾经在编写的ac#项目中遇到过同样的问题,在初始化部分我做错了什么。每次开始,我也总是得到相同的结果。您也可以发布初始化代码吗?
Sagi 2012年

2
好吧,可能有收获!我没有正确初始化值:)至少为此
投票

31

您是否尝试过查看Java文档

从此随机数生成器的序列中返回下一个伪随机的,均匀分布的布尔值……这些值truefalse的产生概率(大约)相等。

例如:

import java.util.Random;

Random random = new Random();
random.nextBoolean();

8

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

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

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

3

为什么不使用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);
    }
  }
}

1

您可以将以下内容用于不偏不倚的结果:

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;

0

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

Random generator = new Random();

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

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


2
嗯,无参数构造函数正是这样做的(至少是至少如此)。除非您知道自己在做什么,否则很少需要直接设置种子。几乎从不适用此类问题。而且它不会使序列看起来“更加随机”。然后,这只是一个不同的序列(绑定到种子)。
乔伊(Joey)

0

您可以获取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周期,但可以获得低分辨率的时钟周期。则您有一个误差范围,每次获得clock()值时,该误差范围就会随机。如果误差范围是对称的,则统计上必须为%50
huseyin tugrul buyukisik 2012年

他并没有要求使用双生成器,因此您发布的代码段是无关紧要的。其次,由于几个原因,检查当前时间是否还不是一个好主意。System.nanoTime()无法保证具有纳秒级的精度。我的只有微秒精度。因此,它总是->始终为真。其次,如果要在短时间内调用多次随机函数,则生成的随机值将取决于先前的值。如果使用currentTimeMillis()并以100次/毫秒的速度调用随机生成器,则该生成器将连续生成100个true。
Alderath

如果始终为真,则没有偏差。位=(布尔)s; 如果需要随机性,则需要随机误差范围。就像随机事物一样,这是不可预知的错误。那就是为什么我故意给System.nanoTime()以获取错误范围。但是您对System.nanoTime()的慢速是正确的,这就是为什么它被用作“种子”的原因。那么randoom()
将以最快的

我的观点是,尽管这完全不符合我先前的评论的字数限制,但使用Java内置的随机函数要好于使用未经调查的假设进行一些特定的临时随机实现,这更好。
阿德拉斯

以防万一他不喜欢图书馆。也许他的Java版本有一些错误或已损坏。我不知道。我只告诉了我所知道的内容
huseyin tugrul buyukisik

0

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

Random rand = new Random();

声明一个范围来管理随机概率。在此示例中,有50%的可能性为真。

int range = 2;

生成2个随机整数。

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

然后只需比较返回值即可。

return a == b; 

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


0

文本中的单词始终是随机性的来源。给定一个单词,就不能推断出下一个单词。对于每个单词,我们可以采用其字母的ASCII码,然后将这些代码相加以形成数字。此数字的奇偶校验是随机布尔值的良好候选者。

可能的缺点:

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

  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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.