Random class does not create random number? [duplicate] - c#

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why is Random class isn't really random?
I have following kind of code:
public static int GenerateRandomNumber(int seed)
{
var random = new Random(seed);
int num = random.Next();
while(num.ToString().Length != 6){
num = random.Next();
}
return num;
}
I want to get different number every time when call this function even with same seed. But I always got same result.
For example, every time when call GenerateRandomNumber(1), I always got number 640839.
How to fix this problem?

I want to get different number every time when call this function even with same seed.
Since that is the opposite of what the Random constructor is documented to do, you are going to have to learn to live with disappointment. You can't always get what you want.

Here is your problem:
var random = new Random(id);
Random generates a pseudo-random set of results - for the same seed, you would get the same sequence every time.
Change the creation of the Random object to a static field and you will get a different result whenever you call it.
From MSDN - Random Class:
The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated.

Random creates a series of pseudo-random numbers based on an initial value called a seed (id in your code).
Since the seed is identical then all calls to the function will follow the same code-path and generate the same result.
Make the random = new Random(seed) a static variable in your function or make it a member in the containing class and pass it to all functions/classes that need it.
Consider using a time based seed value when you are done developing the program.

I want to get different number every time when call this function even with same seed.
That's not how seeds work. The whole point of a seed is that using the same seed will result in the same series of pseudo-random numbers. The series is deterministic

The problem you need to fix is to align your expectations with the product specifications:
Providing an identical seed value to
different Random objects causes each
instance to produce identical
sequences of random numbers.
So either expect the same sequence froma seed, or don't use a seed.

Related

