Random not so random?

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »

46 Replies - 2890 Views - Last Post: 16 June 2013 - 09:15 PM Rate Topic: ***** 1 Votes

#1 _HAWK_  Icon User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1048
  • View blog
  • Posts: 4,075
  • Joined: 02-July 08

Random not so random?

Posted 12 June 2013 - 06:29 PM

So I use the Random class very sparingly. Today I needed a random string generator:

Private alphas As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"


For i As Integer = 0 To 100
      Dim s As String = RndColName()
      Debug.WriteLine(s)
Next


Private Function RndColName() As String
    Dim sb As New StringBuilder
    Dim rnd As New Random
    For i As Integer = 0 To 15
      Dim s As Char = alphas(rnd.Next(0, alphas.Length))
      sb.Append(s)
    Next
    Return sb
End Function


When I step thru the code they don't duplicate like you see in the spoiler. But when I let it just run I get this craziness - any thoughts?

Spoiler


Is This A Good Question/Topic? 1
  • +

Replies To: Random not so random?

#2 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 991
  • View blog
  • Posts: 971
  • Joined: 30-September 10

Re: Random not so random?

Posted 13 June 2013 - 03:16 AM

The Random class uses a seed (which is just an integer) to generate its random numbers. Two Random objects with the same seed will generate the same numbers.

Now, if you don't provide a seed in the constructor, the default is that the seed is taken from Environment.TickCount.

Therefore, if you create multiple Random objects in quick succession, it's likely that many/all of the Random objects will get the same seed value from Environment.TickCount, and thus will generate the same sequence of numbers.

For this reason, it is generally advised that you have only one instance of Random in your application (or possibly one per thread, since the Random class isn't thread safe). So, you need to move the creation of the Random object outside of the loop, and organise your code so you reuse the same Random object to generate the numbers.

This post has been edited by CodingSup3rnatur@l-360: 13 June 2013 - 04:33 AM

Was This Post Helpful? 2
  • +
  • -

#3 Flukeshot  Icon User is offline

  • A little too OCD
  • member icon

Reputation: 415
  • View blog
  • Posts: 1,030
  • Joined: 14-November 12

Re: Random not so random?

Posted 13 June 2013 - 03:21 AM

Is it effective to use the random class to generate seeds of the 4 random objects? Or is that just purely useless/inefficient?

Edit: I ask this in a general programming sense. If the answer is specific to VB, please let me know. :)

This post has been edited by Flukeshot: 13 June 2013 - 03:23 AM

Was This Post Helpful? 0
  • +
  • -

#4 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 991
  • View blog
  • Posts: 971
  • Joined: 30-September 10

Re: Random not so random?

Posted 13 June 2013 - 04:14 AM

That doesn't sound like a particularly good idea to me. What's the point of getting a random number, only to try and use that random number to generate another random number? You'd may as well just use the first random number :) Plus, doing it that way introduces more problems, like what if the Random object that is generating the seeds generates the same seed more than once?

This concept of seeding certainly isn't specific to VB.

Generally, if you start messing around trying to 'improve' the randomness, you are nearly always going to end up shooting yourself in the foot.

My advice is to just create one Random instance, let the system seed it, and reuse that object. It's simple and effective.

The only use I can really think of for seeding the Random object yourself is to deliberately cause it to repeatedly generate the same sequence of numbers, for debugging and/or testing purposes.
Was This Post Helpful? 1
  • +
  • -

#5 dbasnett  Icon User is online

  • D.I.C Addict
  • member icon

Reputation: 109
  • View blog
  • Posts: 603
  • Joined: 01-October 08

Re: Random not so random?

Posted 13 June 2013 - 05:22 AM

As has been suggested your code should look like this

    Private alphas As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        For i As Integer = 0 To 100
            Dim s As String = RndColName()
            Debug.WriteLine(s)
        Next
    End Sub

    Dim prng As New Random '<<<<<<<<<<<<<<<<<<

    Private Function RndColName() As String
        Dim sb As New System.Text.StringBuilder
        For i As Integer = 0 To 15
            Dim s As Char = alphas(prng.Next(0, alphas.Length))
            sb.Append(s)
        Next
        Return sb.ToString
    End Function



I fixed the function return renamed the Random to avoid confusion, and moved the declaration to the Form Namespace.

This post has been edited by dbasnett: 13 June 2013 - 05:54 AM

Was This Post Helpful? 1
  • +
  • -

#6 trevster344  Icon User is offline

  • The Peasant
  • member icon

Reputation: 224
  • View blog
  • Posts: 1,505
  • Joined: 16-March 11

Re: Random not so random?

Posted 13 June 2013 - 05:52 AM

The best way I've found to use the Random object is to declare a new instance of it at the start of the application or some random time but not before or in the same sub routine where I'll be using it. Haven't had as many issues that way.
Was This Post Helpful? 1
  • +
  • -

#7 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7644
  • View blog
  • Posts: 12,890
  • Joined: 19-March 11

Re: Random not so random?

Posted 13 June 2013 - 06:56 AM

*
POPULAR

Quote

Is it effective to use the random class to generate seeds of the 4 random objects? Or is that just purely useless/inefficient?


This is not a useful thing to do. Here's why:

All software-based* random number generators are functions which generate a sequence of bits which has the characteristic of seeming random - there are tests for this, and they're well defined. However, they are functions, meaning that they will always generate the same output when given the same input. Therefore, they should strictly be called "pseudo-random number sequence generators" - since they generate pseudo-random number sequences - and are often referred to as "PRNGs". The way these produce seeming randomness is by using a complex and extremely nonlinear function in conjunction with some external source of entropy.
Because of this, there is no point in having more than one number generator running in any program. If your random number generator is acceptably random - that is, it doesn't show more bias than you can live with for your purposes - then one instance will generate all the randomness that you need. If it is not sufficiently random, then adding more instances cannot add more randomness.
Using the random number generator to seed a new generator is perfectly useless, as @CodingSup3rnatur@l-360 points out, since the generator needs to get its entropy from outside itself.

