Random numbers in VB.net not random...weird?

gknuth
gknuth used Ask the Experts™
on
This is related to the last question I wrote about generating random numbers in VB.NET, but I'll repost the details, here, too.

I need to generate six unique random numbers between 7 and 20 for a dart board application that I'm writing.  It's to simulate wildcard cricket, for those that are familiar.

The code that I have seemingly generates random numbers, but something I've done or some aspect of the random number generator is making the results pretty far from random.  The following code results in the exact same sequence of numbers every time my sub is called.  Each time I re-run the sub, it generates new numbers, but it's always the same numbers, for example:

first refresh results 9,15,16,17,10,7
second refresh results 18,13,12,15,8,7
third refresh results 11,18,19,13,10,8
fourth refresh results 12,9,7,13,16,11
...and so on

It's like this every single time I run the app, the same numbers in the same sequence.  I tried it with one rnd and with one for each intSlot var (as in the sample code), but the results are exactly the same either way.

My guess, since I'm not a very good coder, is that it has to do with my logic that tries to pick unique numbers, but it's so weird that it does the same numbers each time that I just can't tell for sure.

So, any guidance would be much appreciated.  EE has been awesome with this...couldn't have gotten this far without it!

Here's the code:

Public Sub GenWildCard()

        'initialize random number generator
        Static rnd1 As New Random(20)
        Static rnd2 As New Random(20)
        Static rnd3 As New Random(20)
        Static rnd4 As New Random(20)
        Static rnd5 As New Random(20)
        Static rnd6 As New Random(20)

        If Not intSlot1Lock = 1 Then

            intSlot1 = rnd1.Next(7, 20)
            If intSlot1 = intSlot5 Or intSlot1 = intSlot4 Or intSlot1 = intSlot3 Or intSlot1 = intSlot6 Or intSlot1 = intSlot2 Then
                Do Until intSlot1 <> intSlot5 And intSlot1 <> intSlot4 And intSlot1 <> intSlot3 And intSlot1 <> intSlot6 And intSlot1 <> intSlot2

                    intSlot1 = rnd1.Next(7, 20)
                Loop
            End If
            lblSlot1.Text = intSlot1
        End If

        If Not intSlot2Lock = 1 Then
            intSlot2 = rnd2.Next(7, 20)
            If intSlot2 = intSlot5 Or intSlot2 = intSlot4 Or intSlot2 = intSlot3 Or intSlot2 = intSlot6 Or intSlot2 = intSlot1 Then
                Do Until intSlot2 <> intSlot5 And intSlot2 <> intSlot4 And intSlot2 <> intSlot3 And intSlot2 <> intSlot6 And intSlot2 <> intSlot1

                    intSlot2 = rnd2.Next(7, 20)
                Loop
            End If
            lblSlot2.Text = intSlot2
        End If

        If Not intSlot3Lock = 1 Then
            intSlot3 = rnd3.Next(7, 20)
            If intSlot3 = intSlot5 Or intSlot3 = intSlot4 Or intSlot3 = intSlot6 Or intSlot3 = intSlot2 Or intSlot3 = intSlot1 Then
                Do Until intSlot3 <> intSlot5 And intSlot3 <> intSlot4 And intSlot3 <> intSlot6 And intSlot3 <> intSlot2 And intSlot3 <> intSlot1

                    intSlot3 = rnd3.Next(7, 20)
                Loop
            End If
            lblSlot3.Text = intSlot3
        End If

        If Not intSlot4Lock = 1 Then
            intSlot4 = rnd4.Next(7, 20)
            If intSlot4 = intSlot5 Or intSlot4 = intSlot6 Or intSlot4 = intSlot3 Or intSlot4 = intSlot2 Or intSlot4 = intSlot1 Then
                Do Until intSlot4 <> intSlot5 And intSlot4 <> intSlot6 And intSlot4 <> intSlot3 And intSlot4 <> intSlot2 And intSlot4 <> intSlot1

                    intSlot4 = rnd4.Next(7, 20)
                Loop
            End If
            lblSlot4.Text = intSlot4
        End If

        If Not intSlot5Lock = 1 Then
            intSlot5 = rnd5.Next(7, 20)
            If intSlot5 = intSlot6 Or intSlot5 = intSlot4 Or intSlot5 = intSlot3 Or intSlot5 = intSlot2 Or intSlot5 = intSlot1 Then
                Do Until intSlot5 <> intSlot6 And intSlot5 <> intSlot4 And intSlot5 <> intSlot3 And intSlot5 <> intSlot2 And intSlot5 <> intSlot1
                    intSlot5 = rnd5.Next(7, 20)
                Loop
            End If
            lblSlot5.Text = intSlot5
        End If

        If Not intSlot6Lock = 1 Then
            intSlot6 = rnd6.Next(7, 20)
            If intSlot6 = intSlot5 Or intSlot6 = intSlot4 Or intSlot6 = intSlot3 Or intSlot6 = intSlot2 Or intSlot6 = intSlot1 Then
                Do Until intSlot6 <> intSlot5 And intSlot6 <> intSlot4 And intSlot6 <> intSlot3 And intSlot6 <> intSlot2 And intSlot6 <> intSlot1
                    intSlot6 = rnd6.Next(7, 20)
                Loop
            End If
            lblSlot6.Text = intSlot6
        End If

    End Sub

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
By always specifying 20 as your seed, you will always get the same sequence.  If you simply omit the 20 (ie, use Random by itself), the system will use a time-based seed.

