C++ 数字库:std::uniform_int_distribution<>,更改调用之间的分布边界
C++ numerics lib: std::uniform_int_distribution<>, change bounds of distribution between calls
>我有类似于以下内容的代码:
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;
}
标准中包含的发电机都有其特点和问题,您必须了解它们的优点和缺点才能做出正确的选择。如果您的目标不是随机数生成和计算统计学的博士学位,那么最好使用经过验证的质量的久经考验且值得信赖的代码。
- 如何防止clang格式在流运算符调用之间添加换行符<<
- DirectX 9 在重置调用之间保留状态
- Vulkan是否需要在多个具有透明度的平局调用之间进行同步
- 静态模板类成员函数的这两个调用之间有什么区别?
- 在cython调用之间保持数据帧的状态
- C++:cout 和函数调用之间的计算顺序
- unix中选择和轮询系统调用之间的功能差异
- 如何在函数调用之间存储 deque 值
- 如何在c/c++中使函数调用之间的变量值持久化
- 连接线程(阻塞调用线程直到线程终止)和普通函数调用之间的区别是什么
- GDI - 是否可以在WM_PAINT调用之间将位图保存在内存中
- C++ 数字库:std::uniform_int_distribution<>,更改调用之间的分布边界
- 来自托管库的调用之间本机库中静态变量的值
- 按引用调用和按指针调用之间的差异
- 链式静态函数调用之间的参数求值顺序
- 对伪随机数生成器的相同调用之间的不同行为
- 在来自C++应用程序的成功调用之间保留dll中的状态
- 如何在c++ dll中实例化一个类,使它在函数调用之间保持内存
- 我可以在函数调用之间在c++ DLL中维护内存吗?
- 带和不带()的构造函数调用之间的区别