C# - Random number with seed - c#

I have this code:
var rand = new Random(0);
for(int i = 0; i < 100; i++)
{
Console.WriteLine(rand.Next(0, 100));
}
And program should give me 100 times the same number (because seed is the same), but it gives different numbers...
Why?
Edit:
When I will do
for(int i = 0; i < 100; i++)
{
Console.WriteLine(new Random(0).Next);
}
That returns the same number every time. That means, seed is changing? If yes, how? Is it increasing?

It should not give you 100 same numbers but it should give you exactly the same 100 numbers each time you restart the app.
Seed is used to make random predictable. Imagine multiplayer game where you want something to be random. But you want to make sure that this random behaves the same for each player/client. And seed is the way to go here.

Related

I need some help to complete this code of non-duplicate random numbers

I need some help to do my homework. I should write non-duplicate random numbers. I'm able to show random numbers but I don't know about non-duplicate.
Here's my code:
Random r = new Random();
for (int i = 0; i < 40; i++)
{
int temp = r.Next(0, 100);
Console.WriteLine(temp);
}
What do I need to do to generate non-duplicate number?
Note that this answer only deals with (relatively) small, pre-determined sets.
The reason the other (simple) solution is inefficient is this: you want to generate 100 random numbers between 0 and 99. You get to the point where you have generated 90 random numbers, and just need 10 more.
The problem is that you're still generating numbers between 0 and 99 every time, except now your chance of finding a number that hasn't already been generated is 1 in 10. So 9 of every 10 numbers you generate has already been added to the list.
Once you get down to just needing 1 number, your chance of generating the remaining 1 that hasn't already been generated is 1 in 100. So for every 100 numbers you generate, only 1 of them will be the last possible number.
I'm sure this is simplifying things given that the Random class is pseudo-random (i.e. it's an algorithm that appears random), but this does explain your situation and why the other answer will be slower.
An improved solution would be this:
// Add all of the numbers 0 to 100 to a list
var availableNumbers = new List<int>();
for (int i = 0; i < 100; ++i)
{
availableNumbers.Add(i);
}
Random random = new Random();
for (int i = 0; i < 40; ++i)
{
// Choose a random position in the available numbers list
var idx = random.Next(0, availableNumbers.Count);
// Print the number from this position in the list
Console.WriteLine(availableNumbers[idx]);
// Remove the item at this position
availableNumbers.RemoveAt(idx);
}
Because we start with a list of all available numbers, we are able to choose numbers from it at random. Removing items from the available numbers list means that they are not available to be chosen a second time. We no longer have to try many times to find an unused number, as removing them when we select them ensures that all of the numbers in the available numbers list are always only unused numbers.
You may use a HashSet to store the numbers and make sure there are no duplicates. Here's an example:
HashSet<int> numbers = new HashSet<int>();
Random r = new Random();
for (int i = 0; i < 40; i++)
{
int temp;
do
{
temp = r.Next(0, 100);
} while (numbers.Add(temp) == false); // If the `.Add()` method returns false,
// that means the number already exists.
// So, we try to generate another number.
Console.WriteLine(temp);
}

Why is there a strong correlation between random number and correct guesses?

In trying to test whether knowing the history of a random number could help predict the future results, I found a strong, unexpected correlation between the average of the number generated, and the number of correct guesses.
The test was supposed to simulate flipping a coin (heads = 0, tails = 1) and if previous attempts were biased towards heads then guess tails and vice versa.
Why is the sum of the generated numbers always nearly equal to the number of correct guesses in the following LinqPad program?
void Main()
{
var rnd = new Random();
var attempts = 10000000;
var correctGuesses = 0;
long sum = 0;
decimal avg = 0.5m;
for (int i = 0; i < attempts; i++)
{
var guess = avg < 0.5m ? 1 : 0;
var result = rnd.Next(0, 2);
if (guess == result)
{
correctGuesses += 1;
}
sum += result;
avg = (decimal)sum/(decimal)attempts;
}
attempts.Dump("Attempts");
correctGuesses.Dump("Correct Guesses");
avg = (decimal)sum / (decimal)attempts;
avg.Dump("Random Number Average");
}
Have a made an error in the code? Is this a natural relationship? I expected the averages to converge at 0.5 as I increased the number of attempts because the distribution is fairly even - I tested this with 10bn calls to Random.Next(0,2) - but I did not expect the sum of generated numbers to correlate to the number of correct guesses.
Your error is this line:
avg = (decimal)sum/(decimal)attempts;
Makes no sense to divide the sum (based over i to that point) by attempts. Divide by i (EDIT: more precisely i+1) instead for avg to give you something meaningful.
The Random class, without a seed, generates a random number using the current time as seed, meaning that a call of the rnd.Next method in your cycle will result in the same number several times over, depending on how fast your machine goes through the cycle.