You should also consider having a single instance of Random instead of six instances.  It will probably simplify your code quite a bit.

Author

Commented:
So, the seed is 20 when I use:

dim rnd as new Random(20)

but I can leave it blank (which uses milliseconds by default, right?), then use rnd.next(7,20) to specify the range?

I'll give it a shot and report back.

Thanks!

Commented:
and also instead of using 6 random generators to generate random numbers define one random object and use .next method to get the next random number.
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Author

Commented:
Man, do I love this site. Thanks dude!

Commented:
If you want your first six numbers to be unique, try this function.  Because you're dealing with random numbers uniqueness cannot be guaranteed (by this algorithm) but you can increase the likelihood further by increasing kLim.  Note that your range of legal values must be large enough also.
Private r As Random = New Random

'   NextUniqueRNum attempts to return a sequence of unique random numbers.
'   It takes one parameter, which specifies the upper bound for the
'   number to be returned (result will be an integer >= 0 and less than
'   rMax).  If rMax is zero, a new sequence is started.
'   If rMax is not greater than the number of values already returned, it
'   will not be possible to return a unique value and the function returns
'   a duplicate.
Private Function NextUniqueRNum(ByVal rMax As Integer) As Integer
    Static rNums() as Integer       ' Numbers returned in this sequence
    Static nRNums as Integer = 0    ' Length of sequence
    Dim i As Integer, k As Integer = 0
    Const kLim as Integer = 10  ' Arbitrary value; helps ensure that While terminates

    NextUniqueRNum = 0

    if rMax < 1 then        ' Reset the sequence
        nRNums = 0
        Exit Function
    Else                    ' Make room for a new value
        nRNums += 1
        Redim Preserve rNums(nRNums)
    End If

    ' Keep trying until we have a unique number or must give up
    While k < kLim * nRNums
        k += 1
        rNums(nRNums) = r.Next(rMax)    ' Next try
        For i = 0 to nRNums-1           ' Check for uniqueness
            If rNums(nRNums) = rNums(i) Then Continue While
        Next i
        Exit While
    End While

    NextUniqueRNum = rNums(nRNums)
End Function

Open in new window

Fernando SotoRetired
Distinguished Expert 2017

Commented:
Hi gknuth;

Use a seed which is a number used to calculate a starting value for the pseudo-random number sequence. The random number generator is not truely random.

Dim rnd As New Random(DateTime.Now().Second + DateTime.Now().Millisecond)

Fernando

Commented:
Do you know that Random is based on Donald E. Knuth's subtractive random number generator algorithm?

Author

Commented:
Oh wow, that's pretty cool.

That function is great...I knew there had to be a more elegant way than the one I had :)  Thanks!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial