shuffle算法只有随机0,1

时间:2012-03-27 00:12:57

标签: random shuffle

我刚刚在互联网上阅读了一些采访问题,让我对解决方案感到好奇。

问题是这样的。

给定一个数字列表和一个rand(0,1)函数,它返回一个0到1之间的随机整数。提供一个算法,根据rand()函数的输出随机排序给定列表,应该为列表中的每个号码调用一次。

似乎要求生成一个只有0和1的随机数用于随机播放。 我提出了这个解决方案。

int random(int array_index, int array size)
{
    return (array_index * 41 * (array_size + rand(0,1)) % array_size;
}

但我觉得这不够好,因为它取决于array_index。

任何人都有更好的答案吗?

4 个答案:

答案 0 :(得分:2)

你应该使用Fisher-Yates Shuffle algorithm,它在O(n)时间内执行真正随机的随机播放(即:“为列表中的每个数字调用一次”)。

To shuffle an array a of n elements (indices 0..n-1):
    for i from n − 1 downto 1 do
        j ← random integer with 0 ≤ j ≤ i
        exchange a[j] and a[i]

答案 1 :(得分:1)

假设我有一个10元素列表。然后有10个! = 3628800不同的订购方式。

如果我只能调用rand(0,1)10次,我只能生成2 ^ 10 = 1024个不同的二进制序列。

没有办法唯一地识别10个中的一个!数字在0到1024之间的排序。 那就是我们不能进行无偏见的洗牌。 (除了超过3个元素的列表)。因此,我们现在可以专注于选择易于实施的偏差改组。

例如:

result = new List<int>();

foreach( int i in list )
{
  int r = rand(0,1);

  if( r == 0 )
    result.Prepend(i);
  else
    result.Append(i);
}
return result;

这非常偏向于将列表中的元素放在远离列表中间的列表中。

答案 2 :(得分:0)

我会用Ruby编写我的,因为我更多地使用它。

def random_sort(numbers)
  sorted = Array.new
  index = 0
  numbers.each do |number|
    while rand(1)
      index += 1
    end

    index = index % numbers.length
    while numbers[index] != nil
      if index > numbers.length - 1
        index = 0
        continue
      end
      index += 1
    end

    sorted[index] = number
  end

  return sorted
end

答案 3 :(得分:0)

让数组大小为N

要随机播放数字列表,我们使用以下策略。

For the first element we find a position out of the all available N choices.
Then, the second element has N-1 choices and so on. 
We generate the N! possible outcomes which ensures all are equi-probable.

现在要从(比如N)选择中随机生成位置,我们执行以下操作; (我们对N-1,N-2 ......也这样做)

Use Divide - And - Conquer.
First modify N to (Least Power of 2 >= N) Example: For N=5, modified_N=8 
Run rand(0,1) - 
If 0 - we the position is from 1 to modified_N/2
Else - the position is in modified_N/2+1 to modified_N

We do this recursively till we find the final position. 
If the final position is between N+1 and modified_N we run this procedure again.

这样我们可以使用rand(0,1)

随机找到一个位置