0

そこで、Mersenne Twister を使用するカスタムのランダマイザー クラスを作成しました (使用するコードは、このサイトから変更されています)。さまざまなシードのテストを開始するまで、すべてがうまく機能しているように見えました (通常、シードとして 42 を使用して、プログラムを実行するたびに結果が同じであることを確認し、コードの変更が物事にどのように影響するかを確認できるようにします)。

どのシードを選択しても、コードは毎回まったく同じ一連の数値を生成することがわかりました。明らかに私は何か間違ったことをしているのですが、何が悪いのかわかりません。ここに私のシード関数があります:

void Randomizer::Seed(unsigned long int Seed)
{
    int ii;
    x[0] = Seed & 0xffffffffUL;
    for (ii = 0; ii < N; ii++)
    {
        x[ii] = (1812433253UL * (x[ii - 1] ^ (x[ii - 1] >> 30)) + ii);
        x[ii] &= 0xffffffffUL;
    }
}

そして、これは私の Rand() 関数です

unsigned long int Randomizer::Rand()
{
    unsigned long int Result;
    unsigned long int a;
    int ii;

    // Refill x if exhausted
    if (Next == N)
    {
        Next = 0;

        for (ii = 0; ii < N - 1; ii++)
        {
            Result = (x[ii] & U) | x[ii + 1] & L;
            a = (Result & 0x1UL) ? A : 0x0UL;
            x[ii] = x[( ii + M) % N] ^ (Result >> 1) ^ a;
        }

        Result = (x[N - 1] & U) | x[0] & L;
        a = (Result & 0x1UL) ? A : 0x0UL;
        x[N - 1] = x[M - 1] ^ (Result >> 1) ^ a;
    }
    Result = x[Next++];

    //Improves distribution
    Result ^= (Result >> 11);
    Result ^= (Result << 7) & 0x9d2c5680UL;
    Result ^= (Result << 15) & 0xefc60000UL;
    Result ^= (Result >> 18);

    return Result;
}

さまざまな値は次のとおりです。

#define A 0x9908b0dfUL
#define U 0x80000000UL
#define L 0x7fffffffUL

int Randomizer::N = 624;
int Randomizer::M = 397;
int Randomizer::Next = 0;
unsigned long Randomizer::x[624];

異なるシードが異なる数のシーケンスにならない理由を理解するのを手伝ってくれる人はいますか?

4

1 に答える 1

5

Seed()関数はに割り当ててx[0]からループを開始します。これは未定義の値ii=0で上書きされます(参照します)。ループを1から開始すると、おそらくすべて設定されます。x[0]x[-1]

独自のランダマイザーを作成するのは危険です。なんで?正しく理解するのは難しく(上記を参照)、正しく実行したかどうかを知るのは困難です。間違っていると、正しく分散された乱数に依存するものは正しく機能しません。うまくいけば、それはテールが重要な暗号化や統計モデリングではありません.... std :: randomの使用を検討してください。または、C ++ 11をまだ使用していない場合は、boost::randomを使用してください。

于 2012-06-11T19:37:25.020 に答える