Page 1 of 2 12 LastLast
Results 1 to 40 of 42

Thread: 15 randoom numbers out of 100

  1. #1

    Thread Starter
    Fanatic Member joltremari's Avatar
    Join Date
    Sep 2000
    Location
    Mississippi
    Posts
    674

    15 randoom numbers out of 100

    I need to pick 15 random numbers out of 100. I have searched the forums for help but can't seem to put to use what I've found. Any help is appreciated.

    JO
    "I have not failed. I've just found 10,000 ways that won't work."
    'Thomas Edison'

    "If we knew what it was we were doing it wouldn't be called research, would it?"
    'Albert Einstein'

    VB6

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: 15 randoom numbers out of 100

    Thread moved from the FAQ forum.

  3. #3
    Hyperactive Member Philly0494's Avatar
    Join Date
    Apr 2008
    Posts
    485

    Re: 15 randoom numbers out of 100

    when you say out of 100, do you mean 1-100? or like a set of 100 different numbers?

  4. #4
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: 15 randoom numbers out of 100

    Here's an example. I would probably wrap the code up into a more general/reusable function.

    Code:
    Private Function InArray(ByRef IntArray() As Integer, ByVal IntValue As Integer) As Boolean
        Dim i As Integer
        For i = LBound(IntArray) To UBound(IntArray)
            If IntArray(i) = IntValue Then
                InArray = True
                Exit For
            End If
        Next i
    End Function
    
    Private Sub Form_Load()
        Dim i As Integer, r As Integer
        Dim intPicked(1 To 15) As Integer
        Dim intFind As Integer
        Randomize
        
        For i = 1 To 15
            Do
                r = Int(Rnd * 100) + 1
            Loop Until Not InArray(intPicked, r)
            intPicked(i) = r
            Debug.Print i & vbTab & r
        Next i
        
        Erase intPicked
    End Sub

  5. #5
    Hyperactive Member Philly0494's Avatar
    Join Date
    Apr 2008
    Posts
    485

    Re: 15 randoom numbers out of 100

    Code:
    Private Sub cmdRandom_Click()
    List1.Clear
    Randomize
    Dim i As Integer
    Dim x As Integer
    Do While x < 15
    i = (Rnd(i + 8) * 100)
    List1.AddItem (i)
    x = x + 1
    Loop
    End Sub
    well this will only work if you want numbers between 1-100, otherwise just use digi

  6. #6
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: 15 randoom numbers out of 100

    Here's a slightly different approach. The following code generates 100 unique integers, scrambles them all, selects the first 15, and displays the results in a list box. These will be a randomly obtained set of unique integers.
    Code:
    Dim MyNums() As Integer, Temp As Integer
    Const PoolSize = 100, SampleSize = 15
    Private Sub Form_Load()
    ReDim MyNums(PoolSize)
    Randomize
    For I = 1 To PoolSize
        MyNums(I) = I
    Next
    For I = 1 To PoolSize
        Temp = Int(Rnd * PoolSize) + 1
        MyNums(Temp) = MyNums(I)
        MyNums(I) = Temp
    Next
    For I = 1 To SampleSize
        List1.AddItem MyNums(I)
    Next
    End Sub
    Doctor Ed

  7. #7
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Code Doc's approach is the preferred one, but on closer inspection his shuffling algorithm looks flawed. In fairness, I don't know why it's flawed, but it is. Knuth's shuffle isn't supposed to randomly pick from the entire list, but instead randomly pick from only the as-yet-unshuffled part of the list. Again, I don't know why, but that's how it's supposed to work.

    Here's some code:
    Code:
    Private Sub Form_Load()
        Randomize
    End Sub
    
    Private Sub Command1_Click()
        Dim lngArray(1 To 100)
        Dim i As Long
        
        For i = 1 To 100
            lngArray(i) = i
        Next
        ShuffleArray lngArray
        List1.Clear
        For i = 1 To 15
            List1.AddItem lngArray(i)
        Next
    End Sub
    
    ' Knuth shuffle (very fast)
    Public Sub ShuffleArray(pvarArray As Variant)
        Dim i As Long
        Dim iMin As Long
        Dim iMax As Long
        Dim lngReplace As Long
        Dim varSwap As Variant
        
        iMin = LBound(pvarArray)
        iMax = UBound(pvarArray)
        For i = iMax To iMin + 1 Step -1
            lngReplace = Int((i - iMin + 1) * Rnd + iMin)
            varSwap = pvarArray(i)
            pvarArray(i) = pvarArray(lngReplace)
            pvarArray(lngReplace) = varSwap
        Next
    End Sub
    Last edited by Ellis Dee; May 23rd, 2008 at 12:00 AM.

  8. #8
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: 15 randoom numbers out of 100

    The only 'problem' with Code_Doc's approach is that it's possible for duplicate numbers to be selected and will marginally affect the overall 'randomness'.

  9. #9
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Doogle
    The only 'problem' with Code_Doc's approach is that it's possible for duplicate numbers to be selected
    heh, that's a much bigger flaw than the one I was talking about.

  10. #10
    Head Hunted anhn's Avatar
    Join Date
    Aug 2007
    Location
    Australia
    Posts
    3,669

    Re: 15 randoom numbers out of 100

    This is another approach that use a collection.
    Someone may say it's not very good if [Sample] equals or nearly equals to [Pool].
    Code:
    Function RandomPick(Pool As Long, Sample As Long) As Long()
        '-- Randomly pick [Sample] numbers from a pool of numbers from 1 to [Pool]
        Dim myColl As New Collection
        Dim arPick() As Long, n As Long, i As Long
        
        If (Pool <= 0) Or (Sample <= 0) Or (Pool < Sample) Then
            ReDim RandomPick(0) '-- noted that lowerbound = 0 here
            Exit Function
        End If
        
        Randomize
        On Error Resume Next
        Do Until myColl.Count >= Sample
            n = Int(Rnd * Pool) + 1
            myColl.Add n, Str(n)
        Loop
        On Error GoTo 0
            
        ReDim arPick(1 To myColl.Count) '-- noted that lowerbound = 1 here
        For i = 1 To myColl.Count
            arPick(i) = myColl.Item(i)
        Next
        Set myColl = Nothing
        RandomPick = arPick
    End Function
    Code:
    '--Usage:
        Dim arPick() As Long, i As Long
        
        arPick = RandomPick(100, 15)
        For i = 1 To UBound(arPick)
            Debug.Print arPick(i)
        Next
    Last edited by anhn; May 23rd, 2008 at 01:10 AM.
    • Don't forget to use [CODE]your code here[/CODE] when posting code
    • If your question was answered please use Thread Tools to mark your thread [RESOLVED]
    • Don't forget to RATE helpful posts

    • Baby Steps a guided tour
    • IsDigits() and IsNumber() functions • Wichmann-Hill Random() function • >> and << functions for VB • CopyFileByChunk

  11. #11
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: 15 randoom numbers out of 100

    I'm all for optimized/perfect code but seems kind of overkill if the guy just wants a simple way to pick out 15 random numbers from 1-100.

  12. #12
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: 15 randoom numbers out of 100

    In addition to stating requirements more clearly (post#3), apt code also depends on use, e.g. simulate drawing from deck of cards.

  13. #13
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Doogle
    The only 'problem' with Code_Doc's approach is that it's possible for duplicate numbers to be selected and will marginally affect the overall 'randomness'.
    Doogle is correct, that could happen during the shuffle, so swaps could be cancelled out. That is possible with any selection of random numbers. You could randomly select 100 integers form 1 to 100 in sequence that were all the same--improbable but possible. Does "forcing" a non-duplicate swap improve the randomness? I don't think it does. In fact that could distort the solution.

    Using Monte Carlo simulation techniques, I have checked using Chi-Square the scrambling routine I posted above. After N = 50% of the original array is swapped randomly, the scrambled distribution no longer statistically resembles the sorted one. I have checked this using hundreds of iterations. So, my swapping 100% of the original array of the code above is probably overkill.
    Last edited by Code Doc; May 23rd, 2008 at 12:53 PM.
    Doctor Ed

  14. #14
    Discovering Life Siddharth Rout's Avatar
    Join Date
    Feb 2005
    Location
    Mumbai, India
    Posts
    12,001

    Re: 15 randoom numbers out of 100

    This is my version

    Code:
    Sub RandNos()
        Dim nums() As Integer
        Dim maxval As Integer
        Dim Ptr As Integer
        Dim j As Integer, k As Integer
        Randomize
        
        'Change this value as per you requirements
        'Currently you want 15 random numbers out of 100
        maxval = 100
        
        ReDim nums(maxval, 2)
    
        'Fill the initial array
        For j = 1 To maxval
            nums(j, 1) = j
            nums(j, 2) = Int((Rnd * maxval) + 1)
        Next j
    
        'Sort the array based on the random numbers
        For j = 1 To maxval - 1
            Ptr = j
            For k = j + 1 To maxval
                If nums(Ptr, 2) > nums(k, 2) Then Ptr = k
            Next k
            If Ptr <> j Then
                k = nums(Ptr, 1)
                nums(Ptr, 1) = nums(j, 1)
                nums(j, 1) = k
                k = nums(Ptr, 2)
                nums(Ptr, 2) = nums(j, 2)
                nums(j, 2) = k
            End If
        Next j
    
        'Generate 15 Random Numbers
        Ptr = 0
        For k = 1 To 15
            Ptr = Ptr + 1
                'you can output it wherever you want
                MsgBox nums(Ptr, 1)
        Next k
    End Sub
    Hope this helps...
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved


    MyGear:
    ★ CPU ★ Ryzen 5 5800X
    ★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
    ★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
    ★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
    ★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
    ★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
    ★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
    ★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
    ★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
    ★ Keyboard ★ TVS Electronics Gold Keyboard
    ★ Mouse ★ Logitech G502 Hero

  15. #15
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Code Doc
    Doogle is correct, that could happen during the shuffle, so swaps could be cancelled out. That is possible with any selection of random numbers.
    The reason it's allowing duplicates is because you are using the random number as both an array index and an array value, which is odd. It works for this particular application so it's all good, but it's a quirky thing. And that's the only reason that duplicates could be introduced. To avoid the duplicates is a simple fix:
    Code:
    For I = 1 To PoolSize
        Temp = Int(Rnd * PoolSize) + 1
        SwapValue = MyNums(Temp)
        MyNums(Temp) = MyNums(I)
        MyNums(I) = SwapValue
    Next
    I would point out that without this modification, your solution is functionally equivalent to just populating a 100-element array with random numbers and not swapping any elements at all.
    Quote Originally Posted by Code Doc
    Using Monte Carlo simulation techniques, I have checked using Chi-Square the scrambling routine I posted above. After N = 50% of the original array is swapped randomly, the scrambled distribution no longer statistically resembles the sorted one. I have checked this using hundreds of iterations. So, my swapping 100% of the original array of the code above is probably overkill.
    This is over my head mathematically. All I know about shuffling is that it is a problem that is considered to be solved. I just this minute learned that Donald Knuth didn't invent it, but rather popularized it. But hey, I think the "Knuth Shuffle" sounds way cooler than the Fisher-Yates Shuffle, so I'm keeping the name. Note that most of those articles make a big deal about bias, which can be quite tricky when devising a shuffling algorithm.

  16. #16
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: 15 randoom numbers out of 100

    Code Doc is also quite right.

    There's a difference between 'a selection of Random Numbers' and 'a Random selection of Numbers'. (I believe that the OP was after the latter.)

    The former requires a distribution such that the probability of selection of any number is the same for each number in the Distribution and does not change. (brief definitinon of a Random Distribution)

    The latter requires a 'selection method' such that the probability of selecting a given number is the same for each number.

    My 'Logic' was to say that if I had a set of integer numbers between 1 and 100 inclusive, the probability of any given number being returned from the selection process should be 0.01 (1/100). If I then replaced the number '100' with the number '1' the probability of the selection process returnig a '1' is now 0.02 whilst the probability of returing any of the other numbers remains at 0.01. Hence the 'randomness' of the selection result is marginally affected. The probablity of selecting any given element in the list of numbers remains the same (0.01). Clear as mud

    EDIT: It's a bit like "Deal or no Deal", the contestant randomly selects a box but it's what's inside the box that's important. If there were two boxes with 1 pence (UK) in them then I suspect the show would lose it's popularity.

    Saying all that, I learnt a long time ago that Logic and Statistics do not necessarily always share the same space.
    Last edited by Doogle; May 24th, 2008 at 02:38 AM.

  17. #17
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: 15 randoom numbers out of 100

    Doogle said, "... Saying all that, I learnt a long time ago that Logic and Statistics do not necessarily always share the same space."
    ----------------
    +1! and look at it his way. Suppose I somehow managed in 100 tries to obtain 50 duplicate swaps during the shuffle that canceled each other out. The odds of even doing that are unbelievably small. Then I somehow do another 50 swaps that do not cancel each other out and you still have a random scramble.

    That's why when I ran my Chi Square goodness of fit test 1000 times or so with 1000 different shuffles, I never could produce a shuffled array that resembled the original array. Here's a discussion of Chi Square:
    http://www2.chass.ncsu.edu/garson/pa765/chisq.htm

    Simply line up the arrays (1 to 100) in two columns, calculate the Chi Square, and throw the results into a list box or message box. Then repeat the shuffle as many times as you want, calculating Ch Square each time. It's amazing how fast the PC can do this. The larger the Chi Square, the less likely the distributions agree:
    Code:
    Dim MyNums() As Integer, Temp As Integer
    Const PoolSize = 100, SampleSize = 15
    
    Private Sub Command1_Click()
    Dim ChiSq As Single
    ReDim MyNums(PoolSize)
    Randomize
    For I = 1 To PoolSize
        MyNums(I) = I
    Next
    For I = 1 To PoolSize
        Temp = Int(Rnd * PoolSize) + 1
        MyNums(Temp) = MyNums(I)
        MyNums(I) = Temp
    Next
    ' Now Calculate Chi Square
    For I = 1 To PoolSize
        ChSq = ChSq + (MyNums(I) - I) ^ 2 / I
    Next
    List1.AddItem Format$(ChSq, "###,###.00")
    End Sub
    The null hypothesis is that the original array and the shuffled array are the same after shuffling. You need to see a value of Chi Square that exceeds 140 to reject that hypothesis with the probability of being wrong at 0.005. I've never calculated a Chi-Square value less than 2,000 in over 1,000 tries with either PoolSize or PoolSize/2 swaps.
    Doctor Ed

  18. #18
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: 15 randoom numbers out of 100

    However, with a (for example) PoolSize = 4 and SampleSize = 2 it goes a bit Pear shaped.

  19. #19
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Wikipedia says that Code Doc's method has a bias. (It's never a good sign when your algorithm shows up in the "Implementation Errors" section of a wikipedia article. heh.) This is almost certainly responsible for the "pear shaped" results using very small pools.
    Similarly, always selecting k from the entire range of valid array indexes on every iteration (i.e. using k = rng.nextInt(array.length) in the Java example above) also produces a result which is biased, albeit less obviously so. This can be seen from the fact that doing so yields NN distinct possible sequences of swaps, whereas there are only N! possible permutations of an N-element array. Since NN can never be evenly divisible by N! (as the latter is divisible by N−1, which shares no prime factors with N), some permutations must be produced by more of the NN sequences of swaps than others.
    Again, the problem of shuffling a list has already been solved. The Knuth shuffle is the preferred method.

  20. #20
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: 15 randoom numbers out of 100

    Ellis Dee said, "Again, the problem of shuffling a list has already been solved. The Knuth shuffle is the preferred method."
    ------------------
    Looks interesting. Actually, it would be easy to modify my code so that you exit the swap loop faster when the criterion is met. It looks like that a simple modification of just swapping PoolSize/2 times rather than PoolSize times would not be too bad. The concern appears to be that too many swaps can actually work against you, even though PoolSize swaps would run very fast for even an enormous array.

    Hmmm... Ellis, I wonder if we could merge the two ideas of using Chi Square calculations with an incremental number of random swaps to determine when to actually terminate the swapping? For example, in the current case where Chi Square exceeds 200 or so, you stop swapping. I think the stochastic approach to the shuffle still has some merit. When to stop swapping is a function of the array size, of course, so the Chi Square stopping criterion would have to be adjusted.

    On second thought, that won't work. If only a few extreme cases within the array get swapped early (such as 1 and 100 or 2 and 99), the critical value of Chi Square would be exceeded and I assure you that the new array would not be random.
    Last edited by Code Doc; May 24th, 2008 at 02:42 PM.
    Doctor Ed

  21. #21
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Code Doc
    It looks like that a simple modification of just swapping PoolSize/2 times rather than PoolSize times would not be too bad. The concern appears to be that too many swaps can actually work against you, even though PoolSize swaps would run very fast for even an enormous array.
    Nitpick: It's actually PoolSize-1 swaps, not PoolSize. Anyway, the advantage of PoolSize-1 swaps is that it generates every possible permutation an equal number of times. Messing with the number of swaps unbalances the number of possible permutations you can end up with, which means you'll end up with a (slightly) biased shuffle.

    Bias is a tricky thing when trying to shuffle. Best not to tinker with a known, unbiased solution.

  22. #22
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by koolsid
    This is my version (link)
    According to that wikipedia article, the method of assigning each element a random number and then sorting by the random numbers has a bias if you don't force each random number to be unique. The reason is that the way sorting algorithms handle duplicate keys isn't random. And looking at your algorithm, it appears you're using Insertion Sort as the sorting algorithm, which is a stable sort. So any duplicate keys will retain their original order.

    Even with unstable algorithms, the final order of duplicate keys is not easily predictable, but they are not technically random.

    To illustrate, consider if your first random number is 37, which gets assigned to 1. You're generating 99 more random keys, and if any of them are also 37 -- actually a fairly high probability -- then those elements are forced to be after element 1 due to the stable sorting algorithm.

    In short, this method has a subtle bias favoring lower numbers ending up earlier in the list.
    Last edited by Ellis Dee; May 24th, 2008 at 02:52 PM.

  23. #23
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: 15 randoom numbers out of 100

    OK, I have revised my code to use Donald Knuth's algorithm method to perform the random swaps. I believe this looks good:
    Code:
    Dim MyNums() As Integer, Temp As Integer
    Dim RangeLimit As Integer, SwapValue As Integer
    Const PoolSize = 100, SampleSize = 15
    
    Private Sub Command1_Click()
    ReDim MyNums(PoolSize)
    Randomize
    For I = 1 To PoolSize
        MyNums(I) = I
    Next
    RangeLimit = PoolSize
    While RangeLimit > 1
        Do
            Temp = Int(Rnd * RangeLimit) + 1
            If Temp <> RangeLimit Then Exit Do
        Loop
        SwapValue = MyNums(Temp)
        MyNums(Temp) = MyNums(RangeLimit)
        MyNums(RangeLimit) = SwapValue
        RangeLimit = RangeLimit - 1
    Wend
    List1.Clear
    For I = 1 To SampleSize
        List1.AddItem Str$(MyNums(I))
    Next
    End Sub
    Note that this appears to knock out the possibility of identical swaps while limiting the number of swaps to the PoolSize. However, you will likely generate more than PoolSize random numbers because occasionally the random number (Temp) will equal the RangeLimit that is being constantly reduced inside the While ... Wend loop. That is likely a small sacrifice if bias is removed. My results indicate that only about 5 to 10% more swaps will occur and sometimes no additional swaps are required.

    Thanks, Ellis. I'll adjust my future scarmbling routines accordingly if this also looks good to you and to the rest of the forum.
    Doctor Ed

  24. #24
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: 15 randoom numbers out of 100

    Looks (very) good to me

  25. #25
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Code Doc
    I'll adjust my future scarmbling routines accordingly if this also looks good to you and to the rest of the forum.
    It is still biased, though in a different way. When looping through and doing the swapping, the swap pool needs to be all the remaining elements including the one you're on. You are forcing it to be different than the current one, so it introduces a fairly obvious bias: whatever element starts in last place cannot possibly end up in last place. Imagine you're shuffling an array of two elements; with this implementation, your algorithm will only allow exactly one possible outcome. An unbiased algorithm would end up with two possible outcomes, both equally likely.

    As I said, bias is a tricky thing when dealing with shuffling algorithms. Best not to try and reinvent the wheel, but rather just stick with what works. I posted the finished solution as my first post in this thread. It includes a self-contained function for doing an unbiased Knuth shuffle on any array. Here is my post again:
    vb Code:
    1. Private Sub Form_Load()
    2.     Randomize
    3. End Sub
    4.  
    5. Private Sub Command1_Click()
    6.     Dim lngArray(1 To 100)
    7.     Dim i As Long
    8.    
    9.     For i = 1 To 100
    10.         lngArray(i) = i
    11.     Next
    12.     ShuffleArray lngArray
    13.     List1.Clear
    14.     For i = 1 To 15
    15.         List1.AddItem lngArray(i)
    16.     Next
    17. End Sub
    18.  
    19. ' Knuth shuffle (very fast)
    20. Public Sub ShuffleArray(pvarArray As Variant)
    21.     Dim i As Long
    22.     Dim iMin As Long
    23.     Dim iMax As Long
    24.     Dim lngReplace As Long
    25.     Dim varSwap As Variant
    26.    
    27.     iMin = LBound(pvarArray)
    28.     iMax = UBound(pvarArray)
    29.     For i = iMax To iMin + 1 Step -1
    30.         lngReplace = Int((i - iMin + 1) * Rnd + iMin)
    31.         varSwap = pvarArray(i)
    32.         pvarArray(i) = pvarArray(lngReplace)
    33.         pvarArray(lngReplace) = varSwap
    34.     Next
    35. End Sub

  26. #26
    PowerPoster Code Doc's Avatar
    Join Date
    Mar 2007
    Location
    Omaha, Nebraska
    Posts
    2,354

    Re: 15 randoom numbers out of 100

    Ellis Dee said, "It is still biased, though in a different way. When looping through and doing the swapping, the swap pool needs to be all the remaining elements including the one you're on. You are forcing it to be different than the current one,...."
    ----------
    Good point, but in my own defense, let's look at the wording of the publication you directed me to read. The instructions for Durstenfield's version of the Knuth shuffle include the following two steps:

    1. Build an array of n values.
    2. Pick a random number k between 1 and n inclusive (n = array size).
    3. If k <> n, swap the kth and nth values of the array.
    4. Decrease n by 1.
    5. Repeat from step 2 until n is less than 2.

    That's what I tried to program in VB6. Note that step 3 above insists that k <> n, and that's why I include the Do ... Loop in my code to block it. If we eliminate that Do .... Loop filter, then that allows the array element to be swapped with itself and no shuffle would occur should the random number that is generated equal the current array element.

    Perhaps Durstenfield was concerned that for small arrays, you could have the same random number (though not likely) generated n times and the shuffle thus "dies" as it manages to produce an array that is identical to the original.
    Doctor Ed

  27. #27
    Junior Member Barqers's Avatar
    Join Date
    May 2008
    Location
    Canada
    Posts
    28

    Re: 15 randoom numbers out of 100

    Code:
    For X = 0 to 14
          Num(X) = INT(RND * 100) + 1
    Next X
    Now you have 15 numbers all between 1 and 100, stored into an array of Num(14)

    P.s don't forget the Randomize Timer function. Unless you want a sudo random output.

    And why the heck is everyone's code so long and complicated, I think this is all he wanted?
    Great painters paint, Famous painters steal.


    François



  28. #28
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Barqers
    And why the heck is everyone's code so long and complicated, I think this is all he wanted?
    Yes your code if fine if you don't mind getting the same number more then once, Ellis's ShuffleArray code seems more of a non-repeatable random.

  29. #29
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Barqers
    And why the heck is everyone's code so long and complicated, I think this is all he wanted?
    Everyone else's code is longer because they are preventing duplicates.

  30. #30
    Junior Member Barqers's Avatar
    Join Date
    May 2008
    Location
    Canada
    Posts
    28

    Re: 15 randoom numbers out of 100

    Oh, okay.
    Great painters paint, Famous painters steal.


    François



  31. #31
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Code Doc
    Good point, but in my own defense, let's look at the wording of the publication you directed me to read. The instructions for Durstenfield's version of the Knuth shuffle include the following two steps:

    1. Build an array of n values.
    2. Pick a random number k between 1 and n inclusive (n = array size).
    3. If k <> n, swap the kth and nth values of the array.
    4. Decrease n by 1.
    5. Repeat from step 2 until n is less than 2.

    That's what I tried to program in VB6. Note that step 3 above insists that k <> n, and that's why I include the Do ... Loop in my code to block it.
    [...]
    Perhaps Durstenfield was concerned that for small arrays, you could have the same random number (though not likely) generated n times and the shuffle thus "dies" as it manages to produce an array that is identical to the original.
    Just to clarify, I'm not criticizing you. It's a very easy mistake to make, as evidenced by the fact that it is specifically mentioned in the "implementation errors" section. That section would be blank if these weren't commonly made errors.

    Durstenfield's algorithm is the one from my implementation. The only difference is that if k = n, I go ahead and swap them anyway. I consider that inefficiency negligible, and it slightly reduces the code complexity.

    Step 2 is the critical one. "Pick a random number k between 1 and n inclusive." The value "n" isn't the array size, but rather the looping value, as we can see from step 4. (Decrease n by 1.) The key word in step 2 is "inclusive." In other words, when randomly picking numbers, n is a valid choice.

    Step 3 tells us that we can skip swapping if the randomly chosen element is the element we're swapping with. It saves cpu cycles by not bothering to swap an element with itself. It doesn't add any other command to that case; eg: there is no directive to repeat step 2 until k <> n.

    So if in step 3, the random number chosen is n, we do nothing and then move on to step 4: Decrease n by 1 and go back to step 2.

    I agree that the wording can easily be misinterpreted. When you already know what it's supposed to do, it's clear that the wording is very carefully chosen and quite precise. But IMO, anyone unfamiliar with the algorithm is likely to to fall into a similar trap as the one you did.
    Last edited by Ellis Dee; May 28th, 2008 at 06:24 PM.

  32. #32
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Edgemeal
    Ellis's ShuffleArray code
    It's clearly not my algorithm, but even further it's not really my code, either. I originally adapted it from code posted by Logophobic.

    Credit where credit's due.

  33. #33
    Junior Member Barqers's Avatar
    Join Date
    May 2008
    Location
    Canada
    Posts
    28

    Re: 15 randoom numbers out of 100

    When I run this code, I get a runtime 424 error towards the list1.additem or list1.clear

    Why is this?
    Great painters paint, Famous painters steal.


    François



  34. #34
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    Quote Originally Posted by Barqers
    When I run this code, I get a runtime 424 error towards the list1.additem or list1.clear

    Why is this?
    Because you don't have a Listbox named List1 on your form. Change the code to reflect the actual name of your listbox, or if you aren't using a listbox remove that whole section of code and just display the first 15 array elements however you please.

  35. #35
    Junior Member Barqers's Avatar
    Join Date
    May 2008
    Location
    Canada
    Posts
    28

    Re: 15 randoom numbers out of 100

    Ohhh, that would make A LOT of sense.

    Thank you =]

    Fran&#231;ois
    Great painters paint, Famous painters steal.


    François



  36. #36
    Head Hunted anhn's Avatar
    Join Date
    Aug 2007
    Location
    Australia
    Posts
    3,669

    Re: 15 randoom numbers out of 100

    Bias or not bias? Do we need to prove that the Rnd() function is not bias or just assume that?

    Below is the proof of the algorithm used by Ellis in post#25.
    Random Shuffles

    This is more difficult. We have a list (x1,..., xn) and we want to shuffle it randomly.
    The following, surprisingly simple, algorithm does the trick:
    Code:
    algorithm shuffle(x,n)   // shuffle x1,..., xn 
    begin 
      for i = n downto 2 begin 
        k = irand(1,i) 
        swap over xi and xk 
      end 
    end
    Why does this work? It seems that it is not doing enough 'mixing up' to produce a genuinely random shuffle. We can only prove that it works if we have some notion of what we mean by a 'random shuffle'. Let me keep things simple and say that a shuffling process is random if each element of the list can end up in any position in the list with equal probability. That is to say, in a list of n items there are n possible places that any given element can eventually occupy. I want each of these places to be equally likely.

    So we now have to calculate the probability that our algorithm puts element xi into position j, where 1 <= i, j <= n. If you look carefully at the algorithm you will see that element xi end up in position j if it is not chosen on the first n - j steps of the algorithm and is chosen on the step n - j + 1. Since we know that irand(n, m) is genuine we can use elementary methods to find that the probability of xi ending up in position j is
    Code:
    n-1   n-2   n-3          j    1     j   1     1
    --- · --- · --- · ··· · --- · -  =  - · -  =  -
     n    n-1   n-2         j+1   j     n   j     n
    which is exactly what we wanted.
    • Don't forget to use [CODE]your code here[/CODE] when posting code
    • If your question was answered please use Thread Tools to mark your thread [RESOLVED]
    • Don't forget to RATE helpful posts

    • Baby Steps a guided tour
    • IsDigits() and IsNumber() functions • Wichmann-Hill Random() function • >> and << functions for VB • CopyFileByChunk

  37. #37
    Junior Member Barqers's Avatar
    Join Date
    May 2008
    Location
    Canada
    Posts
    28

    Re: 15 randoom numbers out of 100

    Okay so i understand the lngArray() numbers which we are shuffling. i is the range of numbers which lngArray() gets stored. iMin is the minimum number in the range while iMax is the maximum number in the range. And I also understand the Ubound is the highest number of the number placed in brackets? and Lbound the opposite? Sort of ? not too sure on those concepts, BUT

    what does pvarArray do...
    what does varSwap do...
    AND last but not least,
    what does lngReplace do?

    are these just variables which toss around the numbers? Like I'm understanding pretty much all the code except for:
    Code:
            lngReplace = Int((i - iMin + 1) * Rnd + iMin)
            varSwap = pvarArray(i)
            pvarArray(i) = pvarArray(lngReplace)
            pvarArray(lngReplace) = varSwap
    This is the original code from post #7 (Ellis Dee):
    Code:
    Private Sub Form_Load()
        Randomize
    End Sub
    
    Private Sub Command1_Click()
        Dim lngArray(1 To 100)
        Dim i As Long
        
        For i = 1 To 100
            lngArray(i) = i
        Next
        ShuffleArray lngArray
        List1.Clear
        For i = 1 To 15
            List1.AddItem lngArray(i)
        Next
    End Sub
    
    ' Knuth shuffle (very fast)
    Public Sub ShuffleArray(pvarArray As Variant)
        Dim i As Long
        Dim iMin As Long
        Dim iMax As Long
        Dim lngReplace As Long
        Dim varSwap As Variant
        
        iMin = LBound(pvarArray)
        iMax = UBound(pvarArray)
        For i = iMax To iMin + 1 Step -1
            lngReplace = Int((i - iMin + 1) * Rnd + iMin)
            varSwap = pvarArray(i)
            pvarArray(i) = pvarArray(lngReplace)
            pvarArray(lngReplace) = varSwap
        Next
    End Sub
    If someone wouldn't mind explaining each step individually that'd be much appreciated.
    Great painters paint, Famous painters steal.


    François



  38. #38
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: 15 randoom numbers out of 100

    A bit off-topic, but I don't see the harm.

    what does pvarArray do...
    pvarArray is a variant array. It's really just a regular ol' variant, but the name is meant to convey that it will accept an array. Variants can accept any typed array -- except UDTs -- so this makes the function nice and versatile. It means we can shuffle string arrays, long arrays, date arrays, etc...

    what does varSwap do...
    varSwap is a variant that will temporarily hold an array value during the swap. Whenever swapping two values, you save the first to a temp variable, overwrite the first with the second, then overwrite the second with the temp variable. This also must be a variant in order to maintain the versatility discussed above.

    what does lngReplace do?
    lngReplace is the randomly generated array index of the element we want to swap the current element with.

    I'm understanding pretty much all the code except for:
    Code:
            lngReplace = Int((i - iMin + 1) * Rnd + iMin)
            varSwap = pvarArray(i)
            pvarArray(i) = pvarArray(lngReplace)
            pvarArray(lngReplace) = varSwap
    The first line identifies which element we want to swap with. Random numbers are generated using the following formula:

    Int((Maximum - Minimum + 1) * Rnd + Minimum)

    The actual code is:

    lngReplace = Int((i - iMin + 1) * Rnd + iMin)

    We can see through simple substitution that the Maximum is i, and the minimum is iMin. This is consistent with how the algorithm is supposed to work.

  39. #39
    New Member
    Join Date
    Mar 2010
    Posts
    12

    Re: 15 randoom numbers out of 100

    I'm a VB6 quasi-rookie but I have a task for which I need your assistance. I have 10 forms, each has 4 sound files. The request is that I have the forms and audio files randomized (each playing only once) and all lead to a response form (same one). Would it be best to create an array of 40 different forms or can it be done without the duplication. If so, what would the code be (of those above) and where would it go (Module, form?)?
    --feel free to point at laugh

  40. #40
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: 15 randoom numbers out of 100

    vdriscoll, recommend starting your own thread. Hijacking others' threads isn't appropriate.
    Hijacking: using thread for your own questions/problems
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

Page 1 of 2 12 LastLast

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