How to get good random results [duplicate] - c#

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 9 years ago.
For some TreeView I want to test lots of values for the Background Property of the items.
So I have a tree that is filled with 200 items right now.
These are the possible values:
public enum EnumItemState
{
Default,
Red,
Green,
Yellow,
}
Now I wanted to quickly test different values in the view, so I wrote
this code:
private EnumItemState GetRandomItemState()
{
var rand = new Random();
var val = rand.Next(0, 3);
switch (val)
{
case 0:
{
return EnumItemState.Red;
}
case 1:
{
return EnumItemState.Green;
}
case 2:
{
return EnumItemState.Yellow;
}
default:
{
return EnumItemState.Default;
}
}
}
But it is not random at all. All of the values are the same for one run.
Having breakpoints somewhere in my "Random" method, I get different, "more random"
results.
What is happening here?
How to get better random results?
Is it some optimization, so all my Randoms are created with the same time seed and therefore get the same result?

You're creating a new Random object every time you call your method which is being seeded with the same value (it's based on the current time) so you keep getting the same random value.
Do this instead:
void CallingMethod()
{
Random rnd = new Random();
for (int i = 0;i < 200;++i)
EnumItemState state = GetRandomItemState(rnd);
}
private EnumItemState GetRandomItemState(Random rnd)
{
// Same code you had here, but don't create new instance of Random
}

I'm going to assume you're calling this very frequently in a tight loop (i.e., little to no time between calls)
The default ctor for Random looks like this:
public Random() : this(Environment.TickCount)
{
}
See that Environment.TickCount? If you try new'ing multiple Random instances very quickly (i.e., before that tick count changes), you will effectively get the exact same sequence of random numbers - hence "PseudoRandom".
You can do one of a couple things:
Wait a while between calls
Manually pass in a seed to the ctor
Use the prngs in the System.Security namespace

Related

Why is my event handler not always printing out a new random number? [duplicate]

This question already has answers here:
Random Number Generation - Same Number returned [duplicate]
(3 answers)
Closed 4 years ago.
class Run
{
public delegate void PrintRandomEvent();
public static event PrintRandomEvent print;
public void run()
{
while(true)
{
print();
}
}
}
class Print
{
Run.print += new Run.PrintRandomEvent(this.print);
public void print()
{
Random random = new Random();
int n = random.Next(1,5000);
Console.WriteLine(n);
}
}
It keeps on printing the same random number in multiples before printing a new random number in multiples. I've tried adding Run.print -= new Run.PrintRandomEvent(this.print) but it does not do the trick just giving me null errors.
Because this is how Random works, each time you create new instance very close in time to previous one you get the same random value.
Since it's connected to system clock
Just do not create new Random each time
The Random class initializes itself by using the current date and time value of the system. The problem is that this clock is much slower than the CPU clock. Therefore, the CPU can yield several random values before the time clock ticks.
Make the random object static and always use this one and unique random object. At each successive call it will yield the next random value instead of different random objects always returning the first one depending on the system time.
class Print
{
private static Random _random = new Random();
public void print()
{
int n = _random.Next(1,5000);
Console.WriteLine(n);
}
}
static means that all Print objects share the same _random field.
Random is time based but maybe you can try something like this.
But i didt test it.
class Print
{
int seed = (new Random()).Next();
Run.print += new Run.PrintRandomEvent(this.print);
public void print()
{
Random random = new Random(seed++);
int n = random.Next(1,5000);
Console.WriteLine(n);
}
}

Looping through a method call too fast? [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 7 years ago.
I am calling a method instance called buy. My method randomly generates a string of digits and numbers. My for loop appears to be going to fast for the method to change the string because I get the same string like 2-3 times in a row before getting a new string. when i add a System.Threading.Thread.Sleep(100); I am getting random number like the way it is supposed to be. The problem is that it is way too slow and i feel like there must be a better way. is there a way to get random string each time without invoking the Sleep() method?
for (int i = 0; i < exit; i++)
{
ticket = buy.SetNum();
Console.WriteLine("Wellcome Mr.Nissan. The winning numbers for Lotto max are:");
Console.WriteLine(ticket);
System.Threading.Thread.Sleep(25);
}
Yes, this is a problem with your random number generator - not with the code you posted in the question.
consider the following:
public int GenRandomNum()
{
var r = new Random();
return r.Next()
}
You are generating a new random class based on the same seed if you call it in the same tick, and it will generate the same number. Moving the random initialization out side of the method will fix the problem, like so:
private Random _rand = new Random();
public int GenRandomNum()
{
return _rand .Next()
}
You haven't included the code that actually creates the random number but I suspect you're creating a new instance of the random number generator each time around the loop.
What you need to do instead, is create one instance of the random number generator (outside of the loop) and reuse it for each random number generator .Next() call.
Move the random number generation into into the loop:
var rnd = new Random();
for (int i = 0; i < exit; i++)
{
var ticket = rnd.Next();
Console.WriteLine("Wellcome Mr.Nissan. The winning numbers for Lotto max are:");
Console.WriteLine(ticket);
}
I can't tell you why exactly your posted code wasn't working without seeing the buy.SetNum(); method code.

Random Number is getting Repeated in case when Multiple Request Coming in Miliseconds [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 9 years ago.
I have an application which is storing the requests.
I am getting Multiple request in timespan of miliseconds.
I am create a Unique ID like
Random _r = new Random();
int n = _r.Next(9);
String.Format("{0:yyyyMMddHHmmss}{1}", DateTime.Now, n.ToString());
But when the multiple request are coming on timespan of miliseconds. This UniqueID is getting repeated.
I am storing those requests with one unique id. but its getting repeated if request are coming on timespan of miliseconds
Please help me on this....If i am wrong anywhere please suggest me somewhere..
You need 1 instance of Random that is referenced from each execution of your routine.
public class Helper
{
Random _r = new Random();
public string GetUniqueId()
{
int n = _r.Next(9);
return String.Format("{0:yyyyMMddHHmmss}{1}", DateTime.Now, n.ToString());
}
}
You're running into the issue that occurs when you instantiate many Randoms within a small interval. Each instance ends up with the same seed value so all their pseudo-random series of values will be identical. Using 1 instance for all calls guarantees the next value in the series.
Note, the likelihood of still getting the same value in a row is inversely proportional to the size of the maxValue argument of Next.
Yo should define and create _r in a higher scope than the one which runs your method. Than, your method should use this instance of _r, to get other random generated numbers.
This will generate a unique ID for your case -
Random _r = new Random();
int n = _r.Next(9);
String.Format("{0}{1}", DateTime.Now.Ticks, n.ToString());
OR for millisecond precision , you can use
Random _r = new Random();
int n = _r.Next(9);
String.Format("{0:yyyyMMddHHmmssfff}{1}", DateTime.Now, n.ToString());
Every time you run your code, you create a new Random object. The thing about the Random object is that it isn't really random. If you seed it with the same value, it will give you the same number. Therefore, if you create two Random objects at the same time, they'll produce the same value, because the Random() constructor with no arguments uses the current time as a seed. The current time is not that accurate, so all Random() objects created within one small span of time (around 15 milliseconds) will generate the same sequence of numbers because the time has not changed.
Here's an example of how you can fix it - create your Random object just once:
public class MyApp
{
private Random _r;
public MyApp()
{
this._r = new Random();
}
public handle_request()
{
int n = _r.Next(9);
String.Format("{0:yyyyMMddHHmmss}{1}", DateTime.Now, n.ToString());
}
}

Why doesn't this create a "true" random number? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Random number generator only generating one random number
Im trying to create a loop to create and output 5 random numbers in a listbox. Basically it outputs the same random number 5 times instead of 5 different ones. When I use a break point and go through the code it does actually generate the 5 numbers. So why does it only output the first answer? Thank you. (This is not the entirety of the project, but I need to get this working first).
public string Numbertext1;
public string Numbertext2;
public int GeneratedNumbers;
public int Average = 0;
public int TotalSum = 0;
public int TotalCalcs = 0;
public int Counter = 0;
private void btnRandomise_Click(object sender, EventArgs e)
{
Numbertext1 = txtNum1.Text;
int Number1;
int.TryParse(Numbertext1, out Number1);
Numbertext2 = txtNum2.Text;
int Number2;
int.TryParse(Numbertext2, out Number2);
do
{
Random num = new Random();
int number = num.Next(Number1, Number2);
lbNumbers.Items.Add(Convert.ToString(number));
Counter++;
}
while (Counter < 5);
{
TotalCalcs++;
Counter = 0;
}
}
}
}
You need to initialize your num variable at the global level. It's using the same seed over and over again.
Put this : Random num = new Random(); at the top where you are initializing everything else. Then remove it from inside your method.
It's because you're creating a new Random instance within a tight loop, so the seed number will be the same. The Random class is not truly random (in the mathematical sense), so you should change the seed or use one instance of it. Move Random num = new Random(); to the top with the other variables.
Because you didn't adequately seed the random number generator.
The generator has an algorithmn it follows, if you just create it without seeding it then your numbers will be the same each time. To quote from MSDN:
The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers.
To fix this use the other constructor which allows you to specify a seed - there is a good example of this on MSDN.
The Random class instantiation is time-dependent. With a very quick loop, you're creating the same object every time and thus you're getting the same value over and over. You need to move the instantiation outside the loop so you get new numbers when you call Next() .
This is also the reason why it "works" when you use a break point to check the values. The Random object you created will have different reference times and thus would be different.

same random values [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Random number generator not working the way I had planned (C#)
Why does it appear that my random number generator isn't random in C#?
I have a problem with random values
int weight = 0;
Random random = new Random();
for (int i = 0; i < entriesCount; i++)
{
weight = random.Next(10);
this.weights[i] = weight;
}
This code is in constructor of my object. I create 3 diffrent objects
Object object1 = new Object(2);
Object object2 = new Object(2);
Object object3 = new Object(2);
For every object I get same random values for example: 4, 5 | 4, 5 | 4, 5
Every time I get same values in same sequence. I don`t get why> Please help
Best regards,
Dawid
The problem is that you're creating a new Random each time. When you create an instance of the Random class, it uses the current time as a seed. If you do this multiple times very quickly, you get the same seed value, so the different Random instances output the same results.
In order to work around this, you need to either make sure your random is seeded uniquely each time, or share and use a single Random instance. The easiest option is to just make the Random instance static:
class YourClass
{
private static Random randomGenerator = new Random();
public YourClass(int entriesCount)
{
int weight = 0;
for (int i = 0; i < entriesCount; i++)
{
weight = randomGenerator.Next(10);
this.weights[i] = weight;
}
}
// .. rest of your class
This will cause the class to always reuse the same Random instance, so you'll get different values each time.
Note that if you're going to be using this in a multithreaded scenario, you'll also have to synchronize access to the random instance, or come up with a different approach (such as saving a seed value, and using something like Interlocked.Increment to increment it and seed a new random from each instance, etc).
Random is a pseudorandom number generator, which means the sequence of outputs is the same for any given seed. If you pass a seed to the constructor, you get a different sequence.
As far as I am aware, a random is seeded by the system time unless you specify otherwise. It generates numbers based on this number. As you create them almost exactly at the same time, they have the same seed and will almost always return the same number and sequence.
Any easy fix would be to create a static random all instances share, and just call .Next() on that static object.
From the MSDN documentation:
"using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers."

Categories

Resources