This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 9 years ago.
I wrote a function A, and inside this function there is below code piece.
rnd.Next(1,3);
If I run my A function hundred times, and print out the results, results are not realistic for example it is always win or always lose. So the random function is problematic. I need a realistic real random function.
How to achieve that ?
I guess you've done a typical error with Random, you're re-creating it each time i.e:
Random rnd = new Random();
int toss = rnd.Next(1,3);
If you do this, rnd could well start each time from the same seed and that's why the result is badly skewed. The solution can be something like that:
// Let it be thread-safe
private static ThreadLocal<Random> s_Gen = new ThreadLocal<Random>(
() => new Random());
// Thread-safe non-skewed generator
public static Random Generator {
get {
return s_Gen.Value;
}
}
...
int toss = Generator.Next(1,3);
Use this
int i = rnd.Next(int.MaxValue) % 2;
Then have a check whether i = 0 or i = 1.
EDIT Yes, as Dmitry Bychenko mentioned do not instantiate a new Random object each time.
Related
This question already has answers here:
Why Static method sometimes returns same result for separate call?
(2 answers)
C# Random generation
(4 answers)
Closed 5 years ago.
My point in this code is to create some random dates(should be simple) but...
static void Main(string[] args) {
Console.WriteLine(CreateDate());
Console.WriteLine(CreateDate());
Console.WriteLine(CreateDate());
}
public static DateTime CreateDate() {
Random rnd = new Random();
DateTime date = new DateTime(1990, 1, 1);
date = date.AddDays(rnd.Next(30));
date = date.AddMonths(rnd.Next(11));
date = date.AddYears(rnd.Next(28));
return date;
}
The output allways the same...
What am I missing?
The date doesn't change whatever I do.
You need to move random object out of method.
All Random instances seeded with same default value (derived by system clock, due to being in close succession coupled with finite resolution), and will yield same result ( on random.Next() call).
The Random() constructor uses the system clock to provide a seed
value. This is the most common way of instantiating the random number
generator.
If the same seed is used for separate Random objects, they will
generate the same series of random numbers. This can be useful for
creating a test suite that processes random values, or for replaying
games that derive their data from random numbers. However, note that
Random objects in processes running under different versions of the
.NET Framework may return different series of random numbers even if
they're instantiated with identical seed values.
From official msdn documentation https://msdn.microsoft.com/en-us/library/system.random.aspx.
You keep creating new Random, which leads to making the same sequence of pseudo-random numbers.
Create Random once, and pass it to CreateDate:
// Inside Main()
var rnd = new Random();
Console.WriteLine(CreateDate(rnd));
Console.WriteLine(CreateDate(rnd));
Console.WriteLine(CreateDate(rnd));
...
// Change method signature
public static DateTime CreateDate(Random rnd) {
DateTime date = new DateTime(1990, 1, 1);
... // The rest of the method remains the same
}
This question already has answers here:
How do I generate a random integer in C#?
(31 answers)
Closed 5 years ago.
I'm trying to make a random room selector and Random.Next seems to not be working, please help!
List<string> rooms = new List<string>();
rooms.Add(room1);
rooms.Add(room2);
int index = Random.Next(rooms.Count);
System.Console.WriteLine(rooms[index]);
The systems I am using (I think this may be the problem)
Using System
Using System.Collections.Generic
Using.Collections
Using.Collections is greyed out.
your issue is that you want to call the Next method directly on the Random class, unfortunately, there is no static Next method for the Random class.
int index = Random.Next(rooms.Count);
you'll need to make an instance of the Random generator, in order to invoke the Next method.
Example:
Random rand = new Random();
int index = rand.Next(rooms.Count);
System.Console.WriteLine(rooms[index]);
further reading:
How do I generate a random int number in C#?
This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 6 years ago.
I have the following code inside a static method in a static class:
Random r = new Random();
int randomNumber = r.Next(1,100);
I have this inside a loop and I keep getting the same randomNumber!
Any suggestions here?
A good seed generation for me is:
Random rand = new Random(Guid.NewGuid().GetHashCode());
It is very random. The seed is always different because the seed is also random generated.
You should not create a new Random instance in a loop. Try something like:
var rnd = new Random();
for(int i = 0; i < 100; ++i)
Console.WriteLine(rnd.Next(1, 100));
The sequence of random numbers generated by a single Random instance is supposed to be uniformly distributed. By creating a new Random instance for every random number in quick successions, you are likely to seed them with identical values and have them generate identical random numbers. Of course, in this case, the generated sequence will be far from uniform distribution.
For the sake of completeness, if you really need to reseed a Random, you'll create a new instance of Random with the new seed:
rnd = new Random(newSeed);
Bit late, but the implementation used by System.Random is Environment.TickCount:
public Random()
: this(Environment.TickCount) {
}
This avoids having to cast DateTime.UtcNow.Ticks from a long, which is risky anyway as it doesn't represent ticks since system start, but "the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001, in the Gregorian calendar)".
Was looking for a good integer seed for the TestApi's StringFactory.GenerateRandomString
In case you can't for some reason use the same Random again and again, try initializing it with something that changes all the time, like the time itself.
new Random(new System.DateTime().Millisecond).Next();
Remember this is bad practice though.
EDIT: The default constructor already takes its seed from the clock, and probably better than we would. Quoting from MSDN:
Random() : Initializes a new instance of the Random class, using a time-dependent default seed value.
The code below is probably your best option:
new Random().Next();
public static Random rand = new Random(); // this happens once, and will be great at preventing duplicates
Note, this is not to be used for cryptographic purposes.
this workes for me:
private int GetaRandom()
{
Thread.Sleep(1);
return new Random(DateTime.Now.Millisecond).Next();
}
A good seed initialisation can be done like this
Random rnd = new Random((int)DateTime.Now.Ticks);
The ticks will be unique and the cast into a int with probably a loose of value will be OK.
I use this for most situations, keep the seed if there is a need to repeat the sequence
var seed = (int) DateTime.Now.Ticks;
var random = new Random(seed);
or
var random = new Random((int)DateTime.Now.Ticks);
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.
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