用随机播放替换 random_shuffle:如何制作具有给定分布的随机数生成器

Replacing random_shuffle with shuffle: How to make a random number generator with a given distribution

我正在从 C++11 迁移到 C++17,我必须用 shuffle 替换 random_shuffle。 但我面临以下问题:

我需要使用具有特定分布的随机数生成器shuffle向量的内容。 在我的例子中,这是一个 std::piecewise_linear_distribution.

但我不知道如何创建具有给定分布的 UniformRandomBitGenerator。

我试过了(link to code)

    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


    std::mt19937 gen(std::random_device());

    std::vector<double> i{0.0, 0.1, 1.0};
    std::vector<double> w{0.0, 0.9, 1.0};
    std::piecewise_linear_distribution distr(i.begin(), i.end(), w.begin());

    shuffle(v.begin(), v.end(), distr(gen)); // error: 'distr' is not a UniformRandomBitGenerator

但是 shuffle 需要一个生成器作为第三个参数。 我怎样才能使这个生成器具有我想要的分布?

网络上的大多数示例,例如这个,在 cppreference.com 提出一个生成器,它将一个随机数提供给一个分布。

使用 random_shuffle 我必须使用以下 operator():

创建一个函数对象
// random function with desired PDF (and corresponding CDF)
//
struct MyRandomFunc {
  size_t operator() (size_t n)
  {
     double rand_num = rand()/RAND_MAX; // 0 <= rand_num <= 1
     double num = CDF(rand_num); // where 'CDF' = desired cumulative distribution function
     return num * n;    // 'num' is a random number with the desired PDF
  }
};


std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::random_shuffle(v.begin(), v.end(), MyRandomFunc());  // random func with desired pdf

How can I make this generator have the distribution I want?

你不知道。 std::shuffle 需要统一的随机位生成器,因为 it is defined as follows:

Permutes the elements in the range [first, last) such that each possible permutation of those elements has equal probability of appearance.

添加了重点。

你要的是控制某些排列的可能性。这不是 shuffle 的目的,因此您将不得不自己编写改组代码。即使你给它一个 class 实现了 URBG 的接口,它生成的位是 non-uniform 的事实意味着调用该函数的结果将是未定义的。它可能会做你想做的事,也可能会做一些完全不同的事情。