Rcpp 随机洗牌:跨操作系统重现结果

Rcpp random shuffle: reproducing results across operating systems

我正在编写一个使用 Rcpp 包的 R 包。到目前为止,我一直在使用 R 版本 4.0.0 在 macOS Catalina 上工作和测试。使用 R 中的 set.seed,我可以从 Mac 中获得可重现的结果。但是,在 windows 10 机器(也使用 R 4.0.0)上进行测试时,我得到了不同的结果(使用相同的种子)。

在包中,我调用了std::random_shuffle来生成一个排列。我正在使用 the Rcpp website 中的代码来执行此操作。在 C++ 中,它是:

#include<Rcpp.h>

inline int randWrapper(const int n) { return floor(unif_rand()*n); }

// [[Rcpp::export]]
Rcpp::NumericVector randomShuffle(Rcpp::NumericVector a) {

    // clone a into b to leave a alone
    Rcpp::NumericVector b = Rcpp::clone(a);

    std::random_shuffle(b.begin(), b.end(), randWrapper);

    return b;
}

然后它可以从 R 中获取并称为

a <- 1:8
set.seed(42)
randomShuffle(a)

运行 此代码我在 Mac 上得到 8 1 4 2 7 5 3 6,在 Windows 上得到 1 4 3 7 5 8 6 2

起初我认为这可能是由于unif_rand()在两个操作系统上的实现方式不同,但是当我测试

#include<Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector rint() {
    Rcpp::NumericVector a(1);
    a[0] = unif_rand();
    return a;
}

我在两台机器上得到相同的 0.914806 结果。如果我将 unif_rand() 替换为 R::runif(0,1),也会发生同样的事情。我相信 Mac 的结果对于 g++clang++ 是相同的。

任何有关如何解决此问题(如果可能)的建议或见解将不胜感激!

认为 你感到困惑,因为 std::random_shuffle() 实际上是一个标准的 C++ 库函数,它的 RNG 与 R。所以你在 macOS 上得到不同的结果,我猜 Windows 是由于不同的 C++ 库。

然后您获得 runif()unif_rand() 值的结果证实了这种思路。只是 std::random_shuffle().

没有使用这些值

因此,正如@BenBolker 所暗示的那样,对于跨操作系统的 可重现 结果,您可能希望坚持使用 R(和 Rcpp)函数。