-7

enter image description here

I'm using this to generate values between 5 to 13

 int randomGeneratedLevelValue = ThreadLocalRandom.current().nextInt(5, 13);

How to make same matches fewer?

Selvin
  • 6,598
  • 3
  • 37
  • 43
  • try [this](https://stackoverflow.com/a/5887745/7505436) – vm345 Mar 26 '18 at 11:46
  • Although your approach is rather clever, there are some disadvantages as well (some of which may result in your issue), it's been described here [Random over ThreadLocalRandom](https://stackoverflow.com/questions/23396033/random-over-threadlocalrandom) – jujka Mar 26 '18 at 11:49
  • 1
    So you don't wana random values? same values are pretty normal for such range ... do some math and count probability of same number – Selvin Mar 26 '18 at 12:00
  • 1
    https://en.m.wikipedia.org/wiki/Birthday_problem – EJoshuaS - Stand with Ukraine Mar 26 '18 at 13:03

2 Answers2

8

There is no way to reduce the number of repetitions in a true random number sequence without biasing the random number sequence.

So, for example, in your sequence 10, 5, 12, 12, 13, 13, the chance that 12 is followed by another 12 is 1 in 9; i.e. the same as the probability of any other number in the range.

Now it is possible that since you are using Random / ThreadLocalRandom you are seeing the effects of the autocorrelation that is inherent in linear congruential generators. If so, these effects can be eliminated by using SecureRandom instead. But SecureRandom calls are significantly more expensive.


The other approach would be to deliberately bias against repetitions; e.g. (pseudo-code)

int random = rand.nextInt(...)
if (random == lastRandom) {
     random = rand.nextInt(...);
}
return random;

But be careful. Introducing a bias could have unintended / unexpected consequences.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • what is last number?? –  Mar 26 '18 at 12:10
  • The last random number that you got from your generator. This is **pseudocode** – Stephen C Mar 26 '18 at 12:11
  • *what is last number??* with `ThreadLocalRandom.current().nextInt(5, 13)` ? 12 (*nextInt(int least, int bound) Returns a pseudorandom, uniformly distributed value between the given least value (inclusive) and **bound (exclusive).***)... but you asked *How to make same matches fewer?* and this answer answers that question – Selvin Mar 26 '18 at 12:11
  • @Selvin - I think the OP is asking what `lastRandom` means in my pseudo code. But it is really hard to tell. His question and the comments are very unclear. – Stephen C Mar 26 '18 at 12:13
  • hehe He answers to himself with `ThreadLocalRandom.current().nextInt(min, max+1)` that why I thought that *what is last number?* was about what `ThreadLocalRandom.current().nextInt(5, 13)` returns as last number not `lastRandom` in your code .... *What we've got here is failure to communicate* – Selvin Mar 26 '18 at 12:17
  • @Selvin - your rationale is plausible ... and we will only know for sure if he explains himself. – Stephen C Mar 26 '18 at 12:19
3

The Birthday Paradox predicts that the probability of duplicates in random numbers is much higher than you'd think. For example, it predicts that, with a mere 23 random people, there's a greater than 50% chance of two of them have the same birthday. By the Pigeonhole Principle, it takes 367 people for there to be a 100% chance of a duplicate, but the probability of a duplicate is extremely high even before that.

Here's the probability distribution (from Wikipedia): enter image description here

The rule of thumb to approximate the number of numbers you have to generate before the probability of duplicates reaches sqrt(2m * p(n)), where m is the number of possible random numbers and p(n) is the probability that you're looking for. So, for example, if you're generating random numbers in a 50-number range (e.g. if you pick a random number from 100 - 150), you'd only have to generate approximately sqrt((2 * 50) * 0.5) = 7.07 random numbers before the odds are just as good as not that you have a duplicate. If you generate 8 random numbers within a 50-number range, odds are better than not that'll have a duplicate. (Note that this only works for p(n) values of up to 1/2).

In your case, there are 8 possible values for any particular random value (5, 6, 7, 8, 9, 10, 11, 12), so you only need to generate sqrt(8) = 2.83 numbers before there's a probability of 50% that you'll have a duplicate. In other words, the Birthday Paradox predicts you only need to generate approximately 3 numbers for the chances to be better than not that you'll have a duplicate.

See also this Q&A.

One more point: beware the Gambler's Fallacy, in which people assume that if you randomly generate, for example, a 10, odds are the next one won't be a 10. Actually, given that you're generating random numbers, the odds of any particular number is 1/8 regardless of what numbers came before. In other words, if you generate a 12, the probability of the next number being a 10 is 1/8. If you generate a 7, the odds of the next number being a 10 is 1/8. If you generate a 10, the probability of the next number being a 10 is still 1/8. Each number is an independent event (i.e. the numbers you've generated so far don't influence the probability distribution of future numbers in the least).

TL;DR You need to generate much fewer numbers than you think you do before you're likely to start getting duplicates - if you're generating random numbers within a small range of numbers in particular (like you are) the number is particularly low.