C++ 数字库:std::uniform_int_distribution<>,更改调用之间的分布边界

C++ numerics lib: std::uniform_int_distribution<>, change bounds of distribution between calls

本文关键字:调用 之间 边界 分布 lt std 数字 uniform int C++ distribution      更新时间:2023-10-16

>我有类似于以下内容的代码:

    vector<int> vec;
    // stuff vector here
    random_device rd;
    minstd_rand generator(rd());
    uniform_int_distribution<unsigned> dist(0 , vec.size() - 1);
    while (vec.size() > 0)
    {
       auto it = vec.begin() + dist(generator);
       // use *it for something
       swap(*it, *(vec.end() - 1));
       vec.pop_back();
   }

我知道我可以在循环内构建/破坏本地发行版。但我宁愿只是调整循环内dist的边界。我可以这样做吗?

param呢?

dist.param( decltype(dist)::param_type(otherMin, otherMax) );

C++11 标准(及以下标准),[rand.req.dist]/9:

对于D的每个构造函数,取参数对应于 分布的参数, P应有相应的 受相同要求并接受参数的构造函数 在数量、类型和默认值上相同。

<random>有一些不错的部分,它包含的生成器至少可以用于许多目的。但是,该库及其接口还远未成熟。因此,您需要构建自己的标头/库来提供缺少的部分,或者推出诸如 boost 或数字配方中的代码等大枪。

获得一致整数导数的一种快速简便的方法是将 [0,1) 范围内的一致浮点数乘以模数并截断。这会将偏见传播到整个范围内,对于许多即兴使用来说已经足够好了。

相比之下,取整数导数模范围余数的标准方法收集范围开始时的偏差。 例如著名的rand() % modulus.

举个例子:如果你的模量恰好是导数自然模量的 2/3(例如 0xAAAAAAAAu 表示 2^32),那么前半部分的所有结果恰好是结果范围上半部分结果的两倍。建议用于高质量代码。

若要获取无偏整数导数,请使用拒绝方法。下面是一个使用全尺寸随机整数作为基础的示例。您可以在字大小和生成器上对其进行模板化,将其填充到"fix-the-std"标头中,并始终完成:

uint64_t random_uint64 ();
uint64_t random_uint64 (uint64_t modulus)
{
   if (modulus)
   {
      for ( ; ; )
      {
         uint64_t raw_bits = random_uint64();
         uint64_t result = raw_bits % modulus;
         uint64_t check = uint64_t(raw_bits - result + modulus);
         if (check >= raw_bits || check == 0)
         {
            return result;
         }
      }
   }
   return 0;
}

std::uniform_int_distribution<>内部做了一些非常相似的事情......但是,通常的数百行绒毛很好地保护了逻辑免受工业攻击,并且尴尬的界面确保人们不能仅仅因为喜欢而简单地使用该功能。

为了完整起见,这里有一个简单快速的生成器,具有出色的、经过验证的质量(Sebastiano Vigna 的 xorshift64*),当不需要像 xorshift1024* 这样的大枪的极长周期时,它是一个不错的全能生成器:

uint64_t random_seed64 = 42;
uint64_t random_uint64 ()
{
   uint64_t x = random_seed64;
   x ^= x >> 12;  x ^= x << 25;  x ^= x >> 27;
   random_seed64 = x;
   return x * 2685821657736338717ull;
}

标准中包含的发电机都有其特点和问题,您必须了解它们的优点和缺点才能做出正确的选择。如果您的目标不是随机数生成和计算统计学的博士学位,那么最好使用经过验证的质量的久经考验且值得信赖的代码。