views:

79

answers:

3

I'm trying to generate two random numbers, one for a row and one for a column.

In this exact instance, it is a multidimensional array with 4 rows and 4 columns. Thus, the number generator can use the values 0 to 3 for both row and column.

I must also make sure that there are no duplicate points, so if [0,0] is chosen the first time, [0,0] can not be used again.

When I implement my solution and print out the results, it takes a LONG time for C# to generate a working set of numbers.

For instance, I am only looking for 10 numbers out of 16 possibilities in this case and this is what the output looked like:

[1,1]
// {snip 26 times}
[3,3]
// {snip 76 times}
[0,0]
// {snip 83 times}
[2,2]
// {snip 69 times}
[0,0]
// {snip 84 times}
// {etc...}
[0,1] // which is a valid number

Why is it finding [0,0] as a set of random numbers 84 times in a row? Does it not use my system's local entropy or what?

Here is the relevant code:

private static void RandomlyAssignSeat(string name, string[,] seatingArray)
{
    int row, col;

    // loop until seat is not reserved, then reserve it
    do
    {
        // generate random row
        row = RandomNumber(0,seatingArray.GetLength(0));

        // generate random column
        col = RandomNumber(0,seatingArray.GetLength(1));

        Console.WriteLine("[" + row + "," + col + "]");
    } while (ReserveSeat(row, col, name, seatingArray) == false);
} // end method RandomlyAssignSeat

with RandomNumber looking like so:

private static int RandomNumber(int min, int max)
{
    Random random = new Random();
    return random.Next(min, max);
} // end method RandomNumber

I find it gets especially choked up with 90 records with a maximum array of 16x6 (or 96 records)

+3  A: 

Create Random instance once in RandomlyAssignSeat and pass it as an argument to the RandomNumber function.

To get why you should do in this way - look at the first sample at http://msdn.microsoft.com/en-us/library/system.random.aspx

zerkms
Changing RandomlyAssignSeat from using my own custom RandomNumber method to running 'Random random = new Random();' and then 'row = random.Next(0,seatingArray.GetLength(0));' and 'col = random.Next(0,seatingArray.GetLength(1));' worked far faster. Thank you.
Brett Alton
broken link....
yonan2236
@yonan2236: nope, it works
zerkms
A: 

Or make the Random instance a singleton. The signature of your RandomNumber method would not change.

Dennis
A: 
class rowcol
{
    public int row;
    public int col;
}

void Generate(){
    List<int> rowNumbers = new List<int> { 0, 1, 2, 3 };
    List<int> colNumbers = new List<int> { 0, 1, 2, 3 };
    List<rowcol> allRows = new List<rowcol>();

    for (int i=0;i<rowNumbers.Count;i++)
        for (int j = 0; j < colNumbers.Count; i++)
        {
            allRows.Add(new rowcol { row = i, col = j });
        }

    while (allRows.Count > 0)
    {
        Random r = new Random();
        int next = r.Next() % allRows.Count;
        rowcol curr = allRows[next];
        // ...
        allRows.RemoveAt(next);
    }
}
SaeedAlg