More on Randomness (with text this time :-)

E

Ethan Strauss

Hi,
There have been quite a few discussions of Random not giving random
numbers and how to fix that by feeding in a new seed each time, waiting
enough time, or calling the Next() method of the Random object. I have
another wrinkle....
I have created a static Random DNA sequence generator (it is really just
a random number generator with a little chrome). Since it is static, I can't
use the .Next method for multiple calls to the object (or if I can, can you
please let me know how?). Right now, I am have a sister method which allows
the user to pass in a seed, so I can generate THAT seed with a random number
on which I call Next() each time. After discussion from this group, I though
I might add a Thread.Sleep() to the unseeded version and have it wait a tick
each time before running, but a trick turns out not to be long enough! I
found that I have to wait ~80000 ticks before I get a new random number! If
anyone knows of a better way to get this static method to be more truely
random without waiting that long, I would be interested.

Here is the method
public static string RandomSequence (int length)
{
Random Number = new Random();
StringBuilder RandomSequence = new StringBuilder();
int ThisBase; "
for (int Base = 1; Base <= length; Base++)
{
ThisBase = Number.Next(4);
switch (ThisBase)
{
case 0:
RandomSequence.Append("A");
break;
case 1:
RandomSequence.Append("G");
break;
case 2:
RandomSequence.Append("T");
break;
case 3:
RandomSequence.Append("C");
break;
default:
break;
}
}
return RandomSequence.ToString();
}


and here is what I did to determine how many ticks it takes to get a new
number

private void Page_Load(object sender, System.EventArgs e)
{
int NumberNumber = 20;
TimeSpan ATick = new TimeSpan(10000L);
for (int Counter = 0; Counter < NumberNumber;
Counter++)//This returns the same sequence each time
{
RandomNumberLabel.Text += "<br>" +
BiologyTools.NucleicAcidSequence.RandomSequence(10, 20);
}
RandomNumberLabel.Text += "<p>";
for (int Counter = 0; Counter < NumberNumber;
Counter++)//This changes every 8 passes
{
System.Threading.Thread.Sleep(ATick);
RandomNumberLabel.Text += "<br>" +
BiologyTools.NucleicAcidSequence.RandomSequence(10, 20);
}
}

Ethan
 
D

Daniel

It's all about the seed. there is a site that uses some kind of atmospheric
measurement that is random to generate random numbers and you can link to
that site, get the random numbers and use that for seeding. Or use some kind
of other item during your programmes run life that is random. For example if
its a game where players take turns, the time each will take to make a move
at the ms level will be truly random, there is also a cryptographic api you
can use to generate random numbers, again you could use that for the seed or
mix it with other random numbers to generate a new random seed. The point is
the seed must come from a random source, if your seed doesn't change the
random result will be the same.

I believe the site is www.random.org.

Hope that helps?
 
C

Christof Nordiek

Hi Ethan,

your problem is, that you create a new instance of Random in every call. So
if several calls fall into the same timeslice (obviously about 80000 ticks)
all will get the same sequence of random numbers. You should try to reuse
the same instance for all calls. This will have to be stored in a static
field.

static Random Number = new Random(); //RNG instanciated on class
initialization

The method will be the same, without the first line.
This would not be threadsafe.
You would have to lock any access to the static Instance, for threadsafty.
Even better is using the static Instance for creating a seed for a local
instance. By this you minimize the locking.

static Random _number = new Random(); //RNG instanciated on class
initialization

public static string RandomSequence (int length)
{
lock(_number)
Random Number = new Random(_number.Next(1000));
int ThisBase;
......

HTH
 
J

Jon Skeet [C# MVP]

There have been quite a few discussions of Random not giving random
numbers and how to fix that by feeding in a new seed each time, waiting
enough time, or calling the Next() method of the Random object. I have
another wrinkle....
I have created a static Random DNA sequence generator (it is really just
a random number generator with a little chrome). Since it is static, I can't
use the .Next method for multiple calls to the object (or if I can, can you
please let me know how?).

Just have the Random stored as a static variable:

static Random rng = new Random();

Then use it from your static method.

However, Random isn't thread-safe, so you either need to explicitly
lock on every call, or use my StaticRandom class which basically makes
things simpler by doing the locking for you (and creating the Random,
in fact).

See http://www.pobox.com/~skeet/csharp/miscutil
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top