Get random boolean in Java

Viewed 152450

Okay, I implemented this SO question to my code: Return True or False Randomly

But, I have strange behavior: I need to run ten instances simultaneously, where every instance returns true or false just once per run. And surprisingly, no matter what I do, every time i get just false

Is there something to improve the method so I can have at least roughly 50% chance to get true?


To make it more understandable: I have my application builded to JAR file which is then run via batch command

 java -jar my-program.jar
 pause

Content of the program - to make it as simple as possible:

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

If I open 10 command lines and run it, I get false as result every time...

11 Answers

You can use the following for an unbiased result:

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

Note: random.nextInt(2) means that the number 2 is the bound. the counting starts at 0. So we have 2 possible numbers (0 and 1) and hence the probability is 50%!

If you want to give more probability to your result to be true (or false) you can adjust the above as following!

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;

Words in a text are always a source of randomness. Given a certain word, nothing can be inferred about the next word. For each word, we can take the ASCII codes of its letters, add those codes to form a number. The parity of this number is a good candidate for a random boolean.

Possible drawbacks:

  1. this strategy is based upon using a text file as a source for the words. At some point, the end of the file will be reached. However, you can estimate how many times you are expected to call the randomBoolean() function from your app. If you will need to call it about 1 million times, then a text file with 1 million words will be enough. As a correction, you can use a stream of data from a live source like an online newspaper.

  2. using some statistical analysis of the common phrases and idioms in a language, one can estimate the next word in a phrase, given the first words of the phrase, with some degree of accuracy. But statistically, these cases are rare, when we can accuratelly predict the next word. So, in most cases, the next word is independent on the previous words.

    package p01;

    import java.io.File; import java.nio.file.Files; import java.nio.file.Paths;

    public class Main {

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

    }

In Eclipse, in the root of my project, there is a file called 'the_comedy_of_errors' (no extension) - created with File> New > File , where I pasted some content from here: http://shakespeare.mit.edu/comedy_errors/comedy_errors.1.1.html

For a flexible boolean randomizer:

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.*/
}

Make sure to use numbers 0 - 100 or you might lower the bias and get more common false values.

PS: I do not know anything about Java other than it has a few features in common with JavaScript. I used my JavaScript knowledge plus my inferring power to construct this code. Expect my answer to not be functional. Y'all can edit this answer to fix any issues I am not aware of.
Related