有没有办法使用内置随机生成器的 C++ 标准库来获取序列中的特定随机数,而无需全部保存?
像
srand(cTime);
getRand(1); // 10
getRand(2); // 8995
getRand(3); // 65464456
getRand(1); // 10
getRand(2); // 8995
getRand(1); // 10
getRand(3); // 65464456
你必须保存数字。可能还有其他变体,但它仍然需要保存一个数字列表(例如,根据参数使用不同的种子getRand()
- 但这并不比保存它们真正有益)。
像这样的东西会很好地工作,我会说:
int getRand(int n)
{
static std::map<int, int> mrand;
// Check if it's there.
if ((std::map::iterator it = mrand.find(n)) != mrand.end())
{
return it->second;
}
int r = rand();
mrand[n] = r;
return r;
}
(我没有编译这段代码,只是把它写成“这种事情可能会起作用”)
需要 C++11 随机数引擎来实现一个成员函数discard(unsigned long long z)
(第 26.5.1.4 节),该函数逐步推进随机数序列z
。复杂性保证很弱:“不比z
连续调用的复杂性差e()
”。正如注释 274 所述,该成员显然只是为了尽可能地公开更多高性能实现而存在:
z
此操作在用户代码中很常见,并且通常可以以特定于引擎的方式实现,以便与进行连续调用的等效天真循环相比提供显着的性能改进e()
。
假设您可以通过重新设置生成器、丢弃值并使用下一个生成的值discard
来轻松实现n
按顺序检索第 th 个数字的要求。n-1
我不知道哪些(如果有的话)标准 RNG 引擎可以有效地实现discard
. 可能值得您花时间进行一些调查和分析。
实现getRand()
始终播种,然后返回给定的数字。但是,这会干扰系统中的所有其他随机数,而且速度会很慢,尤其是对于大型索引。假设一个基于 1 的索引:
int getRand(int index)
{
srand(999); // fix the seed
for (int loop=1; loop<index; ++loop)
rand();
return rand();
}
类似于cdmh的帖子,
也可以使用 C++11 的以下内容:
#include<random>
long getrand(int index)
{
std::default_random_engine e;
for(auto i=1;i<index;i++)
e();
return e();
}