|
-
May 15th, 2008, 10:47 AM
#1
Random Number
The following allows you to pick a group random numbers from a range of numbers like -19099 to 107,
or 1 to 52. It returns an array of integers, dim x() as Integer, as the result.
An example:
Dim cards As Integer() = generateRandomNumbers(1, 52, 4) 'returns four random numbers between 1 and 52
cards = generateRandomNumbers(1, 52, 4, False) 'get four more - note the Pool is not cleared
You can also check to see if a number has been selected by using picked:
If picked(an integer goes here) Then doSomething
The following test
generateRandomNumbers(1, 100000, 100000)
took about 100 ms. on my 1.8Ghz laptop.
Many thanks to kleinma for his insights.
Code:
Module RandomNumberGenerator
'
'The following Function's can be used to generate a set of
'unique random numbers in a defined range.
'
'How it works:
'An array of bits, one for each possible number, is created. Initially all bits are set to 0
'Then a loop is started that:
' generate a random number between low and high inclusive
' check bit at random number selected
' - if 1 then selected, skip. if 0 then set it to 1, add number to array, increment count.
' continue loop till requested count is satisfied
'
'usage - generateRandomNumbers(low, high, howmany, new pool, exception)
'where:
' low = lowest number to be generated - negatives allowed
' high = highest number to be generated - negatives allowed
' howmany = how many numbers to generate between low and high inclusive
' new pool = (true / false) start with no numbers selected
' exception = (true / false) if true throw exception else return array of length 0
'
'the pool is all numbers from low to high inclusive e.g low = -3 high = 6
'-3 -2 -1 0 1 2 3 4 5 6
'size of the pool is 10
'
'the following are defined here intentionally
Public theRandomNumbers As New BitArray(1)
Public zeroPt As Integer = 0, genTime As Long, howManyAvail As Integer = 0
'
Public Function generateRandomNumbers _
(ByVal RangeLow As Integer, _
ByVal RangeHigh As Integer, _
ByVal QtyToGenerate As Integer, _
Optional ByVal NewPool As Boolean = True, _
Optional ByVal ExceptionOnError As Boolean = True) As Integer()
Dim LenPool As Integer
Dim TheReturn As Integer() = {} 'zero length return
Dim size As Integer = RangeHigh - RangeLow + 1 'size of pool
Dim GenRndm As New Random, ctHits As Integer = 0, num2Check As Integer, rndSTPW As New Stopwatch
If RangeLow >= RangeHigh Then 'is low greater or equal to high
If ExceptionOnError Then
Throw New System.Exception("Low must be less than High") 'low >= high not allowed
Else
Return TheReturn 'return array of length 0
End If
End If
If QtyToGenerate <= 0 Then 'generate zero or less
If ExceptionOnError Then
Throw New System.Exception("Quantitiy must be greater than zero")
Else
Return TheReturn 'return array of length 0
End If
End If
If size < QtyToGenerate Then
If ExceptionOnError Then
Throw New System.Exception("Quantitiy exceeds number available") 'low = 0 high = 2 gen =5????
Else
Return TheReturn 'return array of length 0
End If
End If
rndSTPW.Reset() : rndSTPW.Start() 'start the clock
' determine pool size
If Math.Abs(RangeLow) > Math.Abs(RangeHigh) Then LenPool = Math.Abs(RangeLow) Else LenPool = Math.Abs(RangeHigh)
If LenPool < Math.Abs(RangeHigh - RangeLow) Then LenPool = Math.Abs(RangeHigh - RangeLow)
theRandomNumbers.Length = LenPool + 1 'set size of random pool
If NewPool Then 'is this new pool
theRandomNumbers.SetAll(False) 'yes, set all to not selected
howManyAvail = size 'set how many available
Else 're-using the same pool
If howManyAvail < QtyToGenerate Then 'generate less than available
If ExceptionOnError Then 'yes
Throw New System.Exception("Quantitiy exceeds number available")
Else
Array.Resize(TheReturn, 0) 'return array of length 0
Return TheReturn
End If
End If
End If
Array.Resize(TheReturn, QtyToGenerate) 'set return size
'set zero point to handle any case {-3 -2 -1 0 1 2 3}
Select Case True
Case RangeLow >= 0
'0 1 2 3 low=0 high=3
zeroPt = 0
Case RangeHigh <= 0
'-3 -2 -1 0 low=-3 high=0
zeroPt = LenPool
Case RangeLow < 0
'-2 -1 0 1 low=-2 high=1
zeroPt = Math.Abs(RangeLow)
End Select
'finally, generate the random numbers
Do
num2Check = GenRndm.Next(RangeLow, RangeHigh + 1) 'get a random number
If Not theRandomNumbers(num2Check + zeroPt) Then 'picked previously
theRandomNumbers.Set(num2Check + zeroPt, True) 'no, mark it picked
TheReturn(ctHits) = num2Check 'add to return
ctHits += 1 'increment count
If ctHits >= QtyToGenerate Then Exit Do
End If
Loop
rndSTPW.Stop() 'stop the clock
howManyAvail -= ctHits
genTime = rndSTPW.ElapsedMilliseconds 'store time to generate numbers
Return TheReturn
End Function
Public Function Picked(ByVal number As Integer) As Boolean
If number > theRandomNumbers.Length - 1 Then Return False
If theRandomNumbers(number + zeroPt) Then Return True Else Return False
End Function
End Module
Last edited by dbasnett; May 31st, 2008 at 08:40 AM.
-
May 15th, 2008, 11:07 AM
#2
Re: Random Number
Any question..?
-
May 15th, 2008, 11:21 AM
#3
Re: Random Number
is this a tutorial? if so it really belongs in the codebank.
-
May 15th, 2008, 12:46 PM
#4
Re: Random Number
Sorry. I posted the code and when I realized I hadn't asked the question, my internet service decided to go to s**t. So.
I was hoping someone(s) could test the code, especailly since it allows you to pick random numbers in ranges of numbers like -10 to 10.
My testing indicates it works, and it performs very well, even in cases where you pick all the numbers randomly from 1 to 100000.
If it passes muster, and someone wants to put it in the code bank it is fine with me.
Last edited by dbasnett; Jun 2nd, 2008 at 06:51 PM.
-
May 15th, 2008, 12:48 PM
#5
Re: Random Number
I guess my first question would be why strings? you are generating numbers, so why return a string array?
-
May 15th, 2008, 01:07 PM
#6
Re: Random Number
I changed it to numeric in the original post.
-
May 15th, 2008, 01:25 PM
#7
Re: Random Number
On my 1.8Ghz laptop I performed the following test:
1 to 100,000 pick 100,000 numbers randomly. It took about 100 ms.
-
May 15th, 2008, 01:39 PM
#8
Re: Random Number
add more error handling incase a negative number is passed in as the QtyToGenerate param.
Also on that note, I would not return nothing in the events where there is bad user input to the method, I would throw exceptions.
-
May 15th, 2008, 02:15 PM
#9
Re: Random Number
Done. At least I think so.
BTW - thanks for the good insights.
Last edited by dbasnett; May 15th, 2008 at 02:33 PM.
-
May 15th, 2008, 03:27 PM
#10
Re: Random Number
Was it ready to be moved?
-
May 15th, 2008, 03:29 PM
#11
Re: Random Number
I don't see why not... from what I can tell it does what it is designed to do... codebank entries are not set in stone, you can improve on it if you find some way to.
-
May 16th, 2008, 07:46 AM
#12
Re: Random Number
i added an option that allows the user to decide what to do when there is an error.
default - throw eception.
alternative - return zero length array.
-
May 30th, 2008, 01:33 PM
#13
-
May 30th, 2008, 01:56 PM
#14
Re: Random Number
Fixed.
The problem was in setting the pool size. I found another scenario that also falied.
Last edited by dbasnett; May 31st, 2008 at 08:42 AM.
-
Jun 2nd, 2008, 12:02 PM
#15
-
Jun 2nd, 2008, 01:38 PM
#16
Re: Random Number
Sorry I didn't do a better job of testing. Thanks for your input.
-
Jun 2nd, 2008, 01:59 PM
#17
Re: Random Number
perhaps you should do a little learning on unit testing and write a testbed for your function...
I am not a big unit testing person myself (since I am in a single shop and write all the code here, although that isn't really a valid reason not to unit test) but unit testing is getting really really popular in most development circles, and can really help fix bugs before code ships by testing and logging many scenarios.
-
Jun 2nd, 2008, 07:01 PM
#18
Re: Random Number
I come from an old school that dictated testing was done early and often and by someone else. I did this for the fun of it, and only had me to test it. There were hundreds of test, but not once did I pick two positives as low and high(except 0 or 1 for low), mostly because I got sidetracked with negatives.
If this is the only error, and it was caught first time out, then this was a success.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|