我想生成一个非常大的伪随机排列 p:[0,n-1] -> [0,n-1],然后计算 m 个特定值 p[i],其中 m << n。是否有可能在 O(m) 时间内做到这一点?动机是大型并行计算,其中每个处理器只需要查看一小部分排列,但排列必须在处理器之间保持一致。
请注意,为了在并行情况下有所帮助,计算不相交的 i 值集的不同进程不应意外地为 i != j 生成 p[i] == p[j]。
我想生成一个非常大的伪随机排列 p:[0,n-1] -> [0,n-1],然后计算 m 个特定值 p[i],其中 m << n。是否有可能在 O(m) 时间内做到这一点?动机是大型并行计算,其中每个处理器只需要查看一小部分排列,但排列必须在处理器之间保持一致。
请注意,为了在并行情况下有所帮助,计算不相交的 i 值集的不同进程不应意外地为 i != j 生成 p[i] == p[j]。
编辑:有一个基于分组密码的更聪明的算法,我认为 Geoff 会写出来。
有两种常见的算法来生成排列。Knuth 的 shuffle 本质上是顺序的,因此不是并行性的好选择。另一种是随机选择并在遇到重复时重试。随机选择在以任何顺序应用时显然是等效的,因此我提出以下简单算法:
p[i]
in (并行)随机抽样候选。[0,n-1]
i
Needed
Needed
,以及(可选地)从冲突中删除一些确定性选择(例如,保留p[i]
if i < {j | p[j] = p[i]}
)。Needed
。由于我们在这个过程中没有丢失熵,结果本质上相当于以某种不同的顺序进行顺序随机采样,从i
没有碰撞的位置开始(我们只是事先不知道那个顺序)。请注意,如果我们在比较中使用计算值,例如,我们会引入偏差。
一个非常低强度版本的示例: