Code covered by the BSD License  

Highlights from
Random Integer Generator

5.0

5.0 | 3 ratings Rate this file 45 Downloads (last 30 days) File Size: 6.53 KB File ID: #18443

Random Integer Generator

by Edward Zechmann

 

23 Jan 2008 (Updated 20 Feb 2008)

This program quickly outputs n random integers in the specified range from a to b.

| Watch this File

File Information
Description

The program quickly outputs n random integers in the range from a to b. The integers are drawn from a uniform distribution to make selection of integers equally probable.
 
This program is intended to be especially quick with very large ranges of integers and selecting only a very small number of those integers.

User specifies whether output is sorted or random order.

User specifies whether to remove duplicate integers or to allow duplicate integers.

Acknowledgements

The author wishes to acknowledge the following in the creation of this submission:
MYRANDINT -- Random Integer Generation

MATLAB release MATLAB 7.5 (R2007b)
Tags for This File  
Everyone's Tags
Tags I've Applied
Add New Tags Please login to tag files.
Comments and Ratings (6)
24 Jan 2008 Jos x@y.z

If any, this submission has only educational value, and the author should stress that quite explicitly.

r = randperm(b-a+1) - 1 ;
r = a + r(1:n) ;

will do the job much smoother.

28 Jan 2008 John D'Errico

I'd have to disagree with Jos here. There is value in a code which performs more quickly than a simple solution.

a=0;b=1000000;n=10;

tic,r = randperm(b-a+1) - 1 ;r = a + r(1:n) ;toc
Elapsed time is 0.883846 seconds.

tic,x = rand_int(a,b,n);toc
Elapsed time is 0.003325 seconds.

If you often need to sample only a few integers without replacement from a large set, this seems like a worthwhile utility. Admittedly, its a lot of code for something that might have been done more simply. For example, a simple, brute force, pure rejection code should work fairly well too:

function x = johnsrandint(a,b,n)
flag = true;
while flag
  x = unique(round((a - 1/2) + (b-a+1)*rand(n,1)));
  flag = (length(x)~=n);
end

tic,x = johnsrandint(0,1000000,10);toc
Elapsed time is 0.000656 seconds.

tic,x = rand_int(a,b,n);toc
Elapsed time is 0.002503 seconds.

On the other hand, there are regimes where my simple alternative is also not efficient. For example, when n is any significant fraction of (b-a), my version may be slow, since then the probability of too many rejection steps occurring will be high. So the author might choose to add a third regime to his code, for extremely small samples relative to (b-a).

On to the real purpose of a review...

This code is generally well written. It has good internal comments that explain what is done at each step. This is helpful for debugging purposes.

The code checks for inconsistent inputs, and attempts to return something logical anyway. I'd be tempted to return an error there, or at least a warning message, but the author is not unreasonable in this approach.

The help is expansive and descriptive, with examples of use. My only comment on the help is that I'd like to see a better description of what is to be expected. For example, the only description of the ndraw output is:

% % ndraw is the array of selected integers. The output is sorted.

We can infer that ndraw is an array. But is it a vector? What shape should we expect it to be? Row or column vector? We know that the array is sorted, but in which order? Tell your user these things, rather than forcing them to test run the code to find out that information.

I'd also suggest a bit more explicitness in the description of the inputs. Must it be true that a<=b ? What happens if this fails to be true? What if n>(b-a) ? Must {a,b,n} all be integers? What happens if n is not an integer?

Next, there is a bug in this code. The author has attempted to ensure that all integers are equally likely to be drawn, without replacement. He has done so by expanding the region of sampling by +/- 0.5. He also uses floor and ceil to ensure that the input interval ends are integer. So a few quick test runs by me found the following bug:

rand_int(0.25, 10, 5)
ans =
     0
     1
     4
     7
     8

Note that the lower endpoint was 0.25, yet the sample had a 0 in it. The bug can be repaired of course, with a quick test in the very beginning.

I was originally expecting to apply a 4 rating to this code, but when I recognized the existence of a bug, it pushed me down to a 3. I will always consider revising a rating upwards if/when I learn of repairs to the code & help.

31 Jan 2008 John D'Errico

Better now. But further testing found a new bug. Sampling 2 integers from a range that is 4 integers long or longer works fine.

rand_int(1,4,2)
ans =
     4
     2

But, if I want exactly 2 random integers from the set [1 2 3], I only get 1 integer.

rand_int(1,3,2)
ans =
     3

The other improvements bring this much closer to a 5. I'd have rated it a 5 until I found this problem. Since this bug (it should be a trivial fix) would push me down to a 4 rating, I won't propose a new rating until I check back for the repaired version.

01 Feb 2008 John D'Errico

Perhaps one of the changes made fixed the bug I found. This now works properly:

rand_int(1,3,2)
ans =
     1
     3

10 Nov 2009 Karim Mansour

Very Nice ! Thanks

08 Dec 2011 Tyler

The help for this file says that a 0 as the third input removes duplicates and 1 keeps them (lines 23-25). This is backward. It is listed correctly in the example however. Otherwise, its a useful function.

Please login to add a comment or rating.
Updates
25 Jan 2008

Added contributed code to make the program faster. Added examples to emphasize that the program is fast especially for large ranges of integers and only selecting a few.

28 Jan 2008

Added two additional options:
1) The output can be sorted or random order

2) The output can have no duplicate integers or allow duplicate integers.

29 Jan 2008

Updated program to include contributed code from John D'Errico. Fixed out of range bug.

31 Jan 2008

Made the third regime a catch for the pure rejection regime. Program returns warnings when pure rejection fails to select enough integers and the catch cancels the error if successful.

31 Jan 2008

Fixed a bug in outputting the proper size and orientation of the selected integers. Unfortunately, I was not able to recreate the bug that John D'Errico found. Hopefully, the bug was fixed by improving the resizing code.

20 Feb 2008

Added an option to plot the integers. The plot is helpful in visually inspecting the distribution of the output.

Tag Activity for this File
Tag Applied By Date/Time
random Edward Zechmann 22 Oct 2008 09:44:29
random integer Edward Zechmann 22 Oct 2008 09:44:29
set Edward Zechmann 22 Oct 2008 09:44:29
integer Edward Zechmann 22 Oct 2008 09:44:29
integer Brajesh Lal 25 Jun 2011 09:09:36

Contact us at files@mathworks.com