Random class always returning the same number between two classes [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 5 years ago.
I have a program that rolls two die. The die are objects created from the Dice class. The Dice class contains a method that returns a random number between 1 and the number of sides that the dice contains. Like so:
class Dice
{
//field
private int sides;
private Random rand = new Random();
//Constructor omitted for brevity
//public method to roll the dice.
public int rollDie()
{
return rand.Next(sides) + 1;
}
}
This works just fine for one dice. However, when I create two die and run both of their rollDie methods at the same time, I always receive the same number between the two die objects. For example:
Dice dice1 = new Dice(6); //created two die with 6 sides each.
Dice dice2 = new Dice(6);
dice1.rollDie(); //problem functions
dice2.rollDie();
those two functions will always return the same number, i.e. (1,1), (2,2), etc... never parting from this pattern.
From my research, I have concluded that the random object is creating a random number from the system's time and because the two methods are performed at nearly the same exact moment, they are returning a random number from the same seed. This is obviously a problem because it is far from reality.
The only solution I have tried so far, and the only one I can think of, was to define my own seed for each Dice object to be used in my Random object, but that seems to return the same number each time the rollDie method is called between each time the program is run (i.e. it will return (2, 5), (1, 3) every time the program is run with a seed of 1 and 2, respectively).
The question I have is if there is any way to prevent the two objects from returning the same number as the other?
The two dice objects are being created so close together they're getting the same seed. If you stick a delay between them (e.g. Thread.Sleep(2000)) you'll get different values.

Random number generator generating same numbers each time application is ran [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 8 years ago.
I know there are multiple times this question has been put forth but none of those solutions worked for me.
First I did this in my method called RandomNumGenerator(items)
List<int> randNum = new List<int>();
foreach (var item in items)
{
randNum.Add(new Random(1000).Next());
}
This always gave me the same number, and then after looking at this answer I did this:
Random rnd = new Random(1000);
foreach (var item in items)
{
randNum.Add(rnd.Next());
}
This gave me the numbers as below
325467165
506683626
1623525913
2344573
1485571032
Now while that is fine for every iteration of the loop, the problem here is, when I stop and re-run the application, I get the same numbers I got earlier all over again.
325467165
506683626
1623525913
2344573
1485571032
Is this behavior during debugging only or will I have the same issue every time I call the RandomNumGenerator?
You are seeding the Random instance always with the same seed 1000 here:
Random rnd = new Random(1000);
this will not do that since the current time is used as seed:
Random rnd = new Random();
Have a look at the constructor which takes an int.
Providing an identical seed value to different Random objects causes
each instance to produce identical sequences of random numbers.
As per MSDN.
public Random(
int Seed
)
Seed
A number used to calculate a starting value for the pseudo-random number sequence. If a negative number is specified, the absolute value of the number is used.
The reason for most beginner's mistakes involving RNGs (random number generators), is the lack of understanding about what the "seed" is and what it does.
So what is a "seed"?
The Random class is a class for generating pseudo-random numbers - or numbers that appear to be random. They are usually a mathematical function, that uses a parameter - the "seed" - to generate a sequence of numbers that appear to be random.
In the case of new Random(1000), the first 5 nonnegative random integers are
325467165
506683626
1623525913
2344573
1485571032
In your first code, you create a new sequence of pseudo-random numbers with the same seed every time you need a random number, so obviously your array is filled with the same number: 325467165, which happens to be the first nonnegative integer generated by new Random(1000).
This also explains why your second code always generates the same sequence of pseudo-random numbers every time your application is launched.
To ensure your app always generate different pseudo-random sequences, you need to use a different seed each time. By far the easiest way to ensure that, is to take your time, literally.
Random rnd = new Random(DateTime.UtcNow.Millisecond);
// Taking the millisecond component, because it changes quickly
Luckily, you don't have to type this much, because the default constructor for the Random class already does something similar to that.
Random rnd = new Random(); // Much simpler, isn't it?
Keep in mind that the Random class is not thread safe; if multiple threads attempt to access the same Random object concurrently, your RNG will return only 0 for the remaining of its lifetime.
Another thing to note, is that creating multiple Random objects one after the other - even when using time as the seed - can lead to the same sequence of pseudo-random numbers.
Random r1 = new Random();
Random r2 = new Random();
Random r3 = new Random();
Random r4 = new Random();
In the above code, chances are very high, that r1, r2, r3 and r4 will all generate the same sequence.
How is that possible?
Well, (un)fortunately, CPUs are blazing fast. A 1 GHz CPU can execute about 1 billion instructions per second (give or take); that's 1 instruction every 1 nanosecond - or 1 instruction every 1 millionth of a millisecond.
Creating a new Random object might require quite a lot of instructions, but most definitely less than a million of them.
So why do we need to manually define a seed, if using the clock's current millisecond count is what we "all" want and is already the default?
Because it can be very useful for keeping multiple terminals in sync.
Imagine a game, where important phenomena randomly appear, such as a change in weather that could completely overturn the game. You wouldn't want only one side to suffer from fog, while the rest still profits from clear weather, right?
Of course, you could have the server or the host generate random weather changes and notify the players about it; or you could define a seed before the game starts, and use that seed to ensure the same "randomness" across all players throughout the game.
Isn't coding fun?
You need to change this:
Random rnd = new Random(1000);
to
Random rnd = new Random();
From the Random Constructor docs:
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. This problem can be avoided by using a single
Random object to generate all random numbers. You can also work around
it by modifying the seed value returned by the system clock and then
explicitly providing this new seed value to the Random(Int32)
constructor. For more information, see the Random(Int32) constructor.
Key concept is random seed - the initial piece of data from which the Random derives everything else. If the seed is the same then "random" sequence will be the same.
By default the seed is set to zero, which obviously leads to repeating sequences amongst program runs.
To avoid that, you can construct your Random like this:
Random rnd = new Random();
... which is, under the hood, is:
Random rnd = new Random(Environment.TickCount);
This will init the Random object with amount of milliseconds from the OS start. This will be different each time your program starts, so you'll get different random sequences each time.
Random .Next() method generates pseudo-random number. You should Declare and initialize a random object instead of creating each time new object. And no need to use any Cryctography .. :)
You should use class level random variable. If you used a new Random at the method level as a local , the time-dependent seed would repeat itself generating identical sequence of random numbers.
class Program
{
static Random _r = new Random();
static void Main()
{
// use _r variable to generate random number
}
}

Generating Random Numbers in C# , declaring seed and min interval and max interval

i have defined a method like this:
private String getRadndomNumber(int min, int max) {
Random rnd = new Random((int) DateTime.Now.Ticks & 0x0000FFFF);
return Convert.ToString(rnd.Next(min,max));
}
I am defining both seed and min,max interval , I wanted to know whether the SEED value is of any help here or not ?
tnx :)
Whether the seed value is of any help depends on what you're trying to do!
You're using DateTime.Now.Ticks & 0xFFFF as the seed, which means that (i) you're basing the seed on the current time, and (ii) you're limiting that seed to values between 0 and 65535. In general, neither of these are a particularly good idea. The granularity of the system clock is about 15ms (iirc), so any calls to your method within the same 15ms "segment" will result in the same seed being used.
If you don't pass an explicit seed to the Random constructor then it effectively uses Environment.TickCount & 0x7FFFFFFF as the seed. So it will still be based on the current time, but it will have a much wider range than your custom seed: 0 to 2147483647.
From the documentation for the Random(Int32) constructor...
Providing an identical seed value to different Random objects causes
each instance to produce identical sequences of random numbers.
From the documentation for the Random() constructor...
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. This problem can be avoided by using
a single Random object to generate all random numbers.
Seed helps you generate a random number, it's the base number used for their random algorithm. Using the same seed each time could end up with a predictable set of "random" numbers coming out in sequence.
From the MS documentation:
"If your application requires different random number sequences,
invoke this constructor repeatedly with different seed values. One way
to produce a unique seed value is to make it time-dependent. For
example, derive the seed value from the system clock. However, the
system clock might not have sufficient resolution to provide different
invocations of this constructor with a different seed value."
The default constructor uses the system clock as seed but multiple instances created in the same tick could cause predictable numbers between the generators.