I'm not a VB programmer, so I can't speak to specifics of that language, but typically you'll want to initialize a random number generator when your program is setting itself up, using the system time as a seed. For most purposes, this will get you as random as you're likely to need. You'll then use a reference to this generator throughout your program, rather than creating new instances.
(One caution: If you're generating cryptographic randomness, this may not be enough entropy. If security is an issue, built-in PRNGs initialized to the clock are not likely to withstand a serious attack)


*You could build a hardware-based random number generator, for example making use of the decay of some radioactive particle or some other fact of the world which is known to be "actually random", but this cannot be a part of a language, so we'll leave it aside
Was This Post Helpful? 7
  • +
  • -

#8 trevster344  Icon User is offline

  • The Peasant
  • member icon

Reputation: 224
  • View blog
  • Posts: 1,505
  • Joined: 16-March 11

Re: Random not so random?

Posted 13 June 2013 - 07:10 AM

Quote

*You could build a hardware-based random number generator, for example making use of the decay of some radioactive particle or some other fact of the world which is known to be "actually random", but this cannot be a part of a language, so we'll leave it aside


TRNG's. There are a few you can buy that plug right into the usb.

This post has been edited by trevster344: 13 June 2013 - 07:16 AM

Was This Post Helpful? 0
  • +
  • -

#9 _HAWK_  Icon User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1048
  • View blog
  • Posts: 4,075
  • Joined: 02-July 08

Re: Random not so random?

Posted 13 June 2013 - 07:19 AM

The purpose I had for this to create what I thought would be a better Binding name for some dynamically loaded DataColumns into a Silverlight DataGrid for importing a csv where the number of columns could be any value. One could have just used a CharArray from which the iteration variable could be used to get the char in that array, but this has limits and not totally dynamic and able to complete it's job no matter what was handed to it. This way I can have the function assign the binding name(also the column name) which is a valid binding name as well. Many thanks for the info.
Was This Post Helpful? 0
  • +
  • -

#10 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 765
  • Joined: 19-October 11

Re: Random not so random?

Posted 13 June 2013 - 08:26 AM

_HAWK_ you can have static rnd inside RndColName, and it will work the way you want/expect.
Was This Post Helpful? 1
  • +
  • -

#11 dbasnett  Icon User is online

  • D.I.C Addict
  • member icon

Reputation: 109
  • View blog
  • Posts: 603
  • Joined: 01-October 08

Re: Random not so random?

Posted 13 June 2013 - 08:34 AM

View Post_HAWK_, on 13 June 2013 - 09:19 AM, said:

The purpose I had for this to create what I thought would be a better Binding name for some dynamically loaded DataColumns into a Silverlight DataGrid for importing a csv where the number of columns could be any value. One could have just used a CharArray from which the iteration variable could be used to get the char in that array, but this has limits and not totally dynamic and able to complete it's job no matter what was handed to it. This way I can have the function assign the binding name(also the column name) which is a valid binding name as well. Many thanks for the info.


If the Binding name has to be unique then using random strings isn't foolproof.
Was This Post Helpful? 0
  • +
  • -

#12 _HAWK_  Icon User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1048
  • View blog
  • Posts: 4,075
  • Joined: 02-July 08

Re: Random not so random?

Posted 13 June 2013 - 08:40 AM

View Postdbasnett, on 13 June 2013 - 08:34 AM, said:

View Post_HAWK_, on 13 June 2013 - 09:19 AM, said:

The purpose I had for this to create what I thought would be a better Binding name for some dynamically loaded DataColumns into a Silverlight DataGrid for importing a csv where the number of columns could be any value. One could have just used a CharArray from which the iteration variable could be used to get the char in that array, but this has limits and not totally dynamic and able to complete it's job no matter what was handed to it. This way I can have the function assign the binding name(also the column name) which is a valid binding name as well. Many thanks for the info.


If the Binding name has to be unique then using random strings isn't foolproof.


What do you suggest as a better route?

I just tested for dups from a loop of 5000 several times - none found.
Was This Post Helpful? 0
  • +
  • -

#13 lucky3  Icon User is offline

  • Friend lucky3 As IHelpable
  • member icon

Reputation: 231
  • View blog
  • Posts: 765
  • Joined: 19-October 11

Re: Random not so random?

Posted 13 June 2013 - 08:40 AM

If you need something unique, then Guid (if I understood your question).

    Private Function RndColName() As String
        Dim sb As Guid = Guid.NewGuid()
        Return sb.ToString
    End Function

This post has been edited by lucky3: 13 June 2013 - 08:47 AM

Was This Post Helpful? 1
  • +
  • -

#14 _HAWK_  Icon User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1048
  • View blog
  • Posts: 4,075
  • Joined: 02-July 08

Re: Random not so random?

Posted 13 June 2013 - 08:46 AM

'-' is an illegal character in bindings. I could replace them though.

This post has been edited by _HAWK_: 13 June 2013 - 08:49 AM

Was This Post Helpful? 0
  • +
  • -

#15 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7644
  • View blog
  • Posts: 12,890
  • Joined: 19-March 11

Re: Random not so random?

Posted 13 June 2013 - 08:52 AM

View Post_HAWK_, on 13 June 2013 - 10:40 AM, said:

What do you suggest as a better route?
I just tested for dups from a loop of 5000 several times - none found.


You would expect no duplicates in such a small sample. If those are the spaces in which you need to be unique, you might be okay just taking your chances. What you have to understand, though, is that randomness means duplicates are possible. Since any given outcome is equally likely, and none are excluded, the odds of a duplicate for any given item are just the odds of drawing that particular outcome.

For example, if you throw a fair die twice, the odds of a duplicate are 1/6: whatever value shows on the first die, the odds of throwing it again are 1/6.

If your potential namespace is vastly larger than the number of names you select, you're probably safe*. This might or might not be good enough for you.

*"probably safe" means: vastly unlikely that you'll have a collision
Was This Post Helpful? 0
  • +
  • -

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »