2012-03-04 3 views
0

У меня есть двумерный массив. Я хочу выбрать случайный случай и продолжать делать так, чтобы никогда не выбирать один и тот же слот дважды, пока я, наконец, не выбрал все слоты (так что ничего случайного о последнем выборе курса). Есть ли известный алгоритм для этого? Я использую C#, но, очевидно, это больше об алгоритмах, чем о любой конкретной платформе. Да, «большая книга» находится в моем списке покупок :)Случайный алгоритм построения

+1

Вы ищете [случайный перестановка] (http://stackoverflow.com/search?q=%5Bc%23%5D+random+permutation) набора слотов. – dtb

+1

Возможный дубликат [Случайный алгоритм списка воспроизведения] (http://stackoverflow.com/questions/1816534/random-playlist-algorithm) – dtb

ответ

3

Использование алгоритма Fisher-Yates shuffle, как упоминалось ранее (в O (п))

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; 
    } 
} 
5

Посмотрите на . Он предназначен для выбора случайной перестановки из набора.

1

Если предположить, что массив выглядит так:

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]; 

Это должно работать нормально.

+0

Спасибо, лучше, чем рекурсивное решение выше, но все же мы будем стремиться все больше и больше, поскольку мы доходите до конца набора. Возможно, это всего лишь неотвратимая проблема? –

+0

@MylesMcDonnell Я не думаю, что это можно избежать, и ваше редактирование нарушило функциональность кода. он не должен быть '!', если выбрано значение true, этот индекс недействителен. Я вернул код обратно. –

+0

Извините за беспорядок с ответом;) –

0

Я сделал это для чисел

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; 
} 
+0

Проблема в том, что чем ближе мы добираемся до конца набора, тем больше рекурсии. Для получения последнего элемента может потребоваться много вызовов rnd.Next (0,99). Уч. –

Смежные вопросы