Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

28.12.2013, 19:37

Mersenne-Twister Funktionsweise

Hallo,

unter anderem bei den Contests habe ich den folgenden Mersenne-Twister gefunden und ein paar Fragen zu.
Die erste wäre die, was in der Funktion Seed passiert. Ich habe gelesen, dass man die ersten 624 Startwerte vorgibt, aber hier werden die ja nach einem ganz bestimmten Pattern erzeugt. Woher kommt das? Wie heißt diese Methode und wie kommt man auf die genauen Faktoren?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Mersenne Twister-Zufallsgenerator
class MTRand
{
public:
    MTRand(uint seed = 0) { this->seed(seed); }

    void seed(uint seed)
    {
        next = 0;
        const unsigned long long int factor = 69069;
        mt[0] = seed;
        for(uint i = 1; i != 624; ++i) mt[i] = static_cast<uint>(factor * mt[i - 1] + 1);
    }

    float float_0_to_1()
    {
        const uint x = (*this)() & 0xFFFFFF;
        return static_cast<float>(x) / 0xFFFFFF;
    }

    uint operator ()()
    {
        if(next == 624) { generateNumbers(); next = 0; }
        uint x = mt[next++];
        x ^= x >> 11;
        x ^= (x << 7) & 0x9D2C5680;
        x ^= (x << 15) & 0xEFC60000;
        x ^= x >> 18;
        return x;
    }

private:
    void generateNumbers()
    {
        const uint xorTab[] = { 0, 0x9908B0DF };
        for(uint i = 0; i != 227; ++i) { const uint x = (mt[i] & 0x80000000) | (mt[i + 1] & 0x7FFFFFFF); mt[i] = mt[i + 397] ^ (x >> 1) ^ xorTab[x & 1]; }
        for(uint i = 227; i != 624; ++i) { const uint x = (mt[i] & 0x80000000) | (mt[i + 1] & 0x7FFFFFFF); mt[i] = mt[i - 227] ^ (x >> 1) ^ xorTab[x & 1]; }
        const uint x = (mt[623] & 0x80000000) | (mt[0] & 0x7FFFFFFF);
        mt[623] = mt[396] ^ (x >> 1) ^ xorTab[x & 1];
    }

    uint mt[624];
    uint next;
};

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

29.12.2013, 01:17

Das einzige was ich sicher weiß, ist das der MT bei falsche Initialisierung dieses Arrays (z.B. alles 0 wenn ich mich richtig erinnere) keinerlei Zufall produziert. Und wenn die Initialisierung relativ "wenig" zufällig ist, soll es eine Weile dauern bis der MT trotzdem qualitativ gute Zufallszahlen generiert.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

29.12.2013, 09:26

Sieht mir auf den ersten Blick nach einem Linear Congruential Generator aus (der static_cast entspricht einem Modulo)...

Werbeanzeige