My program needs to:
a. Generate an array of 20 random integers from zero to nine. Search for the first occurrence, if any, of the number 7, and report its position in the array.
b. Repeat the computation of part a 1000 times, and for each position in the array, report the number of times that the first occurrence of a 7 in the array is at that position
However whenever I run the program I get strange results (different every time) such as:
No sevens found at any position
1000 sevens found at one position and no sevens found anywhere else
Hundreds of sevens found in 2 positions, and none found anywhere else.
Does anyone have an idea what is wrong with my program?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Week_6_Project_2
{
class Program
{
static int intArrayLength = 20;
static int[] resultsArray = new int[intArrayLength];
public static Array generateRandomArray() {
int[] randomNumberArray = new int[intArrayLength];
Random random = new Random();
int popcounter = 0;
while (popcounter < intArrayLength) {
randomNumberArray[popcounter] = random.Next(0, 10);
popcounter += 1;
}
return randomNumberArray;
}
public static void searchForSevens()
{
int counter = 0;
int[] randomArray = (int[])generateRandomArray();
while (counter < intArrayLength)
{
if (randomArray[counter] == 7)
{
resultsArray[counter] += 1;
counter = intArrayLength;
}
counter += 1;
}
}
static void Main()
{
int searchCounter = 0;
while (searchCounter < 1000)
{
searchForSevens();
searchCounter += 1;
}
int displayCounter = 0;
while (displayCounter < intArrayLength)
{
Console.WriteLine("Number of first occurrence of 7 at position {0} = {1}", displayCounter, resultsArray[displayCounter]);
displayCounter += 1;
}
Console.ReadLine();
}
}
}
Your main problem is that each searchForSevens() test only takes a small fraction of time and the Random class uses auto-seeding from the clock. The clock however has a limited resolution. The result is that many (sometimes all) of your random sequences will be the same. And at most you will have 2 or 3 different result sets.
The simple fix for this single-threaded program is to use 1 static instance of Random.
You're instantiating a new instance of Random every time you call the generateRandomArray method. Since the random number generator uses the current time as a seed, instantiating two Random instances at the same time results in the same numbers being generated, which explains your unexpected results.
To solve your problem, you should only instantiate one Random instance, store it in private field, and reuse it every time you call the Next method.
The problem I assume stems from the fact, that Random() uses current time as seed. And the computation happens so fast, that each time new Random() is called, it uses same time. So you get same sequence of numbers.
To fix this, you simply need to set seed by yourself, incremmenting it every cycle should be enough.
long base = DateTime.Now.TotalMilliseconds;
Random rand = new Random(base+searchCounter);
.. something like that.
I will not answer but will try to give an analogy for the people that think that they need more then one Random instance...
Suppose that you need to fill 6 sheets of paper with random numbers from 1-6. Ask yourself this: do you need 6 dices or one to do the job? If you answer that you need more than one dice, ask yourself this: how different or more random is throwing different dice instead of same dice every time?
I mean, if you throw ONE on a dice, next throw of a dice won't have any less chance to be ONE again than it would be any other number. It goes against intuition, but it is mathematically and statistically so.
In your original code, you're calling the Random method in rapid succession [broken example based on OP's original code], thus seeding the method with the same number, resulting in duplicate "random" numbers. Creating a static member will ensure randomness simply because you're only creating a single instance of it.
Try creating a single static instance of random like this. [static member example].
static readonly Random Random = new Random();
Based on this, here's how I would solve your particular problem.
using System;
namespace Week_6_Project_2
{
class Program
{
// ******************************************
// THIS IS A SINGLE INSTANCE OF Random.
// read below as to why I'm seeding the instantiation of Random();
static readonly Random Random = new Random(Guid.NewGuid().GetHashCode());
// ******************************************
private const int IntArrayLength = 20;
static readonly int[] ResultsArray = new int[IntArrayLength];
public static Array GenerateRandomArray()
{
var randomNumberArray = new int[IntArrayLength];
var popcounter = 0;
while (popcounter < IntArrayLength)
{
randomNumberArray[popcounter] = Random.Next(0, 10);
popcounter += 1;
}
return randomNumberArray;
}
public static void SearchForSevens()
{
var counter = 0;
var randomArray = (int[])GenerateRandomArray();
while (counter < IntArrayLength)
{
if (randomArray[counter] == 7)
{
ResultsArray[counter] += 1;
counter = IntArrayLength;
}
counter += 1;
}
}
static void Main()
{
var searchCounter = 0;
while (searchCounter < 1000)
{
SearchForSevens();
searchCounter += 1;
}
var displayCounter = 0;
while (displayCounter < IntArrayLength)
{
Console.WriteLine("Number of first occurrence of 7 at position {0} = {1}", displayCounter, ResultsArray[displayCounter]);
displayCounter += 1;
}
Console.ReadLine();
}
}
}
Further reading about Random()
Beyond the answer above, sometimes it is necessary to seed Random(int); (I like to use the HashCode of a Guid) to ensure further randomness. This is because the default seed uses the clock which from the docs [microsoft] has a finite resolution. If your class is instantiated multiple times in quick succession (< 16ms), you will get the same seed from the clock... this breaks stuff.
[example of seeded Random(int) run in rapid succession with random results]
"using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers."
hear me when I say that you should NOT instantiate a new Random on every iteration of a loop -- use a static member
Another valid reason to implement your own seed is when you want to recreate a random sequence [example of two identical lists based on same seed]. Re-using the same seed will recreate the sequence since the sequence is based on the seed.
note: others might say that seeding it is not necessary [link], but I personally believe that for the additional few keystrokes and the microscopic hit on the clock, you might as well increase the probability of a unique seed. It doesn't hurt anything, and in some situations it can help.
Related
I want to make 2 different Random objects in 2 consecutive lines of code. The parameterless constructer of the Random class is like this:
public Random()
: this(Environment.TickCount) {
}
It uses Environment.TickCount as the seed. TickCount represents the amount of time that has passed since the OS is switched on, right?
I tried the following:
Random r1 = new Random ();
Random r2 = new Random ();
And I found out that the 2 Random objects had the same seed because their Next methods return the same number each time. I was surprised by how fast a line of code can be executed. Then I tried:
long tick1 = Environment.TickCount;
for (int i = 0 ; i < 100000 ; i++) {
}
long tick2 = Environment.TickCount;
Console.WriteLine (tick2 - tick1);
And I get 0. So I iterated 100000 times and still, not even 1 millisecond has passed?
I just want to ask how can I create 2 different Random objects or is there another way to generate random numbers?
Base on #PankajMishra's answer, try this one:
//Function to get random number
private static readonly Random getrandom = new Random();
private static readonly object syncLock = new object();
public static int GetRandomNumber(int min, int max)
{
lock(syncLock) { // synchronize
return getrandom.Next(min, max);
}
}
lock block is effective when you use it in a multi-threading program, if you sure just one thread use it, so you can prevent lock to increase your code performance.
To me, it seems like an XY problem, because you don't need two separate Random instances - you can use the same one to generate all your random number, can't you? Just call Next again and that's it:
var rnd = new Random();
int firstRandomInt = rnd.Next();
int secondRandomInt = rnd.Next();
However, you really need 2 Random instances, you can use the first one to seed the second one:
var rnd = new Random();
var rnd2 = new Random(rnd.Next());
This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 7 years ago.
Consider this method:
private static int GenerateRandomNumber(int seed, int max)
{
return new Random(seed).Next(max);
}
On my machine, executing this loop yields the same number through 1500 iterations:
for (int i = 0; i < 1501; i++)
{
int random = GenerateRandomNumber(100000000, 999999999);
Console.WriteLine(random.ToString());
Console.ReadKey();
}
I get 145156561, for every single iteration.
I don't have a pressing issue, I was just curious about this behavior because .Next(max) says "Returns a Non Negative random number less than the specified maximum. Perhaps I am not understanding something basic.
You're always seeding a new instance with the same seed, and then grabbing the first max. By using a Seed, you're guaranteeing the same results.
If you want to have a static, random number generation that does different results, you should rework this a bit. However, since Random is not threadsafe, it requires some synchronization when used statically. Something like:
private static Random random;
private static object syncObj = new object();
private static void InitRandomNumber(int seed)
{
random = new Random(seed);
}
private static int GenerateRandomNumber(int max)
{
lock(syncObj)
{
if (random == null)
random = new Random(); // Or exception...
return random.Next(max);
}
}
Dilbert has encountered the same problem back in 2001:
http://dilbert.com/strips/comic/2001-10-25/
Coincidence?
I don't think so.
And random.org agrees : http://www.random.org/analysis/
The problem is that you are creating a new Random instance with the same seed number each time. You should create a single Random instance (store it in a static if necessary) and simply call the next method on that same instance.
Random number generation is not truly random, see this Wikipedia entry for more details.
Salam to All,
Well it drove me crazy as well. The answer is simple. Change the seed before you generate random.
Example:
I want to generate random number between 1 to 10
Random rnd = new Random(DateTime.Now.Second);
int random_number = rnd.Next(10);
Put it inside a loop and run it three times. It will give out random numbers below 10.
Pseudo-random number generator usually work by choosing a seed, and then generating a deterministic sequence based on that seed. Choosing the same seed every time, you generate the same sequence.
There are "only" 2^32 different random sequences in .NET.
Not sure how the internals work.. check wiki for it, but it's very simple.
public class MathCalculations
{
private Random rnd = new Random();
public Int32 getRandom(Int32 iMin, Int32 iMax)
{
return rnd.Next(iMin, iMax);
}
}
public class Main
{
MathCalculations mathCalculations = new MathCalculations();
for (int i = 0; i < 6; i++)
{
getRandom(0,1000);
}
}
will generate Number1, Number2, Number3, Number4, Number5, Number6 (1 seed, 1 sequence of many numbers, random*not really, but approx.*)
if you however do this:
public class MathCalculations
{
public Int32 getRandom(Int32 iMin, Int32 iMax)
{
Random rnd = new Random();
return rnd.Next(iMin, iMax);
}
}
public class Main
{
MathCalculations mathCalculations = new MathCalculations();
for (int i = 0; i < 6; i++)
{
getRandom(0,1000);
}
}
You will now get Number1, Number1, Number1, Number1, Number1, Number1 (1 seed, 6 equal sequences of many numbers, always pick the same starting number from each equal sequence).. At some point Number1 will be different, because the seed changes over time.. but you need to wait some time for this, nonetheless, you never pick number2 from the sequence.
The reason is, each time you generate a new sequence with the same seed, hence the sequence is the same over and over again, and each time your random generated will pick the first number in it's sequence, which, with the same seed, is of course always the same.
Not sure if this is technically correct by the underlying methods of the random generator, but that's how it behaves.
In the event that anyone is looking for a "quick and dirty" "solution" (and I use that term with caution) then this will suffice for most.
int secondsSinceMidnight = Convert.ToInt32(DateTime.Now.Subtract(DateTime.Today).TotalSeconds);
Random rand = new Random(secondsSinceMidnight);
var usuallyRandomId = rand.Next();
Please note my use of usually random. I agree that the item marked as the answer is a more correct way of doing this.
When I run the following code in Mono (and not in Microsoft's C# apparently) in the monodevelop IDE. I get the same sequence of random numbers every time (00111111110110001001). If I change the range to something else e.g. r.Next(0, 5) then I do get random values. This seems very weird to me .. is this a bug or am I doing something dumb?
NOTE: it seems sometimes these numbers are negated.. e.g. I see 11000000001001110110 occasionally.
using System;
namespace TestRNG
{
class MainClass
{
public static void Main (string[] args)
{
Random r = new Random ();
for (int i = 0; i < 20; i++) {
Console.Write(r.Next(0, 2));
}
Console.WriteLine();
}
}
}
This is not the "Calling Next() on instances of Random called too closely together and therefore seeded with the same seed from the system clock problem".
Using the following code:
using System;
namespace TestRNG
{
class MainClass
{
public static void Main (string[] args)
{
Random r = new Random (Guid.NewGuid().ToByteArray()[0]);
for (int i = 0; i < 20; i++) {
int rn = r.Next ();
Console.WriteLine(rn + " " + (rn % 2));
}
Console.WriteLine();
}
}
}
I see that I get different values for rn every time but the sequence of values for rn % 2, which is what I suspect r.Next() is returning, is the same old values I always see. This leads me to believe that the Russian? fellow who posted an answer before and was down-voted to oblivion was correct (he's subsequently removed his answer). See http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx for example.
Based on one of the comments below this may only be a mono implementation thing.
Well, extending on what swistak said(because i used the Guid class too), this is the code i made for your issue, is already tested and it works:
using System;
using System.Linq;
namespace pruebaDeNumerosAleatorios
{
class MainClass
{
public static int RandomNumber()
{
Random x = new Random(Guid.NewGuid().ToByteArray().First());
return x.Next(0, 20);
}
public static void Main(string[] args)
{
for (int i = 0; i < 20; i++)
Console.WriteLine(RandomNumber());
}
}
}
As it was said before, you don't give the time to the internal clock (which you are using as seed) to change between iterations so, the number generated is the same. What i did here is implement the Guid class which generates a 'unique' number, convert it as an array of bytes and just used the first element of the array as seed.
i did this in a method because that guarantees me that everytime the method is called a diferent number is generated by the Guid class, so im using a different seed for the random number.
You can generate "more random" number without much higher impact on performance by using Guid class:
Random r = new Random(Guid.NewGuid().ToByteArray()[0]);
Edit: The problem with getting similar values every time is because Random.Next() is taking value from current system clock, so probably there isn't much difference in time between each compilation to generate varied values. Try running your code in a loop and values should be more varied.
This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 9 years ago.
// Create a string array that consists of ten lines.
string[] personalNumbers; // declare personalNumbers as a 10-element array
personalNumbers = new string[10]; //= { "First number", "Second number", "Third line", etc}
for (int i = 0; i < 9; i++) // populate the array with 10 random values
{
Random random = new Random();
int randomNumber = random.Next(1, 50);
string RandomNumberText = Convert.ToString(randomNumber);
personalNumbers[i] = RandomNumberText;
}
Hi, I know that this SEEMS to be a duplicate of previously asked questions, but I am trying to
generate a series of random numbers between 1 and 50 to populate an array
The problem is, if I do it as we were taught in class, each number is the same
I know that the problem is that the tight loop causes the random to be seeded with the same number
What NONE of the other threads addresses however, is HOW to fix this problem when using a loop iteration....
All of the explanations thus far are so far advanced beyond our level that I (and the other askers BTW) have no clue how to implement them as a solution, which I also cannot submit in class as they are techniques that we have not covered
The tutorials at Microsoft insist that putting the random inside the loop is the right solution
I've tried putting an instance of random outside the loop and then calling it from inside the loop but this has caused an exception
Is there a straightforward way to use random to create a series of random numbers that doesn't run into this problem?
Create the random instance outside of the loop:
Random random = new Random();
for (int i = 0; i < 9; i++) // populate the array with 10 random values
{
MSDN:
The random number generation starts from a seed value. If the same
seed is used repeatedly, the same series of numbers is generated. One
way to produce different sequences is to make the seed value
time-dependent, thereby producing a different series with each new
instance of Random. By default, the parameterless constructor of the
Random class uses the system clock to generate its seed value, while
its parameterized constructor can take an Int32 value based on the
number of ticks in the current time. However, 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.
You have to define the Random object outside the loop and just get a number each time inside the loop. If you create it each time again, it will be created with the same initial value because the interval between creations is too small.
Random random = new Random();
for (int i = 0; i < 9; i++) {
int randomNumber = random.Next(1, 50);
}
I've tried putting an instance of random outside the loop and then
calling it from inside the loop but this has caused an exception
Here are two concrete examples, one for a Console app, and the other for a WinForms app.
This is one way to declare it in a Console app. random can be used from anywhere within the application, even in methods other than Main():
class Program
{
private static Random random = new Random();
static void Main(string[] args)
{
// ... code ...
for (int i = 0; i < 9; i++) // populate the array with 10 random values
{
int randomNumber = random.Next(1, 50);
personalNumbers[i] = randomNumber.ToString();
}
// ... code ...
}
}
This is one way to declare it for use in a WinForms app. random in this example can be used anywhere within Form1:
public partial class Form1 : Form
{
private Random random = new Random();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// ... code ...
for (int i = 0; i < 9; i++) // populate the array with 10 random values
{
int randomNumber = random.Next(1, 50);
personalNumbers[i] = randomNumber.ToString();
}
// ... code ...
}
}
This should cover most simple homework assignments. Nothing fancy here.
thank you for the input, it is much appreciated!
I have posted the complete code thus far, which is now giving me what seems like "random" numbers
in that they are always different when I run it
#Steve thank you...I have looked at those questions, but all of the solutions involve using some other technique than random() which I am not allowed to use
#Oerkelens thank you, when I moved the code for random() outside the loop, I got two possible results
one was a series of 9, 9-digit random numbers, or an exception that says
Error 1 A local variable named 'randomNumber' cannot be declared in this scope because
it would give a different meaning to'randomNumber', which is already used in a 'parent or current' scope to denote something else
I have posted the larger bit of code to show what I have changed to get it to work...I don't really understand how to properly call the random() from within the loop, but for some reason, having the same line both inside and outside of the loop did the trick
#Preston - we don't have a textbook for this course, and we are only allowed to use techniques that are contained within the Microsoft C# video tutorials by Bob Tabor (learnvisualstudiodotnet) and Envato (learn C# in 30 days)
I apologize if this all seems obvious to you, but we are in the position of being told that half-way through the course that we are switching from learning to program in Visual Basic to C#, so all of our work now needs to be re-written in C#, without any particular instruction in how to how to use this language...needless to say, it is a huge stress and we are being left without any resources to do this, so much of what we are doing is guesswork
the more complete code that is "working"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace GuessingGameProgram
{
class Program
{
int randNum;
static void Main(string[] args)
{
// Create a string array that consists of ten lines.
string[] personalNumbers; // declare personalNumbers as a 10-element array
personalNumbers = new string[10]; //= { "First number", "Second number", "Third line", etc}
Random outsideLoopRandom = new Random();
int randomNumber = outsideLoopRandom.Next(1, 50);
for (int i = 0; i < 9; i++) // populate the array with 10 random values
{
randomNumber = outsideLoopRandom.Next(1, 50);
string RandomNumberText = Convert.ToString(randomNumber);
personalNumbers[i] = RandomNumberText;
}
// WriteAllLines creates a file, writes a collection of strings to the file,
// and then closes the file.
//System.IO.File.WriteAllLines(#"C:\Users\Public\TestFolder\WriteLines.txt", lines);
foreach (string i in personalNumbers) // this is just a test to see what the output is
{
Console.Write("{0} ", i);
}
Console.ReadLine();
}
}
}
//randNum = Random.Equals(1, 50);
//StreamReader myReader = new StreamReader("personalNumbers.txt");
//string line = "";
//while (line != null)
//{
// line = myReader.ReadLine();
// if (line != null)
// Console.WriteLine(line);
//}
//myReader.Close();
//Console.ReadLine();
//personalNumbers = RandomNumbers.next(1, 10);
//int returnValue = personalNumbers.Next(1, 50);
//int Guess = 0;
//Console.WriteLine("Please guess a number between 1 and 50");
//Console.ReadLine();
////while (Guess = Convert.ToInt32(Console.Read());
//if (Guess < returnValue)
//{
// Console.WriteLine("Wrong! the number that I am thinking of is higher than " + Guess + ". Try again!");
// Console.ReadLine();
//}
//if (Guess > returnValue)
//{
// Console.WriteLine("Wrong! The number that I am thinking of is lower than " + Guess + ". Try again!");
// Console.ReadLine();
//}
// else if (Guess = returnValue)
// Console.WriteLine("Correct! The number that I was thinking of was " + Guess + ". Congratulations!");
// //{
//Console.WriteLine("Let's play a guessing game!")
//Console.WriteLine("")
//Console.WriteLine("guess a number between 1 and 10")
//Console.WriteLine("")
//randNum = randomGenerator.Next(1, 10)
//While userGuess <> randNum
// {
// userGuess = Console.ReadLine()
// }
// If userGuess > randNum Then
// Console.WriteLine("too high, guess again!")
// {
// If userGuess < randNum Then
// Console.WriteLine("too low, guess again!")
// }
// Else
//End While
//Console.WriteLine("Correct! the secret number is " & randNum)
//Console.ReadLine()
For a part of a program i need the following 2 methods.
The first method listed will generated a random number.
where the 2nd method will "call" this method to fill the array.
The array has a max. number of elements defefined on 100 (and all the random generated numbers should be between 1-100).
The problem is i never get random numbers generated. (either i get 100 x the same value, 3 random numbers divided over the 100 max. elements of the array, or the same value 100 times all over again).
The problem should be in the first method, but i cannot seem to figure out the problem.
Been staring at this for quite some time now...
The problem should be with the return, cause it DOES create random generated numbers. But how do i return the generated value every time? (the int method has to be called with the 3 parameters).
private int ValidNumber(int[] T, int X, int Range)
{
for (byte I = 0; I < T.Lenght; I++)
{
Random RndInt = new Random();
X = RndInt.Next(1, Range+1);
}
return X;
}/*ValidNumber*/
public void FillArray(int[] T, int Range)
{
for (byte I = 0; I < T.Length; I++)
{
T[I] = ValidNumber(T, I, Range);
}
}/*FillArray*/
Console code:
public void ExecuteProgram()
{
ClsBereken Ber = new ClsBereken();
//const byte Range = 100;
const int Max = 100;
int[] T = new int[Max];
Ber.FillArray(T, Max);
DisplayArray(T);
}/*ExecuteProgram*/
private void DisplayArray(int[] T)
{
for (byte i = 0; i < T.Length; i++)
{
Console.Write("{0,4} ", T[i]);
}
Console.WriteLine();
}/*DisplayArray*/
Any help alot appreciated.
Kind Regards.
Re-use the Random instance. NOTE I've edited this to show passing the Random instance down, but I'm really not sure what ValidNumber is trying to do - it looks like it is juts burning up CPU cycles? I would suggest you can remove ValidNumber completely (and just use the next value from the Random in FillArray), but presumably you are trying to do something here - I'm just not sure what!
private int ValidNumber(int[] T, int X, int Range, Random random)
{
for (byte I = 0; I < T.Lenght; I++)
{
X = random.Next(1, Range+1);
}
return X;
}/*ValidNumber*/
public void FillArray(int[] T, int Range)
{
Random random = new Random();
for (byte I = 0; I < T.Length; I++)
{
T[I] = ValidNumber(T, I, Range, random);
}
}/*FillArray*/
When you create a Random, it is "seeded" using the system clock, but this is rounded heavily. If you create lots of Random in a tight loop, they all get the same "seed", so they all create the same next number.
If necessary you could move the Random further out (if you have other loops), or make it static (but if you do that you need to worry about synchronization too).
The problem is that you are reinitializing rndint over and over.
take the line:
Random RndInt = new Random();
and move it in front of the loop and see if that fixes it.
When you initialize a random object, it is assigned a seed (probably based on the time), and that seed is used to generate a series of seemingly random values. However, if you plug in the same seed to two random objects, you will get the same series of random numbers.
So, what is happening in your code is you are initializing a new random object with a seed, and then asking for the first random number in its series. Then, you are initializing another random object (even though it is assigned to the same name, it is a new object) and it is getting the same seed, and you are again asking for the first random number in the series. So naturally, you are getting the same random number over and over.
You are continuously creating an new Random object. I'm afraid this is seeded (randomized) by the timestamp of creation. Since this is really fast and happens multiple times, the seed is the same, and so is the result of the call RndInt.Next(1, Range+1);.
By the way, even though not incorrect, it's not a common practice in c#.net to start with a capital letter on names of local variables and parameters.
Any random number generation algorithm* is not truly random; it is simply a deterministic algorithm that has been specifically designed to output numbers that resemble randomness. (See Pseudorandom number generator.) Since the algorithm is deterministic, its output is completely dependent upon a starting "seed" value.
The Random class in .NET has two constructors: one which takes an integer seed, and another which takes no parameters. This one bases its seed off the current time.
From this information perhaps you can guess why creating a new Random instance for every value in your array results in the entire array being filled with the same number: every time you construct a Random object within a very small time frame, it will have the same seed value, which means it will generate identical output to another Random object constructed within the same time frame.
As Marc Gravell has already indicated, you should be using only a single Random instance to generate a sequence of random numbers.
*Well, almost any. I believe there are hardware implementations of random number generators that factor in random noise (taken from the surrounding environment) and may therefore be considered "truly" random. Whether you believe these are actually random
depends on your personal definition of "random" and whether or not you believe that we live in a deterministic universe.
You can pass Random() a seed but if you send it the same seed number you will get the same results. The way you are using it
Random rnd = new Random();
Is using an auto-generated seed based on time. But you may not get seemingly random results if you don't at least sleep for a second. (Source http://msdn.microsoft.com/en-us/library/system.random(VS.71).aspx)
As everyone has mentioned here already your biggest issue is the fact you keep recreating the random object each iteration.