Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating random numbers with no duplicates

Tags:

java

random

In this case, the MAX is only 5, so I could check the duplicates one by one, but how could I do this in a simpler way? For example, what if the MAX has a value of 20? Thanks.

int MAX = 5;  for (i = 1 , i <= MAX; i++) {         drawNum[1] = (int)(Math.random()*MAX)+1;          while (drawNum[2] == drawNum[1])         {              drawNum[2] = (int)(Math.random()*MAX)+1;         }         while ((drawNum[3] == drawNum[1]) || (drawNum[3] == drawNum[2]) )         {              drawNum[3] = (int)(Math.random()*MAX)+1;         }         while ((drawNum[4] == drawNum[1]) || (drawNum[4] == drawNum[2]) || (drawNum[4] == drawNum[3]) )         {              drawNum[4] = (int)(Math.random()*MAX)+1;         }         while ((drawNum[5] == drawNum[1]) ||                (drawNum[5] == drawNum[2]) ||                (drawNum[5] == drawNum[3]) ||                (drawNum[5] == drawNum[4]) )         {              drawNum[5] = (int)(Math.random()*MAX)+1;         }  } 
like image 359
Woong-Sup Jung Avatar asked Oct 28 '10 05:10

Woong-Sup Jung


People also ask

How do you use Randbetween without repeating numbers?

As both RAND and RANDBETWEEN recalculate with every change on the worksheet, your list of random numbers will be continuously changing. To prevent this from happening, use Paste Special > Values to convert formulas to values as explained in How to stop random numbers from recalculating. Delete duplicates.

How do you generate unique random numbers?

In a column, use =RAND() formula to generate a set of random numbers between 0 and 1.

How do you generate a random number without duplicates in Java?

The correct approach is to use “Math. random()”- to create random numbers and to avoid repetition we can use a hashset to achieve that.


2 Answers

The simplest way would be to create a list of the possible numbers (1..20 or whatever) and then shuffle them with Collections.shuffle. Then just take however many elements you want. This is great if your range is equal to the number of elements you need in the end (e.g. for shuffling a deck of cards).

That doesn't work so well if you want (say) 10 random elements in the range 1..10,000 - you'd end up doing a lot of work unnecessarily. At that point, it's probably better to keep a set of values you've generated so far, and just keep generating numbers in a loop until the next one isn't already present:

if (max < numbersNeeded) {     throw new IllegalArgumentException("Can't ask for more numbers than are available"); } Random rng = new Random(); // Ideally just create one instance globally // Note: use LinkedHashSet to maintain insertion order Set<Integer> generated = new LinkedHashSet<Integer>(); while (generated.size() < numbersNeeded) {     Integer next = rng.nextInt(max) + 1;     // As we're adding to a set, this will automatically do a containment check     generated.add(next); } 

Be careful with the set choice though - I've very deliberately used LinkedHashSet as it maintains insertion order, which we care about here.

Yet another option is to always make progress, by reducing the range each time and compensating for existing values. So for example, suppose you wanted 3 values in the range 0..9. On the first iteration you'd generate any number in the range 0..9 - let's say you generate a 4.

On the second iteration you'd then generate a number in the range 0..8. If the generated number is less than 4, you'd keep it as is... otherwise you add one to it. That gets you a result range of 0..9 without 4. Suppose we get 7 that way.

On the third iteration you'd generate a number in the range 0..7. If the generated number is less than 4, you'd keep it as is. If it's 4 or 5, you'd add one. If it's 6 or 7, you'd add two. That way the result range is 0..9 without 4 or 6.

like image 182
Jon Skeet Avatar answered Oct 12 '22 16:10

Jon Skeet


Here's how I'd do it

import java.util.ArrayList; import java.util.Random;  public class Test {     public static void main(String[] args) {         int size = 20;          ArrayList<Integer> list = new ArrayList<Integer>(size);         for(int i = 1; i <= size; i++) {             list.add(i);         }          Random rand = new Random();         while(list.size() > 0) {             int index = rand.nextInt(list.size());             System.out.println("Selected: "+list.remove(index));         }     } } 

As the esteemed Mr Skeet has pointed out:
If n is the number of randomly selected numbers you wish to choose and N is the total sample space of numbers available for selection:

  1. If n << N, you should just store the numbers that you have picked and check a list to see if the number selected is in it.
  2. If n ~= N, you should probably use my method, by populating a list containing the entire sample space and then removing numbers from it as you select them.
like image 29
Catchwa Avatar answered Oct 12 '22 16:10

Catchwa