Random not that random [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 8 years ago.
I am using Random to generate a sequence of random number. I am constructing the random object just once and then inside the loop generating the random values (300 of them). The problem is that once I get all the values and do a sort on them I realize that some of them are equal and/or sequential: I am generating numbers from 0 to 50000.
This is my script:
Random rnd = new Random();
for (int n=0; n < 300; n++)
{
int RndNumber = rnd.Next(0, 50000);
System.Threading.Thread.Sleep(3);
}
Can someone have a clue on why this is happening, and how can I improve this to make it more random?
So this is the birthday paradox*. When you draw 300 numbers from 50000 the approximate probability that at least two of them are equal is
p(300) = 1 - exp(-300 * 300 / (2 * 50000))
= 0.59
(I could work out the exact probability but I'm lazy!.)
So, chances are more likely than not that you'll have a collision. Sequential is even more likely (now you don't need a collision, you just need n - 1 and n or n and n + 1 to be hit for some n).
Random is fickle.
*: In case you're not familiar with it, it says that if you have twenty-three people in a room, it is more likely than not that at least two people in the room share the same birthday.
!: Okay, I worked it out. It's 0.5953830515549951746819986449....
Research:
If you use the constructor without parameters new Random() the seed is depending on the current servertime.
Random(): "Initializes a new instance of the Random class, using a time-dependent"
http://msdn.microsoft.com/en-us/library/system.random.aspx
So, if I try it like this:
for(int i = 0; i < 1000; i++)
{
Random ran = new Random();
Console.WriteLine(ran.Next(50001));
}
I only get 3 different numbers about 300 times within a thousand calls! Not that random...
Setting the seed in the constructor new Random(0) returns a fix serie of numbers.
e.g. new Random(0).Next(50) always! returns 36. Try it yourself, if you don't trust me;
What we need for "real" random numbers is a changing seed, that's independent of time.
I'm using Hashcode of changing values:
e.g. Guid.NewGuid().GetHashCode() or DateTime.Now.GetHashCode()
Result:
Random ran = new Random(Guid.NewGuid().GetHashCode());
for(int i = 0; i < 1000; i++)
{
Console.WriteLine(ran.Next(50001));
}
or (for better performance):
for(int i = 0; i < 1000; i++)
{
int val = Guid.NewGuid().GetHashCode() % 50001;
val = val > 0 ? val : -val;
Console.WriteLine(val);
}
PS: The maximum of the Next(max)-method is always max - 1;
-> ran.Next(11) can return 0,1,2,...,8,9,10. Not 11!
As an explanation of why you're seeing the occasional duplicate, Jason's answer is right on.
If what you want is 300 distinct random numbers, what about something like this?
static IEnumerable<int> GetRandoms(int min, int max)
{
var rand = new Random();
while (true)
{
yield return rand.Next(min, max);
}
}
var distinctRandoms = GetRandoms(0, 50000).Distinct().Take(300);

C# Random codes - Is most of it simply wrong?

I had a lot of issues with randomizing lists. I am talking about a list of 200 elements, where I want to shuffle the list. Don't get me wrong, I read a lot of examples, and on first glance there are pretty nice things, like this:
Randomize a List<T>
But in my experience, at least on a fast machine, this is basically worthless. The shuffling works so fast that there is NOT a MS delay between two calls to Random.NEXT() which results in not nearly random behaviour.
I am NOT talking about super secure stuff, just a basic game random. I know I can add a delay of 1 MS, but this means "wasting" 200 MS just to randomize a list.
Now I found this approach: http://www.codinghorror.com/blog/2007/12/shuffling.html
It looks nice, using GUIDs to sort. BUT aren't they created the same way? Lets step it up a notch, lets assume I want to create 1000 numbers, between 0 - 5. This code is basically useless:
var resultA = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultA.Add(new Random().Next(5));
}
var resultB = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultB.Add(new Random().Next(5));
Thread.Sleep(1);
}
A does not work at all, at least not im my environment in Windows Phone 7. B is fine, but it takes a second, which is also stupid. Any comments or thoughts, it can't be that hard to create a random list of integers :-)
Don't keep initializing a new instance of Random; make just one and continually reference it.
var random = new Random();
var resultA = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultA.Add(random.Next(5));
}
You are correct that repeatedly creating new instances of Random within the same "timestamp" will result in the same seed; but calling .Next on an instance of Random "advances" the seed so that the next number you retrieve is (most likely) different.
This is also covered in the documentation on Random:
... because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers.
...
This problem can be avoided by creating a single Random object rather than multiple ones.
You need to keep hold of the same instance of Random.
var random = new Random();
var resultA = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultA.Add(random.Next(5));
}
var resultB = new List<int>();
for (int i = 0; i < 1000; i++)
{
resultB.Add(random.Next(5));
Thread.Sleep(1);
}
This is because when Random initializes it uses the system clock to get a point in time. When you call next it can use the difference in time to get the next number. If you keep initializing a Random object you will keep getting the same number most of the time.
The shuffling works so fast that there is NOT a MS delay between two calls to Random.NEXT() which results in not nearly random behaviour.
What makes you think that there needs to be a ms delay between two calls to Random.Next?
Your bog standard random number generator is going to take some initial seed (say the system clock) and then repeatedly some algorithm to that seed to produce a sequence of numbers that appears to be random. Most of these algorithms don't take the clock as an input other than for the seed and so it doesn't matter how quickly two consecutive calls are executed.
The reason your code fails is because you keep instantiating a new random number generator on each iteration. This is where the clock can kill you because you end up with the same seed twice. You are not calling Random.Next consecutively on the same random number generator. You are calling Random.Next on a new random number generator on every iteration and sometimes these random number generators are seeded with the same value because you are seeding them by the system clock.
Move the instantiation of the random number generator outside of your loop.
var resultA = new List<int>();
Random rg = new Random();
for (int i = 0; i < 1000; i++) {
resultA.Add(rg.Next(5));
}

