【问题标题】:best algorithm to shuffle an array洗牌数组的最佳算法
【发布时间】:2014-10-05 03:36:28
【问题描述】:

我有一个数组 s = {'ACA','BBC','CKA',...};

我想随机播放 s。所以我创建列表 A={1,2,3,4..} 和列表 B={1,2,3,4,...}

然后,我将这两个列表打乱。 random.shuffle(A) random.shuffle(B)

最后,我将 s[A[0]] 与 s[B[0]] 交换,将 s[A[1]] 与 s[B[1]] 交换.....

这个算法会产生 s 的随机排列吗?是否足够随机?假设 random.shuffle 产生足够随机的 A 和 B 排列。

【问题讨论】:

  • 这是什么语言?为什么你不能只打乱你的原始数组,而不是创建另外两个数组,打乱它们,然后用它来打乱第一个?
  • s,A 和 B 的关系是什么。您的问题似乎说明了几个问题的不足部分。
  • s 是一个非常大的字符串序列。每个字符串大约 8000 字节。 A 和 B 是序列 {1,2,3,....length(s)} 的排列
  • @NickT 我正在使用 C 语言。 s 的每个元素实际上都是很长的字符串(大约 8000 字节)。 s 大约 500GB,我想对 s 进行就地排列,因为我想把所有东西都保存在内存中。

标签: algorithm random permutation shuffle


【解决方案1】:

要将 Fisher--Yates (Knuth) 洗牌与索引数组一起使用,请初始化单个索引数组 A 类似

for (int i = 0; i < n; i++) A[i] = /* random integer in 0..i */;

然后像这样进行交换

for (int i = 0; i < n; i++) swap(&s[A[i]], &s[i]);

您的算法不会生成统一的随机排列。当 n = 2 时,A 和 B 的可能性为

A = {0, 1}; B = {0, 1};
A = {0, 1}; B = {1, 0};
A = {1, 0}; B = {0, 1};
A = {1, 0}; B = {1, 0};

这些都不会对起始排列产生任何影响;要么两个元素相互交换,要么重复两次相同的非平凡交换,取消其效果。

【讨论】:

  • 我认为您的代码运行良好。但是我很好奇我的算法是否会生成均匀的随机排列。我希望有人可以给出数学证明。
  • @readRead 不起作用;当 n = 2 时,决算中不会有任何变动。
【解决方案2】:

Knut's shuffle 是一种简单而有效的方法来洗牌一个数组。您不需要额外的索引数组。使用它们有什么特殊原因吗?

【讨论】:

  • 克努特的洗牌是否比我的算法产生更多的随机排列?我使用索引数组是因为我想以完全相同的方式置换另一个数组 x。 s 和 x 是一一对应的。
  • 它只是产生均匀分布(所有排列的概率都相等)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
相关资源
最近更新 更多