Reputation: 2254
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?
Upvotes: 3
Views: 1580
Reputation: 15641
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.
Upvotes: 4
Reputation: 32323
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);
}
}
}
Upvotes: 0
Reputation: 882
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()
Upvotes: 0
Reputation: 945
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).
Upvotes: 0