1

C++ TR1 乱数生成スキームは、異なるスレッドのランダム エンジンまたは独立したランダム シーケンスに対して個別の状態を維持するという点で、古い C ランタイム ライブラリを改善しました。古いライブラリにはグローバル ステート マシンがあり、これは通常悪いことです。

ただし、決定論的なランダム シーケンスを必要とするアルゴリズムを実装する場合、そのようなシーケンスから数値を描画するメソッドにエンジンを渡す必要があるのは面倒です。設計の観点からは、ランダム シードを初期化するコードは、スタックのどのメソッドが乱数を使用しているかを知る必要はありません。しかし、これらの内部メソッドは独自のランダム エンジンを初期化できません。

  1. 独自の再現可能な種子を作成するための知識が不足している
  2. メモリ要件により、多数のダウンストリーム クライアントの個別の状態を維持できない

明確にするために、ダウンストリーム メソッドは、メイン メソッドと同じシーケンスから数字を引き出す必要はありませんが、独立していて、異なる実行で再現可能である必要があります。

この難問をエレガントに解決する方法について何か考えはありますか?

編集

状況を明確にするためのコード

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

1 に答える 1

0

アーキテクチャの詳細を知らなければ、簡単な質問ではありません。したがって、これは単なる試みです
。乱数を提供する方法を知っているインターフェイスへの参照を渡すことはどうですか。このインターフェイスには、要求された場合に大量の乱数を返す関数が 1 つだけある場合があります。このようにして、下流の関数 (メソッド) から実装の詳細を隠すことができ、定数参照を渡すことはほぼ無料です。これらの乱数がどこから来るかをトップレベルで決定することもできます (ファイル、乱数ジェネレーター、室温など)。

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

このようなもの。

于 2012-04-17T18:12:54.680 に答える