C# code only gives expected results on step through?

Ok so I have a dice throw app...
When I step through the code it functions normally and 'results' contains the correct number of throw results and they appear to be random, when I leave the code to run and do exactly the same thing it produces a set of identical numbers.
I'm sure this is a logical error I cannot see but fiddling with it for hours hasnt improved the situation, so any help is much appriciated. :)
class Dice
{
public int[] Roll(int _throws, int _sides, int _count)
{
Random rnd = new Random();
int[] results = new int[_throws];
// for each set of dice to throw pass data to calculate method
for (int i = 0; i < _throws; i++)
{
int thisThrow = Calculate(_sides, _count);
//add each throw to a new index of array... repeat for every throw
results[i] = thisThrow;
}
return results;
}
private int Calculate(int _sides, int _count)
{
Random rnd = new Random();
int[] result = new int[_count];
int total = 0;
//for each dice to throw put data into result
for (int i = 0; i < _count; i++)
{
result[i] = rnd.Next(1, _sides);
}
//count the values in result
for (int x = 0; x < _count; x++)
{
total = total + result[x];
}
//return total of all dice to Roll method
return total;
}
}
First mistake: Never use multiple instances of Random, use a single instance, and pass that along with the other parameters.
When you create "Random rnd = new Random();" it is seeded by the current time. When you debug your code (which takes time) it will be seeded differently each time.
Create 1 instance of Random, and reference that everywhere.
You're creating a random class every time you need to create a number. Doing this will give you the nutty results.
See here: FROM MSDN
This problem can be avoided by creating a single Random object rather than multiple ones.
To improve performance, create one Random object to generate many random numbers over time, instead of repeatedly creating a new Random objects to generate one random number.
E.g. create a private instance of Random...
In addition to what has been mentioned before...
Use Random for things like dice, card games, choosing random images and so forth. If you ever need to create a random number for security sake, use System.Security.Cryptography.RandomNumberGenerator. This simple example shows creating a random integer.
RandomNumberGenerator gen = RandomNumberGenerator.Create();
byte[] myBytes = new byte[4];
gen.GetBytes(myBytes);
int myValue = (BitConverter.ToInt32(myBytes, 0));
DO NOT use this unless you have a security need. The performance is less than that of the Random class. I suppose you could use this to seed Random but that might be overkill.
EDIT: It occurred to me that I had never tested this. A quick performance test showed the following:
1,000,000 random numbers:
RandomNumberGenerator: 2.6 seconds
Random: .015 seconds.
So Random is about 150 times faster.
Give the constructor Random a seed. That's the problem.
http://msdn.microsoft.com/en-us/library/aa329890%28VS.71%29.aspx
Random r = new Random(DateTime.Now.Millisecond);

Categories

Resources