1

I have two dimensional array. I want to pick a slot at random, and continue to do so never picking the same slot twice until I have finally picked all slots (so nothing random about the last pick of course). Is there a well known algorithm for doing this? I'm using C#, but obviously this is more about algorithms than any particular platform. Yes, 'the big book' is on my purchase list :)

2
  • 1
    You are looking for a random permutation of the set of slots. Commented Mar 4, 2012 at 19:04
  • 1
    possible duplicate of Random playlist algorithm Commented Mar 4, 2012 at 19:04

4 Answers 4

5

Take a look at the Fisher-Yates shuffle. It's designed to pick a random permutation from a set.

Sign up to request clarification or add additional context in comments.

Comments

3

Using the Fisher-Yates shuffle algorithm as mentioned before (in O(n) time)

int X = 3;  int Y = 4;
int[] array = new int[X * Y];

for (int i = 0; i < array.Length; i++) array[i] = i;
FisherYatesShuffle(array);

var randomSlots = array.Select((i,j) => new {x=array[j]%X , y=array[j]/X })
                       .ToArray();

public static void FisherYatesShuffle<T>(T[] array)
{
    Random r = new Random();
    for (int i = array.Length - 1; i > 0; i--)
    {
        int j = r.Next(0, i + 1);
        T temp = array[j];
        array[j] = array[i];
        array[i] = temp;
    }
}

Comments

1

Assuming your array is like this:

Random rand = new Random();

object[,] array = new object[width,height];
bool[,] chosen = new bool[width,height];

int i, j;
do
{
    i = rand.Next(width);
    j = rand.Next(height);
} while (chosen[i,j]);

chosen[i,j] = true;
object current = array[i,j];

This should work fine.

4 Comments

Thanks, better than the recursive solution above, but still we will tend to loop more and more as we get toward the end of the set. Perhaps this is just an unavoidable issue?
@MylesMcDonnell I don't think it's avoidable, and your edit broke the functionality of the code. it is not supposed to be a !, if chosen is set to true, that index is invalid. I have rolled the code back.
Sorry for messing with your answer ;)
@RichardJ.RossIII Apologies..@Fuex I think we both made the same mistake
0

I did this for numbers

list<int> PastList=new PastList<int>();
private void Choоse()
{
   int i = Recurs();
   PastList.Add(i);
}

private int Recurs()
{
   int i;

   i = rnd.Next(0, 99);
   if (PastList.Contains(i))
   {
       i = Recurs();
   }

   return i;
}

1 Comment

The problem with this is the closer we get to the end of the set more recursion occurs. It could take a lot of calls to rnd.Next(0,99) to get the last item. Ouch.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.