2012-03-04 71 views
0

我有二维数组。我想随机选择一个插槽,并继续这样做,直到我最终选择了所有插槽(因此对于最后一个选择当然没有随机选择),从不选择相同的插槽两次。有这样一个众所周知的算法吗?我使用C#,但显然这比任何特定的平台更关心算法。是的,'大书'在我的购买清单:)随机绘图算法

+1

你正在寻找一个[随机提到置换](http://stackoverflow.com/search?q=%5Bc%23%5D+random+permutation)。 – dtb 2012-03-04 19:04:04

+1

[Random playlist algorithm]可能的重复(http://stackoverflow.com/questions/1816534/random-playlist-algorithm) – dtb 2012-03-04 19:04:57

回答

3

使用Fisher-Yates shuffle算法之前(在O(n)的时间)

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

谢谢,比上面的递归解决方案好,但我们仍然会越来越多地循环,因为我们走向集合的尽头。也许这只是一个不可避免的问题? – 2012-03-04 19:32:14

+0

@MylesMcDonnell我不认为这是可以避免的,你的编辑打破了代码的功能。它不应该是'!',如果选择设置为true,则该索引无效。我已将代码回滚。 – 2012-03-04 19:39:59

+0

对不起你的答案;) – 2012-03-04 19:40:56

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)以获取最后一个项目。哎哟。 – 2012-03-04 19:28:54