Results 1 to 18 of 18

Thread: Random Number

Threaded View

  1. #1

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    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.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width