1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

The Best Random Number Generator

Discussion in 'Visual Basic .NET' started by moonlighsunligh, Oct 13, 2012.

  1. moonlighsunligh

    moonlighsunligh Jr. VIP Jr. VIP Premium Member

    Joined:
    May 1, 2010
    Messages:
    2,016
    Likes Received:
    293
    Home Page:
    Is there a better function for generating random numbers than this one:


    Code:
    Dim rdm As New Random(System.DateTime.Now.Millisecond)
    Dim number as integer = rdm.[Next](min, max)
    

    What number generator for example the best spinner uses?
     
  2. cgimaster

    cgimaster Power Member

    Joined:
    Jun 30, 2012
    Messages:
    525
    Likes Received:
    311
    Gender:
    Male
    Have you tried running your method against the same method using a static Random(in your case rdm) ? I am sure it will give you more uniqueness then your current method.
     
  3. jazzc

    jazzc Moderator Staff Member Moderator Jr. VIP

    Joined:
    Jan 27, 2009
    Messages:
    2,612
    Likes Received:
    11,241
    Occupation:
    Pusillanimous Knitter
    Location:
    Buenos Aires
    Yes.
    Code:
    System.Security.Cryptography.RandomNumberGenerator.Create()
    
     
  4. qrazy

    qrazy Senior Member

    Joined:
    Mar 19, 2012
    Messages:
    1,115
    Likes Received:
    1,725
    Location:
    Banana Republic
    Almost all the random number generates based on static algorithm which always outputs in a similar fashion. To make them effective the random number generator has to be seeded with dynamic values. And in your case you are seeding it with current time. So what's the problem with the current method?
     
  5. ShiftySituation

    ShiftySituation Power Member

    Joined:
    Apr 15, 2010
    Messages:
    621
    Likes Received:
    315
    Occupation:
    Having fun
    Location:
    Jacksonville, FL
    The problem with seeding based on time is CPUs process so fast that it can spit out a great amount of data in a millisecond. In turn, you will be using the same seed to produce your random int. To test this, put your code in a for loop and loop it a thousand times while outputting the int as a string so you can see what you get. You'll notice it is a lot of the same values.
     
  6. moonlighsunligh

    moonlighsunligh Jr. VIP Jr. VIP Premium Member

    Joined:
    May 1, 2010
    Messages:
    2,016
    Likes Received:
    293
    Home Page:
    Thanks very much. Trying.



    I think i got less unique results with that method. I didn't tried to do loop but I will try soon.

    But what is solution for this problem? The static random? I have tried a method based on CPU/Memory usage, but it wasn't that good.

    I am getting the same number multiple times. Up to 5 times for this sequence 1,2,3,4.
     
    Last edited: Oct 13, 2012
  7. moonlighsunligh

    moonlighsunligh Jr. VIP Jr. VIP Premium Member

    Joined:
    May 1, 2010
    Messages:
    2,016
    Likes Received:
    293
    Home Page:
    I wrote a slow function for the implementation, but still I am not sure if results are ok.

    Code:
        Public Function Randomize(ByVal min As Integer, ByVal max As Integer) As Integer
            Dim rdm As Integer = max + 1
    
            Do While rdm = max + 1
    
                Dim rn(1) As Byte
                System.Security.Cryptography.RandomNumberGenerator.Create.GetNonZeroBytes(rn)
                Dim rdm_big As Integer = Convert.ToInt32(rn(0).ToString)
    
                For i = min To max
                    If rdm_big = i Then
                        rdm = i - 1
                    End If
                Next
    
            Loop
    
            Return rdm
        End Function
    
    


    Here are results after a for:
    Code:
    3
    2
    2
    2
    1
    4
    3
    3
    2
    2
    2
    4
    3
    4
    1
    1
    4
    4
    4
    3
    4
    2
    3
    2
    2
    4
    1
    4
    4
    1
    4
    3
    4
    2
    3
    3
    4
    2
    3
    4
    2
    
     
    Last edited: Oct 13, 2012
  8. qrazy

    qrazy Senior Member

    Joined:
    Mar 19, 2012
    Messages:
    1,115
    Likes Received:
    1,725
    Location:
    Banana Republic
    Also better don't seed it inside the loop. Just seed it once and use Next method inside the loop.
     
  9. moonlighsunligh

    moonlighsunligh Jr. VIP Jr. VIP Premium Member

    Joined:
    May 1, 2010
    Messages:
    2,016
    Likes Received:
    293
    Home Page:
    Do the results seems ok?

    This function generates random number between 1 and 255, so if i want to generate random numbers between some other values than 1 and 255 then I have to use a loop.
     
    Last edited: Oct 13, 2012
  10. adh0c

    adh0c Newbie

    Joined:
    Apr 20, 2012
    Messages:
    11
    Likes Received:
    7
    I put this together quick and ran a couple benchmarks. The main problem seems to be the seed, so I tried to use the RNGCryptoServiceProvider to generate a more unique seed. Here are the results:

    Using System.DateTime.Now.Millisecond to seed:
    1-99
    Test 1 = 97 duplicates
    Test 2 = 98 duplicates
    Avg Execution time: 87ms


    1-999
    Test 1 = 989 duplicates
    Test 2 = 984 duplicates
    Avg Execution time: 705ms


    1-9999
    Test 1 = 9802 duplicates
    Test 2 = 9829 duplicates
    Avg Execution time: 11400ms


    Using your Randomize() function
    1-99
    Test 1 = 34 duplicates
    Test 2 = 34 duplicates
    Test 3 = 34 duplicates
    Avg Execution time: 131ms


    1-999
    Test 1 = 751 duplicates
    Test 2 = 753 duplicates
    Test 2 = 749 duplicates
    Avg Execution time: 760ms


    1-9999
    Test 1 = 9746 duplicates
    Test 2 = 9746 duplicates
    Test 3 = 9746 duplicates
    Avg Execution time: 9100 ms


    Using System.Security.Cryptography.RNGCryptoServiceProvider to seed:
    1-99
    Test 1 = 35 duplicates
    Test 2 = 33 duplicates
    Test 3 = 40 duplicates
    Test 4 = 40 duplicates
    Avg Execution time: 71ms


    1-999
    Test 1 = 376 duplicates
    Test 2 = 373 duplicates
    Test 3 = 367 duplicates
    Avg Execution time: 690ms


    1-9999
    Test 1 = 3681 duplicates
    Test 2 = 3709 duplicates
    Test 3 = 3644 duplicates
    Avg Execution time: 11425ms


    The Function:
    Imports
    System.Security.Cryptography

    Code:
        
    Private Function GetRandom(ByVal iMin As Integer, ByVal iMax As Integer) As Integer        
    
            Dim iMaxIntLength As Integer = 9
    
            Dim cChars() As Char = ("1234567890").ToCharArray
    
    
            Dim iSize As Integer = iMaxIntLength
            Dim bData(0) As Byte
    
    
            Dim Crypt As New RNGCryptoServiceProvider
            Crypt.GetNonZeroBytes(bData)
    
    
            iSize = iMaxIntLength
            ReDim bData(iSize - 1)
            Crypt.GetNonZeroBytes(bData)
    
    
            Dim sResult As New System.Text.StringBuilder
            For Each bByte As Byte In bData
                sResult.Append(cChars(bByte Mod (cChars.Length - 1)))
            Next
    
    
            Dim iRndSeed As Integer = CInt(sResult.ToString)
            Dim rdm As New Random(iRndSeed)
            Dim Num As Integer = rdm.[Next](iMin, iMax)
    
    
            Return Num
    End Function
    
     
    • Thanks Thanks x 2
    Last edited: Oct 13, 2012
  11. moonlighsunligh

    moonlighsunligh Jr. VIP Jr. VIP Premium Member

    Joined:
    May 1, 2010
    Messages:
    2,016
    Likes Received:
    293
    Home Page:
    Thanks. So you still use random function, only it's seed is randomized. I am not sure is that better than using Static random - like bellow:

    Code:
    Static rdm As System.Random = New System.Random().
     
  12. adh0c

    adh0c Newbie

    Joined:
    Apr 20, 2012
    Messages:
    11
    Likes Received:
    7
    That is slightly better and much simpler.

    1-99
    Test 1 = 37 duplicates
    Test 2 = 35 duplicates
    Avg Execution Time: 12ms


    1-999
    Test 1 = 345 duplicates
    Test 2 = 367 duplicates
    Avg Execution Time: 630ms


    1-9999
    Test 1 = 3688 duplicates
    Test 2 = 3688 duplicates
    Test 3 = 3662 duplicates
    Avg Execution Time: 11294ms
     
    • Thanks Thanks x 1