Welcome to Siva's Blog

~-Scribbles by Sivananda Hanumanthu
My experiences and learnings on Technology, Leadership, Domains, Life and on various topics as a reference!
What you can expect here, it could be something on Java, J2EE, Databases, or altogether on a newer Programming language, Software Engineering Best Practices, Software Architecture, SOA, REST, Web Services, Micro Services, APIs, Technical Architecture, Design, Programming, Cloud, Application Security, Artificial Intelligence, Machine Learning, Big data and Analytics, Integrations, Middleware, Continuous Delivery, DevOps, Cyber Security, Application Security, QA/QE, Automations, Emerging Technologies, B2B, B2C, ERP, SCM, PLM, FinTech, IoT, RegTech or any other domain, Tips & Traps, News, Books, Life experiences, Notes, latest trends and many more...

Saturday, October 23, 2010

How to generate unique random numbers from a range of numbers

Generating a series of random numbers is one of those common tasks that crops up from time to time. In Java, it can be achieved simply by using the java.util.Random class.


The first step, as with the use of any API class, is to put the import statement before the start of your program class:
 import java.util.Random; 

Next, create a Random object:
 Random rand = new Random(); 

The Random object provides you with a simple random number generator. The methods of the object give the ability to pick random numbers. For example, the nextInt() and nextLong() methods will return a number that is within the range of values (negative and positive) of the int and long data types respectively:
 Random rand = new Random(); 
 for (int j=0;j < 5;j++)
 {
   System.out.printf("%12d ",rand.nextInt());
   System.out.print(rand.nextLong());
   System.out.println();
 } 

The numbers returned will be randomly chosen int and long values:

 -1531072189 -1273932119090680678
 1849305478  6088686658983485101
 1043154343  6461973185931677018
 1457591513  3914920476055359941
 -1128970433 -7917790146686928828
 

Picking Random Numbers From a Certain Range

Normally the random numbers to be generated need to be from a certain range (e.g., between 1 to 40 inclusively). For this purpose the nextInt() method can also accept an int parameter. It denotes the upper limit for the range of numbers. However, the upper limit number is not included as one of the numbers that can be picked. That might sound confusing but the nextInt() method works from zero upwards. For example:

 Random rand = new Random(); 
 rand.nextInt(40); 

will only pick a random number from 0 to 39 inclusively. To pick from a range that starts with 1, simply add 1 to the result of the nextInt() method. For example, to pick a number between 1 to 40 inclusively add one to the result:
 Random rand = new Random(); 
 int pickedNumber = rand.nextInt(40) + 1; 

If the range starts from a higher number than one you will need to:
  • minus the starting number from the upper limit number and then add one.
  • add the starting number to the result of the nextInt() method.
For example, to pick a number from from 5 to 35 inclusively, the upper limit number will be 35-5+1=31 and 5 needs to be added to the result:

 Random rand = new Random(); 
 int pickedNumber = rand.nextInt(31) + 5; 

Just How Random Is the Random Class?

I should point out that the Random class generates random numbers in a deterministic way. The algorithm that produces the randomness is based on a number called a seed. If the seed number is known then it's possible to figure out the numbers that are going to be produced from the algorithm. To prove this I'll use the numbers from the date that Neil Armstrong first stepped on the Moon as my seed number (20th July 1969) :

 import java.util.Random;
 public class RandomTest {;
 
   public static void main(String[] args) {
     Random rand = new Random(20071969);
 
     for (int j = 0; j<10; j++)
     {
       int pick = rand.nextInt(10);
       System.out.println(pick);
     }
   }
 } 

No matter who runs this code the sequence of "random" numbers produced will be:
 3 0 3 0 7 9 8 2 2 5 

By default the seed number that is used by:
 Random rand = new Random(); 
is the current time in milliseconds since January 1, 1970. Normally this will produce sufficiently random numbers for most purposes. However, note that two random number generators created within the same millisecond will generate the same random numbers.

Also be careful when using the Random class for any application that must have a secure random number generator (e.g., a gambling program). It might be possible to guess the seed number based on the time the application is running. Generally for applications where the random numbers are absolutely critical it's best to find an alternative to the Random object. For most applications where there just needs to be a certain random element (e.g., dice for a board game) then it works fine.


>>>> The result may have duplicate numbers in it and there is another way of getting the unique random numbers and below is how...

Using a Collection

The easiest way to pick unique random numbers is to put the range of numbers into a collection called an ArrayList. If you've not come across an ArrayList before it's a way of storing a set of elements that don't have a fixed number. The elements are objects that can be added to or removed from the list. For example, let's make the lottery number picker. It needs to pick unique numbers from a range of 1 to 40.
First put the numbers into an ArrayList using the add() method. It takes the object to be added as a parameter:
 import java.util.ArrayList;
 public class Lottery {
 
   public static void main(String[] args) {
 
   //define ArrayList to hold Integer objects
   ArrayList numbers = new ArrayList();
   for(int i = 0; i < 40; i++)
   {
     numbers.add(i+1);
   }
   System.out.println(numbers);
 } 
Note that I'm using the Integer wrapper class for the element type so that the ArrayList contains objects and not primitive data types.
The output shows the range of numbers from 1 to 40 in order:
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40] 

Using the Collections Class

There is a utility class called Collections that provides different actions that can be performed on a collection like an ArrayList (e.g., search the elements, find the maximum or minimum element, reverse the order of elements, and so on). One of the actions it can perform is to shuffle the elements. The shuffle will randomly move each element to a different position in the list. It does this by using a Random object. This means it's a deterministic randomness, but it will do in most situations.

To shuffle the ArrayList, add the Collections import to the top of the program and then use the Shuffle static method. It takes the ArrayList to be shuffled as a parameter:
 import java.util.Collections;
 import java.util.ArrayList;
 public class Lottery {
 
   public static void main(String[] args) {
 
     //define ArrayList to hold Integer objects
     ArrayList numbers = new ArrayList();
     for(int i = 0; i < 40; i++)
     {
       numbers.add(i+1);
     }
 
     Collections.shuffle(numbers);
     System.out.println(numbers);
   }
 } 
Now the output will show the elements in the ArrayList in a random order:
 [24, 30, 20, 15, 25, 1, 8, 7, 37, 16, 21, 2, 12, 22, 34, 33, 14, 38, 39, 18,
 36, 28, 17, 4, 32, 13, 40, 35, 6, 5, 11, 31, 26, 27, 23, 29, 19, 10, 3, 9] 

Picking the Unique Numbers

To pick the unique random numbers simply read the ArrayList elements one by one by using the get() method. It takes the position of the element in the ArrayList as a parameter. For example, if the lottery program needs to pick six numbers from the range of 1 to 40:
 import java.util.Collections;
 import java.util.ArrayList;
 public class Lottery {
 
   public static void main(String[] args) {
 
     //define ArrayList to hold Integer objects
     ArrayList numbers = new ArrayList();
     for(int i = 0; i < 40; i++)
     {
     numbers.add(i+1);
   }
 
     Collections.shuffle(numbers);
     System.out.print("This week's lottery numbers are: ");
     for(int j =0; j < 6; j++)
     {
       System.out.print(numbers.get(j) + " ");
     }
   }

 } 
The output being:

 This week's lottery numbers are: 6 38 7 36 1 18 
 
Reference: http://java.about.com/od/javautil/a/randomnumbers.htm