`std :: shuffle`确保在不同向量上具有相同种子的相同顺序吗?

问题描述:

我有两个向量具有相同数量的元素,但它们的类型具有完全不同的大小。我需要对它们进行混洗,以便在混洗之后都具有完全相同的顺序(一个向量中的每个元素与另一个向量中的每个元素相关)。我发现这样做的方式是:`std :: shuffle`确保在不同向量上具有相同种子的相同顺序吗?

// sizeof(a[0]) != sizeof(b[0]) 
// a.size() == b.size() 
{ 
    std::mt19937 g(same_seed); 
    std::shuffle(a.begin(), a.end(), g); 
} 
{ 
    std::mt19937 g(same_seed); 
    std::shuffle(b.begin(), b.end(), g); 
} 

我可以放心,这两个载体会以同样的方式洗牌吗?这个实现是否依赖于?我有std::shuffle规格的保证吗?

+4

在做shuffle之前,你最好将它们压缩成一个对的向量,或者改为创建一个新的向量向量,对其进行混洗,然后用它来索引平行向量。 – Taywee

+0

我的第一次尝试是索引的向量,但是我的数据很大,并且不适合我的记忆中的两个副本,因此我试图按照洗牌顺序从磁盘加载它,当然,速度非常慢。所以我采取了另一种方式,以便能够顺序地(非常快速地)从磁盘读取数据并进行随机播放(没有双重记忆)。 – lvella

+0

该规范并不完全保证这一点,尽管很难想象一个实现不会给这个标准带来洗牌的限制。 'suffle'算法本身看起来相当简单,所以我会编写自己的实现来保证。 https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle – Galik

有关于洗牌说明书中的一个有趣的说法:

备注:为了这个功能的实现是利用随机数的范围,对象g应作为随机性的实现的源。

即便如此,该声明并没有帮助你。 “备注”部分是规范性文字,所以这就是说将提供随机数来确定混洗订单。但是,它并没有声明g是决定排列的唯一因素。

尽管容器的大小值可能并不重要,但没有保证该类型的某些属性不会影响某些内容。例如,如果值类型是可复制的,则实现可能使用使用稍微不同的算法的不同版本的函数。但是,如果它是一个寄存器大小的值,它可能不是。

总之,不,std::shuffle不能保证你在找什么。