【发布时间】:2015-12-14 13:20:56
【问题描述】:
我正在浏览 C++ Primer,我刚刚完成了讨论<random> 实用程序的章节。问我几个问题:
练习 17.28:编写一个函数,生成并返回一个统一的 每次调用时分发随机无符号整数。
练习 17.29:允许用户提供种子作为可选参数 你在上一个练习中编写的函数。
练习 17.30:这次再次修改你的函数,以最小化和 函数应返回的数字的最大值。
这些问题希望我使用讨论过的random_default_engine 和uniform_int_distribution 类。第一个问题很简单:
#include <random>
unsigned randomUns(){
static default_random_engine e;
static uniform_int_distribution<unsigned> u;
return u(e);
}
使用创建对象static 的建议,这样它们就不会在调用后被销毁,因此每次调用函数都会生成一个新数字,而不是每次都从序列的开头开始。困难出在最后两个问题上,我原来的解决办法是:
unsigned randomUns(unsigned minV, unsigned maxV, default_random_engine::result_type seed = 0){
static default_random_engine e(seed);
static uniform_int_distribution<unsigned> u(minV, maxV);
return u(e);
}
除了那是在我意识到静态变量只被初始化一次之前。所以这个函数将使用来自对randomUns 的调用的参数初始化u,然后再也不会。我只能在一个范围内使用此功能。例如
cout << randomUns(2,3) << " " << randomUns(5,6);
尽管第二个范围不同,但可能会输出 2 3。
seed 也存在类似问题。我将如何处理这个?对于引擎/种子,我也许可以像这样重写函数:
static default_random_engine::result prev = 0;
static default_random_engine e(seed);
if(prev != seed){
e.seed(seed)
prev = seed;
}
但这当然不是一个真正的随机函数。
randomUns(1,2,50);
randomUns(1,2,60);
randomUns(1,2,50);
据我所知,第三次调用将产生与第一次相同的输出,因为引擎已重置回相同的状态。对于更改分布的范围,我完全不确定。
变量不能在每次调用后销毁,否则函数将始终输出相同的序列 - 所以它们必须是 static 或存在于函数范围之外。另一方面,我需要能够控制范围/种子,因此需要在函数内修改变量。
这可以通过random_default_engine 和uniform_int_distribution 提供的实用程序实现吗?
【问题讨论】:
-
或者,如果希望为不同的范围生成不同的分布:See。当然可以更进一步并使用
tuple来确保相同的生成器用于相同的发行版,我不完全确定这是否有必要。