简体   繁体   English

随机引擎状态和多个确定性独立随机序列

[英]Random engine state and multiple deterministic independent random sequences

The C++ TR1 random number generation scheme has improved the old C runtime library in terms of keeping a separate state for random engines in different threads, or for independent random sequences. C ++ TR1随机数生成方案在保持不同线程中的随机引擎或独立随机序列的独立状态方面,改进了旧的C运行时库。 The old library has a global state machine, and this is usually bad. 旧的库具有全局状态机,这通常是不好的。

However, when implementing an algorithm that requires deterministic random sequences, I find it annoying to have to pass the engine down to any method that should be drawing numbers from such a sequence. 但是,当实现需要确定性随机序列的算法时,我发现必须将引擎传递给应该从此类序列中提取数字的任何方法,这很烦人。 From a design perspective, the code that initializes the random seed doesn't need to know which methods down the stack are using random numbers. 从设计的角度来看,初始化随机种子的代码不需要知道堆栈中哪些方法正在使用随机数。 Yet those inner methods cannot initialize their own random engines, because: 但是,这些内部方法无法初始化自己的随机引擎,因为:

  1. they lack the knowledge to create a unique reproducible seed 他们缺乏创造独特的可繁殖种子的知识
  2. memory requirements prevent keeping a separate state for the many downstream clients 内存要求阻止为许多下游客户端保持单独的状态

To clarify, the downstream methods do not need to draw numbers from the same sequence as the main method, but they do need to be independent and reproducible in different runs. 为了明确起见,下游方法不需要从与主方法相同的序列中提取数字,但是它们确实需要独立且可在不同运行中重现。

Any idea on how to solve this conundrum elegantly? 任何想法如何优雅地解决这个难题?

EDIT 编辑

Some code to clarify the situation 一些代码来澄清这种情况

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...
};

Not an easy question without knowing some detail about your architecture. 如果不了解有关您的体系结构的一些细节,这不是一个简单的问题。 So this is just a try: 所以这只是一个尝试:
How about passing down references to an interface that knows how to provide random numbers. 如何将引用传递给知道如何提供随机数的接口。 This interface may just have one function that returns an amount of random numbers if asked. 如果需要,此接口可能只有一个函数可以返回一定数量的随机数。 In this way you can hide the implementation details from the downstream functions (methods) and passing constant references around is nearly for free. 这样,您可以从下游函数(方法)中隐藏实现细节,并且传递常量引用几乎是免费的。 You can even decide at top level where those random numbers come from (file, random number generator, your room temperature, ...). 您甚至可以在最高级别决定这些随机数的来源(文件,随机数生成器,您的室温等)。

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  
    ...
}  

something like this. 这样的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM