C# DateTime not change [duplicate] - c#

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
}

Related

Generated random string isn't random when called more than once [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 6 years ago.
I'm attempting to create a randomly generated string of words, which works fine unless I call it multiple times in a row. This is on a WebForms page that and the list of words comes from a file.
I suspect I'm not understanding something with out C# or possibly ASP.NET works in this case, can someone explain why this is happening and how to approach a fix?
Here is the method
public string GeneratePhrase()
{
// get dictionary file
var data = File.ReadAllLines(HttpContext.Current.Server.MapPath("~/libs/words.txt"));
Random rand = new Random();
int r1 = rand.Next(data.Count());
int r2 = rand.Next(data.Count());
int r3 = rand.Next(data.Count());
string p1 = data.ElementAt(r1).ToLower();
string p2 = data.ElementAt(r2).ToLower();
string p3 = data.ElementAt(r3).ToLower();
string ret = string.Format("{0}{1}{2}", p1, p2, p3);
return ret;
}
If I call this once during a PostBack, it's fine and always creates a random combination of words. However if I use this more than once during a PostBack, it simply repeats the same random string from each call.
string s1 = this.GeneratePhrase();
string s2 = this.GeneratePhrase();
string s3 = this.GeneratePhrase();
Response.Write(s1);
Response.Write(s2);
Response.Write(s3);
output
tirefriendhotdog
tirefriendhotdog
tirefriendhotdog
Any reason on why this may happen?
Random rand = new Random(); uses the current time as a seed value, so calling it multiple times in quick succession will give you the same random sequences. You can:
create a single Random object that is used for all requests
seed it with a different pseudo-random number like Guid.NewGuid().GetHashCode()
Use a different random number generator that is not time-dependent.
MSDN has this to say about the parameterless constructor for Random:
The Random() constructor uses the system clock to provide a seed value. This is the most common way of instantiating the random number generator.
When you create several new instances of Random in short succession, they may end up with the same seed, and so produce the same sequence.
To get proper (pseudo)randomness, it is best to have only a single instance of Random per thread in you application.

C# generating a random number, returns the same result each time [duplicate]

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);

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());
}
}

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."

How do I seed a random class to avoid getting duplicate random values [duplicate]

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);

Categories

Resources