"new Random(x)" always generates the same numbers? [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 9 years ago.
I am trying to get a unique random number but i always get the same number every time i run the code. i will get 14 first then 6 but my list for holding all the used numbers doesn't seem to work.adding the 14 manually works but when i add randInt it doesn't work.
const int numCards = 32;
List<int> usedCards = new List<int>();
int randInt = 0;
Random rand = new Random(numCards);
usedCards.Add(14);
do
{
randInt = rand.Next(0, numCards);
MessageBox.Show(randInt.ToString(), "End Game", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
while (usedCards.Contains(randInt));
usedCards.Add(randInt);
Replace:
Random rand = new Random(numCards);
with
Random rand = new Random();
Supplying a fixed seed value (numCards always has the same value) in the Random constructor call will result in a predictable, reproducible sequence which is always the same for the same seed value, just like this (not quite but still the point is valid):
For example using a fixed seed of 1 and drawing 10 numbers ranging from 0 to 100, on my machine always produces the sequence
24,11,46,77,65,43,35,94,10,64
Using no seed value on the other hand, the sequence becomes unpredictable.
Without a seed value passed in, Random will generate a new seed value based on the current time, that's what you want to get a new sequence of random numbers - provided you don't initialize it again in fast order, that's why you should re-use Random instances instead of re-creating them every time.
Random Class
If you specify a seed value to the Random class constructor, it will generate the same sequence every time. The algorithm to produce the random number sequence is deterministic.
If you use the constructor without parameters, the Random object will use a seed value on the current time, so each Random object instantiated using this constructor will have a different sequence of random numbers as long as the time seed value is different which is likely.
You can still get the same sequence of numbers from two different Random objects if they are initialized very close in time to each other.
Random Constructor

Why does this Random Number Generator not random? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Why does it appear that my random number generator isn't random in C#?
Random number generator not working the way I had planned (C#)
I have this method to calculate a random value:
private double getMetrics(SourceFile sf)
{
Random r = new Random();
return (r.NextDouble());
}
However it returns always the same number, in my case 0.41500350386603
Why????
new Random() uses the current time as the seed value. Thus, if you are calling this function multiple times in a very short time span, it might return the same value. Here's the explanation 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. This problem can be avoided by using a single Random object to generate all random numbers.
Just declare the Random out of your method and everytime you call the method, new numbers will be created unless it gets disposed and recreated. When re-created, the numbers will be alike with the start again. You can make it wait a few ms before creating the random number if you want "more" unique numbers. If you want very unique numbers, GuID is better.

Categories

Resources