Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Randomly Generating Numbers

Status
Not open for further replies.

rene316

Programmer
Jan 14, 2002
81
US
Hello,
This may and may not be a simple question. I have to generate random numbers, making sure I don't duplicate any numbers along the way(a million records all together). I am at a loss on where to even begin. Can anyone help me out on this?

Thanks in advance.
 
rene316

faq184-793

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
There are a variety of ways to get random or, at least pseudo random, numbers

=SYS(2015)
The name that SYS(2015) returns is created from the system date and system time. Calling SYS(2015) more than once during the same millisecond interval will return a unique string containing numeric characters.

=RAND(<seed value>)
See Foxpro Help file...

Or you can &quot;roll your own&quot; using the above with something like:
* ---------------------------------
* Generates Pseudo Random Number
* From 0 To 999 (Modify code for more digits)
*

FUNCTION RNDM999
PRIVATE m.nNUMBER

=RAND(-1)

m.cNumber = DIGITS(3)
m.nNUMBER = INT(VAL(m.cNUMBER))

=RAND(100001)
RETURN m.nNUMBER

* ---------------------------------
*** RETURNs a random n-digit number
FUNCTION DIGITS
PARAMETER N
X = 10^N
Y = IRAND(0, X-1) + X
RETURN SUBSTR(STR(Y,N+1),2)

* ---------------------------------
FUNCTION IRAND
PARAMETER I, J
RETURN INT((J-I+1)*RAND( )+I)

Or you most likely can find numerous other routines from other forum users or on the web.

Good Luck,


JRB-Bldr
VisionQuest Consulting
Business Analyst & CIO Consulting Services
CIOServices@yahoo.com
 
rene316,

Are you looking for a way to generate 1000000 unique numeric identifiers for those records? The reason I ask is that you say that the numbers can't repeat, which in some sense takes away from the randomness of the numbers. Also, what is the size of the field that you are putting these generated numbers into? I mean are you looking for numbers 1-1000000 but just having them placed on random records so that the count isn't sequential anymore? Could you tell us a little more about it, what is the application for this, or what is it that you are trying to accomplish by adding these generated numbers to the records in your table?

Slighthaze = NULL
[sub]craig1442@mchsi.com[/sub][sup]
&quot;Whom computers would destroy, they must first drive mad.&quot; - Anon​
[/sup]
 
Note: Since FAQ184-793 uses an array to save off the chosen numbers, it wouldn't work for a million records - it's limited to 65K values. You could change the array to a cursor and modify the technique appropriately, or you could use a quicker technique. (This one can do a lot of looping - especially toward the end, looking for a non-duplicate.)
This is a variant of a &quot;shuffle&quot; program I use. It simply picks a random number from 1 to max, grabs the value in that record and swaps the value with the first record. The next time it picks a number from 2 to max and swaps that records value with second record. This continues for each of the records. You only call rand() once for each record. You can load up any values in the cursor to start with (I used 1 to 1,000,000) the &quot;shuffler&quot; doesn't care.
Note: It took ~ 10 secs on my machine to create and shuffle these numbers.
Code:
* create cursor with random numbers from 1 to 1,000,000 **
CREATE CURSOR picks (pick n (10,0))
lnTotPicks = 1000000 

* Load the values *
FOR lnii = 1 to lnTotPicks
    INSERT INTO picks VALUES (lnii)
ENDFOR

=RAND(-1)
*** &quot;Shuffle&quot; ***
GOTO 1 && start in the right place
FOR lnii = 1 to lnTotPicks
   lnCurPick = Picks.Pick
   lnPick = INT(RAND()*(lnTotPicks-lnii+1))+lnii
   GOTO lnPick
   lnSvPick = Picks.Pick
   REPLACE Pick WITH lnCurPick
   GOTO lnii
   REPLACE Pick WITH lnSvPick
   SKIP +1
ENDFOR
Rick
 
Rene,

I'm sure you have all you need, but here's yet another function:

lnrandom=100000 &&how many unique values you want
notdone=.t.

CREATE TABLE rand_num1 (randnum n(10))
FOR lnCounter = 1 TO lnrandom
APPEND BLANK
ENDFOR
REPLACE ALL randnum WITH RAND()*lnrandom*100

DO WHILE notdone
SELECT dist randnum FROM rand_num1 INTO TABLE rand_num2 WHERE randnum>0
IF RECCOUNT()>=lnrandom
SELECT TOP lnrandom * FROM rand_num2 ORDER BY randnum INTO TABLE randnum_results
notdone=.f.
USE randnum_results
BROWSE NOWAIT
DROP TABLE rand_num1
DROP TABLE rand_num2
ELSE
lnMakeMore=lnrandom-RECCOUNT()
SELECT * from rand_num2 INTO TABLE rand_num1
FOR lnCounter = lnMakeMore TO lnrandom
APPEND BLANK
REPLACE randnum WITH RAND()*lnrandom*100
ENDFOR
ENDIF
ENDDO
 
The following will create a table of psuedo-random,
non-repeating numbers.

Darrell

[tt]
CREATE CURSOR tmp (RD N(18))
INDEX ON RD TAG MAIN CANDIDATE
SET ORDER TO

RAND(-1)
LOCAL i, j
j = 100
ON ERROR ErrHand(@j)

FOR i = 1 TO 100000 && Just do 100k for now
INSERT INTO tmp (RD) VALUES (RAND()*j)
NEXT
ON ERROR

PROCEDURE ErrHand(j)
j=j*1.05
RETRY
ENDPROC
[/tt]
 
rene316

If you want a truly garanteed unique number take a look at faq184-230.

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike,

The function I posted does create unique numbers since it uses a SELECT DISTINCT. My <slow> laptop ran 1,000,000 at an acceptable speed, but it did take ~2X longer than your code.

Brian
 
To respond to Lee, I used Rick's code 'rgbean'. Thank you all for all your responses. I appreciate all the help.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top