我的代码类似于以下内容:
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
的范围。我可以这样做吗?
答案 0 :(得分:3)
param
怎么办?
dist.param( decltype(dist)::param_type(otherMin, otherMax) );
C ++ 11标准(及以下),[rand.req.dist] / 9:
对于
D
的每个构造函数,它们使用相应的参数 分布参数,P
应具有相应的参数 构造函数受相同要求和参数的约束 数量,类型和默认值相同。
答案 1 :(得分:1)
<random>
有一些不错的部分,它包含的生成器至少可以用于许多目的。但是,库及其接口还远未成熟。因此,您需要构建自己的头/库来提供缺少的部分,或者推出像boost或Numeric Recipes中的代码等大枪。
获得均匀整数导数的一种快捷方法是将[0,1]范围内的均匀浮点数与模数和截断相乘。这会在整个范围内传播偏差,这对于许多袖口使用来说已经足够了。
相反,采用模数范围的整数导数的余数的标准方法收集范围开始处的偏差。例如。着名的rand() % modulus
。
一个例子:如果你的模数恰好是衍生物的自然模量的2/3(例如0xAAAAAAAAu为2 ^ 32)那么结果范围的前半部分结果范围的结果范围正好是上半部分的两倍。结果范围。 不建议用于质量代码。
要获取未偏置的整数派生,请使用rejection方法。这是一个使用全尺寸随机整数作为基础的示例。您可以在字大小和生成器上对其进行模板化,将其填入您的“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;
}
标准中包含的发电机都有它们的特点和问题,你必须知道它们的优点和缺点才能做出好的选择。如果您的目标不是随机数生成和计算统计学博士,那么您可能最好使用经过验证且质量可靠且经过验证的代码。