Bradward B. schrieb:
Bei sehr kleinem p (bspw <0.01) wäre es auch überlegenswert, nicht für
jedes bit den Zufallsgenerator anzuwerfen, sondern lediglich den Abstand
zur nächsten Zufalls-'1' "auszuwürfeln". Diese Abstände dürften auch
eine Zufallsreihe mit dem Erwartungswert 1/p sein.
Das ist meiner Meinung nach keine gute Methode, um "guten" Zufall zu erzeugen. Der Grund ist: Die Ziel-Bitfolge soll normalverteilt sein. Die Abstände zwischen den wenigen gesetzten Bits müssten dann Poisson-verteilt sein. Diese Abstands-Zufallszahl ist imho noch schlechter effizient aus einem Zufalls-Bitstrom herzustellen. (Bitte nagelt mich hier nicht fest. Mein Verständnis von Zufall ist zwar noch einigermaßen ok, aber die genaue Mathematik habe ich nicht mehr im Kopf.)
Ganz grundsätzlich geht es bei dieser Frage imho hauptsächlich um die Effizienz: Wie viele Original-Zufallsbits muss man pro Ergebnisbit investieren?
Hippelhaxe hat imho schon in der ersten Antwort einen guten und sicheren Algorithmus beschrieben:
Hippelhaxe schrieb im Beitrag #7682517:
Du erzeugst den Zielwert bitweise.
Du nimmst für jeden Zielwert einen Block von 32 gleich-
verteilten Zufallszahlen und vergleichst sie alle mit
max_int*p. Wenn die jeweilige Zufallszahl kleiner als
dieser Schwellenwert ist, setzt Du das korrespondierende
Bit des Zielwertes auf 1, andernfalls auf 0.
Schlecht ist hier nur die Effizienz: 32 Input-Bits für ein Ergebnis-Bit.
Wenn man binär "glatte" Zahlen für p hat, z.B. 1/4 oder 3/8, dann kann man die Effizienz steigern, indem man zur Entscheidung keine 32-Bit-Zahl erzeugt, sondern z.B. nur 2 oder 3 Original-Zufallsbits verbraucht, natürlich mit einem angepassten Schwellwert.
Es kommt halt sehr drauf an, welche Anforderungen du an deinen Ergebnis-Zufall hast. Ein ganz offensichtliches Maß dafür ist die Unabhängigkeit des Ergebnis-Bits von der vorangegangenen Bitfolge. Das bekommt man ganz sicher hin, wenn man jedes Bit "frisch" aus Originalzufall herstellt und keinen Zustandsspeicher hat.
Wenn du etwas entspannter sein kannst, kann es ausreichen, eine leeren Bitpuffer anzulegen und dann per Zufall eine plausible Anzahl von 1-Bits drüberzusprenkeln und dann einfach den Puffer von vorne nach hinten auszugeben.
Ebenso denkbar ist, vorab einen ganzen Satz solcher Puffer zu erzeugen, die dann epsilon-typische Zufallsfolgen enthalten. Dann brauchst du nur wenige Bit Originalzufall um auszuwählen, von welchem Puffer du das nächste Bit holen willst. (Jeder Puffer braucht dann einen eigenen Positionszähler.)
Wenn es noch entspannter sein darf: Entscheide zufällig, welchen dieser Puffer du als nächstes komplett abspielen willst. Dann ist im Ergebnis zwar wirklich nur noch sehr wenig echter Zufall drin, dafür ist es extrem CPU-effizient. Und könnte für deine Anwendung vielleicht trotzdem noch ausreichen.