简体   繁体   中英

Generate list of unique random numbers in constant time

I need 100 random numbers from the range 1 to 1,000,000. The numbers must be unique, no duplicates. It's similar to this question , but my range is too large to create an array from.

I need to generate these 100 random numbers many, many times, so generation needs to be as fast as possible, preferably O(1). What's the fastest way to do it?

I would use a HashSet and a Mersenne Twister .

code:

    MersenneTwisterFast ran = new MersenneTwisterFast();
    long time = System.nanoTime();
    Set set = new HashSet(100);
    while( set.size()<100) {
        set.add(ran.nextInt(1000000));
   }

System.out.println(System.nanoTime()-time+" : nano");
System.out.println(set.size());

The output was:

320000 : nano

100

Fast enough? and yes, this is O(1) as you always do 100 numbers.

Beware of the Birthday paradox , here you select 100 out of 1000000, thats ok but if you boost the 100 up, it will take longer and longer.

Divide your range in 100 parts and generate a random number from each sub-range. I think it'll work fine in your case.

Alternatively, generate random numbers and put them in a HashSet. when the size of the HashSet is 100, you break.

Though If you want to generate 100 random numbers, it'll always be O(1).

Create a Random here.

 Random generator = new Random();

And create a timer class to execute the function every x seconds

 int d = 1000; //milliseconds 
 ActionListener t = new ActionListener() {
  public void actionPerformed(ActionEvent e) {
      //...Number genration task Here

  for (int idx = 1; idx <= 10; ++idx){
  int r = generator.nextInt(1000000);
  log("Generated : " + r);
  }
  }
  };
  new Timer(a,t).start()

Disclaimer: this solution only works quickly when the amount of possible generated numbers greatly exceeds the amount of numbers you have to generate!

Edit: you can use this exact code with a Mersenne Twister also if you like

import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;

public class MakeRand {
    private static final HashSet<Integer> theNumbers = new HashSet<Integer>();
    private static final Random myRandom = new Random();

    private static void addNumber() {
         int newNumber = -1;
         do {
            newNumber = myRandom.nextInt(1000000) + 1;
         } while(theNumbers.contains(newNumber));

         theNumbers.add(newNumber);
    }

    public static void populate(int howMany) {
        for (int i = 0; i < howMany; i++) {
            addNumber();
        }
    }

    public static void main(String args[]) {
        populate(100);

        Iterator<Integer> iter = theNumbers.iterator();
        while(iter.hasNext()) {
            Integer current = iter.next();
            System.out.println(current);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM