29

I need to generate some random booleans. However I need to be able to specify the probability of returning true. As a results doing:

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

will not work.

One possible solution would be:

private Random random = new Random()

public boolean getRandomBoolean(float p){
    return random.nextFloat() < p;
}

I was wondering if there is a better or more natural way of doing this.

EDIT: I guess I am asking whether there is a library class that provides a nextBoolean(float probability) method.

diestl
  • 2,020
  • 4
  • 23
  • 37

9 Answers9

10

I was wondering if there is a better or more natural way of doing this.

The approach you're using already is fine.

* As far as I know, there's not a standard Java method that will make this code any shorter.


* For non-cryptographic purposes.
gvaish
  • 9,374
  • 3
  • 38
  • 43
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
4

1) Yes, i think your approach is valid and I don't see another easier way.

2) There is a library for handling random numbers of different statistical distributions:

http://introcs.cs.princeton.edu/java/22library/StdRandom.java.html

luksch
  • 11,497
  • 6
  • 38
  • 53
3

Here's what I'm using. Very similar to FracturedRetina's answer.

Random random = new Random();

// 20% chance
boolean true20 = (random.nextInt(5) == 0) ? true : false;

// 25% chance
boolean true25 = (random.nextInt(4) == 0) ? true : false;

// 40% chance
boolean true40 = (random.nextInt(5) < 2) ? true : false;
bobanahalf
  • 829
  • 1
  • 11
  • 23
  • 4
    The ternary operator is totally redundant. Why not just `boolean true20 = (random.nextInt(5) == 0)` ? – Oneiros Oct 11 '17 at 14:25
  • You know how when you learn a new thing, it's useful in every situation? I completely agree that it's redundant. – bobanahalf Oct 12 '17 at 15:33
1

The MockNeat library implements this feature.

Example for generating a boolean value that has 99.99% of being true:

MockNeat m = MockNeat.threadLocal();
boolean almostAlwaysTrue = m.bools().probability(99.99).val();
Andrei Ciobanu
  • 12,500
  • 24
  • 85
  • 118
0
    public boolean getBiasedRandom(int bias) {
      int c;
      Random t = new Random();
     // random integers in [0, 100]
      c=t.nextInt(100);
      if (c>bias){return false;
      }
      else{return true;}
      }

This one is based on percentage...

-1

Expanding on user2495765's answer, you can make a function which takes an input ratio (as two values chance:range see code)

public class MyRandomFuncs {
    public Random rand = new Random();

    boolean getBooleanAsRatio(int chance, int range) {
        int c = rand.nextInt(range + 1);
        return c > chance;
    }

}

Depending on what you intend to do, you probably don't want to initalize Random from within your method but rather use as a class variable (as in the code above) and call nextInt() from within your function.

R. Smyth
  • 175
  • 1
  • 8
-1

Here's a Kotlin function that generates a boolean value based on a given probability:

import kotlin.random.Random

fun generateBooleanWithProbability(probability: Double): Boolean {
    require(probability >= 0.0 && probability <= 1.0) { "Probability must be between 0 and 1" }
    return Random.nextDouble() < probability
}

fun main() {
    val probability = 0.7 // Adjust this value to set your desired probability
    val result = generateBooleanWithProbability(probability)
    println("Generated boolean value: $result")
}

In this example, the generateBooleanWithProbability function takes a probability parameter, which should be a value between 0 and 1. The function uses Random.nextDouble() to generate a random double value between 0 (inclusive) and 1 (exclusive), and then compares it with the given probability. If the random value is less than the probability, the function returns true, otherwise, it returns false.

Remember to adjust the probability value in the main function to set your desired probability for generating the boolean value.

Arunachalam k
  • 734
  • 1
  • 7
  • 20
-2

Your way is probably better, code golf-wise, but another way to do it is like this:

public boolean getRandomBoolean() {
    Random random = new Random();
    //For 1 in 5
    int chanceOfTrue = 5;

    if (random.nextInt(chanceOfTrue) == 0) {
        return true;
    } else {
        return false;
    }
}

Or for 2 in 5, try this:

public boolean getRandomBoolean() {
    Random random = new Random();
    //For 2 in 5
    int chanceOfTrue = 5;
    int randInt = random.nextInt(chanceOfTrue);

    if (randInt == 0 || randInt == 1) {
        return true;
    } else {
        return false;
    }
}
rootmeanclaire
  • 808
  • 3
  • 13
  • 37
-2

Random object needs to be intialized already.

public static boolean flipRandom(double probability) {
    Validate.isBetween(probability, 0, 1, true);
    if(probability == 0)
        return false;
    if(probability == 1)
        return true;
    if(probability == 0.5)
        return random.nextBoolean();
    return random.nextDouble() < probability ? true : false;
}
Rohit
  • 392
  • 3
  • 14
  • The validation is reasonable, the rest makes the code unnecessarily less readable. Keep it simple – Oneiros Oct 11 '17 at 14:24