C++ TR1 随机数生成方案在为不同线程中的随机引擎或独立随机序列保持独立状态方面改进了旧的 C 运行时库。旧库有一个全局状态机,这通常很糟糕。
但是,当实现需要确定性随机序列的算法时,我发现必须将引擎传递给任何应该从此类序列中提取数字的方法很烦人。从设计的角度来看,初始化随机种子的代码不需要知道堆栈中哪些方法正在使用随机数。然而,这些内部方法无法初始化它们自己的随机引擎,因为:
- 他们缺乏创造独特的可繁殖种子的知识
- 内存要求阻止为许多下游客户端保持单独的状态
澄清一下,下游方法不需要从与主要方法相同的序列中提取数字,但它们确实需要在不同的运行中独立且可重现。
关于如何优雅地解决这个难题有什么想法吗?
编辑
一些代码来澄清情况
typedef std::mt19937 RandEng;
class PossibleRandomConsumer;
class RandomProvider {
public:
void foo() {
std::uniform_int<> uni;
uni(eng, 17); // using the random engine myself
std::for_each(children.begin(), children.end(), [](PossibleRandomConsumer& child) {
// may or may not need a random number. if it does, it has to be different than from other children, and from other providers
child.DoSomething(eng);
});
}
private:
RandEng eng; // unique seed per RandomProvider
std::array<PossibleRandomConsumer,10000> children; // lots of these...
};
如果不了解您的架构的一些细节,这不是一个简单的问题。所以这只是一个尝试:
如何将引用传递给知道如何提供随机数的接口(interface)。这个接口(interface)可能只有一个函数,如果被要求返回一定数量的随机数。通过这种方式,您可以对下游函数(方法)隐藏实现细节,并且几乎可以免费传递常量引用。您甚至可以在顶层决定这些随机数的来源(文件、随机数生成器、您的室温……)。
class RandomNumberProvider {
public:
typedef std::vector<int> RandomArray;
virtual RandomArray Generate(unsigned numNumbers) = 0;
};
void Consumer(const RandomNumberProvider& rndProvider) {
RandomNumberProvider::RandomArray rndNumber;
rndNumber = rndProvider(10); // get a sequence of 10 random numbers
...
}
是这样的。
我是一名优秀的程序员,十分优秀!