【问题标题】:Random access random permutations [closed]随机访问随机排列[关闭]
【发布时间】:2012-12-29 01:39:02
【问题描述】:

我想生成一个非常大的伪随机排列 p : [0,n-1] -> [0,n-1],然后计算 m 个特定值 p[i],其中 m

请注意,为了在并行情况下有所帮助,计算不相交的 i 值集的不同进程不应意外产生 p[i] == p[j] for i != j。

【问题讨论】:

标签: random


【解决方案1】:

编辑:我认为 Geoff 会写更多 clever algorithm based on block ciphers

有两种常见的算法来生成排列。 Knuth 的 shuffle 本质上是顺序的,因此不是并行性的好选择。另一种是随机选择,只要遇到重复就重试。随机选择在以任何顺序应用时显然是等效的,因此我提出以下简单算法:

  1. Needed 中的每个i[0,n-1] 中随机抽样候选p[i](并行)。
  2. Needed 中删除所有未冲突的条目,以及(可选)从冲突中做出的一些确定性选择(例如,如果i < {j | p[j] = p[i]},则保留p[i])。
  3. 使用新的(较小的)集合 Needed 从第 1 步重复。

由于我们在这个过程中没有丢失熵,结果本质上相当于以某种不同的顺序进行顺序随机抽样,从没有碰撞的位置i开始(我们只是事先不知道那个顺序)。请注意,例如,如果我们在比较中使用计算值,我们就会引入偏差。

【讨论】:

  • 这个解决方案确实回答了上述问题,但没有解决不同并行进程需要协调选择哪个排列的动机问题。我将编辑问题。
【解决方案2】:

一个非常低强度的例子:

  1. 在 [0,n-1] 中生成 2k = O(1) 个随机整数 a_i,b_i,其中 a_i 与 n 互质。
  2. 选择一个弱排列 wp:[0,n-1] -> [0,n-1],例如 w(i) = i,除了高位以外的所有位都翻转。
  3. p[i] = b_0 + a_0 * wp(b_1 + a_1 * wp(... i ...))

【讨论】:

猜你喜欢
  • 2013-01-01
  • 2019-07-18
  • 2021-07-28
  • 2016-05-29
  • 2012-06-24
  • 1970-01-01
  • 2017-07-04
  • 1970-01-01
相关资源
最近更新 更多