Multiply-with-carryDer Multiply-with-Carry (kurz: MWC) und dessen modifizierte Variante Complimentary-Multiply-with-Carry (kurz: CMWC) sind Pseudozufallszahlengeneratoren, die 2003 von George Marsaglia vorgestellt wurden. Eigenschaften
AlgorithmusDer Algorithmus für den MWC kann durch zwei Rekurrenzgleichungen beschrieben werden: Das Ergebnis der Multiplikation ist aufgeteilt in Hier steht für die i-te generierte Zahl, a für einen konstanten Faktor und b für die Zahlenbasis. Die Konstanten a und b sollten so gewählt werden, dass eine Primzahl ist. Dann gibt der Generator für alle nicht-trivialen Startwerte und eine Sequenz mit der Periodenlänge aus. BeispielSei , und als Startwerte , : Sequenzlänge:
Der MWC gibt in umgekehrter Reihenfolge die Dezimalbruchentwicklung von aus. Complimentary Multiply-with-carryFür die Erzielung einer maximalen Periodenlänge wird beispielsweise bei Verwendung von 32-Bit-Integern für gewählt. Dies ermöglicht die optimale Nutzung des Wertebereichs und eine gleichzeitig schnelle Berechnung. Bei MWC-Generatoren verkürzt sich hier aber die Periode um die Hälfte und es wird schwieriger, passende Primzahlen zu finden. Diese Probleme können durch eine kleine Modifikation des ursprünglichen Algorithmus behoben werden, indem man als Rekurrenzgleichung verwendet. InitialisierungDie Initialisierung des Zustandsregisters sollte mit möglichst zufälligen und gleich verteilten Bits erfolgen, sprich etwa so viele 1- wie 0-Bits. Anderenfalls braucht der Generator eine „Warmlauf-Phase“, d. h. es muss eine gewisse Menge an Zufallszahlen generiert werden bis der Generator gleich verteilte Zufallszahlen liefert. ImplementierungMWC#include <stdint.h>
static uint32_t Q[1038];
static uint32_t c = 123;
uint32_t MWC1038() {
static uint32_t i = 1037;
uint64_t t;
t = (611376378ULL * Q[i]) + c;
c = t >> 32;
if (--i != 0)
return (Q[i] = t);
i = 1037;
return (Q[0] = t);
}
CMWC#include <stdint.h>
static uint32_t Q[4096];
static uint32_t c = 123; /* 0 <= c < 18782 */
uint32_t CMWC() {
static uint32_t i = 4095;
uint64_t t;
uint32_t x;
i = (i + 1) & 4095;
t = (18782ULL * Q[i]) + c;
c = t >> 32;
x = t + c;
if (x < c) { ++x; ++c; }
Q[i] = 0xfffffffe - x;
return Q[i];
}
Siehe auchLiteratur
Weblinks
|
Portal di Ensiklopedia Dunia