0

How can I generate integer numbers randomly from (1 to 100) with probability for example 30% if the numbers range from (1 to 50), and with probability 70% if the numbers range from (50 to 100)?

int integer = new Random().nextInt(100) + 1;

// Probabilities
   ..... code here ....

How would I do that?

mkobit
  • 43,979
  • 12
  • 156
  • 150
iibrahimbakr
  • 1,116
  • 1
  • 13
  • 32
  • 1
    duplicate https://stackoverflow.com/questions/20327958/random-number-with-probabilitieshttps://stackoverflow.com/questions/20327958/random-number-with-probabilities edit: um that's weird.. if you click the link directly it gives a 404 but it's available via google https://www.google.com/search?q=questions%2F20327958%2Frandom-number-with-probabilities&oq=questions%2F20327958%2Frandom-number-with-probabilities&aqs=chrome..69i57j69i58j69i60.5166j0j8&sourceid=chrome&es_sm=91&ie=UTF-8 – Michael Queue Oct 27 '15 at 03:35
  • @MichaelJames Correct link is https://stackoverflow.com/questions/20327958/random-number-with-probabilities – Andreas Oct 27 '15 at 03:37
  • this is a chinese website [generate integer numbers randomly with probabilities](http://www.360doc.com/content/10/1208/14/2960485_76121195.shtml) – Thomas Zhang Oct 27 '15 at 03:37
  • @MichaelJames You must have double pasted the link? It is repeated twice – mkobit Oct 27 '15 at 03:41
  • These links are very useful. Thanks for everyone. – iibrahimbakr Oct 27 '15 at 03:49

3 Answers3

6

Here is a method getRandom() which returns a single random number meeting the criteria you specified. It actually uses a random number between 0 and 9 to determine which of the two ranges to use.

public int getRandom() {
    Random random = new Random();
    int val = random.nextInt(10);

    if (val < 3) {
        return random.nextInt(50) + 1;      // random range 1 to 50
    }
    else {
        return random.nextInt(51) + 50;     // random range 50 to 100
    }
}
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
1

Here's a general solution that will return one of any number of events, where you specify the relative weights of the events. The weights could be probabilities, but they don't have to; they don't have to add up to 1. For example, if you have three events, and you want the first one to have probability 20%, the second 30%, and the third 50%, you could call addEvent on each event with 2, 3, and 5 as the second parameter, or 20, 30, and 50, or 0.2, 0.3, and 0.5, or any other combination of numbers that has those ratios. For your case, you could make the generic parameter an interval and add two events with weights 3 and 7 (or 30 and 70, or whatever); then, when you call randomEvent, and it returns an interval with endpoints m and n inclusive, you then generate another random number in that interval:

value = m + random.nextInt(n - m + 1);

where random is your own instance of Random.

class RandomDistribution<T> {

    private class Event {
        public final T event;
        public final double relativeWeight;
        public Event(T event, double relativeWeight) {
            this.event = event;
            this.relativeWeight = relativeWeight;
        }
    }

    private double totalWeight = 0D;
    private ArrayList<Event> events = new ArrayList<>();
    private Random generator = new Random();

    public void addEvent(T event, double relativeWeight) {
        events.add(new Event(event, relativeWeight));
        totalWeight += relativeWeight;
    }

    public T randomEvent() {
        double random = generator.nextDouble() * totalWeight;
        for (Event event : events) {
            random -= event.relativeWeight;
            if (random < 0D) {
                return event.event;
            }
        }
        // It's possible to get here due to rounding errors
        return events.get(events.size() - 1).event;
    }

}
ajb
  • 31,309
  • 3
  • 58
  • 84
1

You can use MockNeat probabilities() method.

String s = mockNeat.probabilites(String.class)
                .add(0.1, "A")
                .add(0.2, "B")
                .add(0.5, "C")
                .add(0.2, "D")
                .val();

The above example will generate "A" with 10% probability, B with 20% probability and so on.

Integer x = m.probabilites(Integer.class)
         .add(0.2, m.ints().range(0, 100))
         .add(0.5, m.ints().range(100, 200))
         .add(0.3, m.ints().range(200, 300))
         .val();

The above example will generate a number in the range [0, 100) with 20% probability, a number in the range [100, 200) with 50% probability and a number in the range [200, 300) with 30% probability.

Disclaimer: I am the author of the library, so I might be biased when I am recommending it.

Andrei Ciobanu
  • 12,500
  • 24
  • 85
  • 118