Den Zufallszahlengenerator in Javascript setzen

372

Ist es möglich, den Zufallszahlengenerator (Math.random) in Javascript zu setzen?

weinerlich
quelle
Es ist nicht klar, ob Sie es säen möchten, damit Sie wiederholt dieselben Ergebnisse für verschiedene Testläufe erhalten, oder ob Sie es mit "etwas Einzigartigem" pro Benutzer säen möchten, um eine bessere Zufälligkeit zwischen den Verwendungszwecken zu erzielen.
Simbo1905
2
Nein, das ist leider nicht möglich. jsrand ist eine kleine Bibliothek, die ich geschrieben habe, als ich ein setzbares PRNG brauchte. Es gibt auch andere komplexere Bibliotheken, die Sie googeln können.
Domenico De Felice
4
Hinzu kommt die Frage: Wie ist es möglicherweise eine gute Idee, ein PRNG anzubieten, ohne es zu säen? Gibt es dafür einen guten Grund?
Alan
Siehe auch stackoverflow.com/questions/424292
Palimondo

Antworten:

159

HINWEIS: Trotz (oder vielmehr wegen) Prägnanz und offensichtlicher Eleganz ist dieser Algorithmus in Bezug auf die Zufälligkeit keineswegs von hoher Qualität. Suchen Sie nach den in dieser Antwort aufgeführten, um bessere Ergebnisse zu erzielen.

(Ursprünglich angepasst von einer cleveren Idee, die in einem Kommentar zu einer anderen Antwort präsentiert wurde.)

var seed = 1;
function random() {
    var x = Math.sin(seed++) * 10000;
    return x - Math.floor(x);
}

Sie können einstellen seed eine beliebige Zahl festlegen. Vermeiden Sie einfach Null (oder ein Vielfaches von Math.PI).

Die Eleganz dieser Lösung beruht meiner Meinung nach auf dem Fehlen jeglicher "magischer" Zahlen (neben 10000, was ungefähr der Mindestanzahl von Ziffern entspricht, die Sie wegwerfen müssen, um ungerade Muster zu vermeiden - siehe Ergebnisse mit Werten 10 , 100 , 1000 ). Kürze ist auch schön.

Es ist etwas langsamer als Math.random () (um den Faktor 2 oder 3), aber ich glaube, es ist ungefähr so ​​schnell wie jede andere in JavaScript geschriebene Lösung.

Antti Kissaniemi
quelle
20
Gibt es eine Möglichkeit zu beweisen, dass dieses RNG Zahlen generiert, die gleichmäßig verteilt sind? Experimentell scheint es: jsfiddle.net/bhrLT
Nathan Breit
6
6.000.000 Operationen / Sekunde sind ziemlich schnell, ich habe nicht vor, mehr als ~ 3.000.000 pro Klick zu generieren. Scherz, das ist genial.
AMK
59
-1, Dies ist überhaupt kein einheitlicher Sampler - er ist ziemlich voreingenommen in Richtung 0 und 1 (siehe jsfiddle.net/bhrLT/17 , dessen Berechnung eine Weile dauern kann). Aufeinanderfolgende Werte sind korreliert - alle 355 Werte und noch mehr alle 710 sind miteinander verbunden. Bitte verwenden Sie etwas sorgfältig durchdachtes!
Spencer Nelson
37
Bei der Frage geht es nicht darum, einen kryptografisch sicheren Zufallszahlengenerator zu erstellen, sondern um etwas, das in Javascript funktioniert, für schnelle Demos nützlich ist usw. Ich nehme etwas schnelles und einfaches, das zu diesem Zweck eine gut aussehende Verteilung über eine Million Zufallszahlen ergibt.
Jason Goemaat
15
Achtung. Math.sin () kann auf Client und Server unterschiedliche Ergebnisse liefern. Ich benutze Meteor (verwendet Javascript auf Client & Server).
Obiwahn
145

Ich habe eine Reihe guter, kurzer und schneller Funktionen des Pseudozufallszahlengenerators (PRNG) in einfachem JavaScript implementiert . Alle von ihnen können ausgesät werden und liefern gute Qualitätszahlen.

Achten Sie zunächst darauf, Ihre PRNGs ordnungsgemäß zu initialisieren. Die meisten der Generatoren haben unten keine integrierte Prozedur Samen Erzeugen (der Einfachheit halber), aber akzeptieren einen oder mehrere 32-Bit - Werte als Anfangszustand des PRNG. Ähnliche Keime (z. B. ein einfacher Keim von 1 und 2) können Korrelationen in schwächeren PRNGs verursachen, was dazu führt, dass die Ausgabe ähnliche Eigenschaften aufweist (z. B. zufällig erzeugte Niveaus sind ähnlich). Um dies zu vermeiden, empfiehlt es sich, PRNGs mit einem gut verteilten Seed zu initialisieren.

Glücklicherweise sind Hash-Funktionen sehr gut darin, aus kurzen Strings Seeds für PRNGs zu generieren. Eine gute Hash-Funktion führt zu sehr unterschiedlichen Ergebnissen, selbst wenn zwei Zeichenfolgen ähnlich sind. Hier ist ein Beispiel, das auf der Mischfunktion von MurmurHash3 basiert:

function xmur3(str) {
    for(var i = 0, h = 1779033703 ^ str.length; i < str.length; i++)
        h = Math.imul(h ^ str.charCodeAt(i), 3432918353),
        h = h << 13 | h >>> 19;
    return function() {
        h = Math.imul(h ^ h >>> 16, 2246822507);
        h = Math.imul(h ^ h >>> 13, 3266489909);
        return (h ^= h >>> 16) >>> 0;
    }
}

Jeder nachfolgende Aufruf der Rückgabefunktion von xmur3erzeugt einen neuen "zufälligen" 32-Bit-Hashwert, der als Startwert in einem PRNG verwendet wird. So können Sie es verwenden:

// Create xmur3 state:
var seed = xmur3("apples");
// Output four 32-bit hashes to provide the seed for sfc32.
var rand = sfc32(seed(), seed(), seed(), seed());

// Output one 32-bit hash to provide the seed for mulberry32.
var rand = mulberry32(seed());

// Obtain sequential random numbers like so:
rand();
rand();

Alternativ können Sie einfach einige Dummy-Daten auswählen, mit denen der Startwert aufgefüllt werden soll, und den Generator einige Male (12 bis 20 Iterationen) vorschieben, um den Anfangszustand gründlich zu mischen. Dies wird häufig in Referenzimplementierungen von PRNGs gesehen, begrenzt jedoch die Anzahl der Anfangszustände.

var seed = 1337 ^ 0xDEADBEEF; // 32-bit seed with optional XOR value
// Pad seed with Phi, Pi and E.
// https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number
var rand = sfc32(0x9E3779B9, 0x243F6A88, 0xB7E15162, seed);
for (var i = 0; i < 15; i++) rand();

Die Ausgabe dieser PRNG-Funktionen erzeugt eine positive 32-Bit-Zahl (0 bis 2 32 -1), die dann in eine Gleitkommazahl zwischen 0-1 (0 einschließlich, 1 exklusiv) umgewandelt wird, was entspricht Math.random(), wenn Sie Zufallszahlen wünschen Lesen Sie diesen Artikel über MDN . Wenn Sie nur die Rohbits möchten, entfernen Sie einfach die letzte Teilungsoperation.

Eine andere Sache zu beachten sind die Einschränkungen von JS. Zahlen können nur ganze Ganzzahlen mit einer Auflösung von bis zu 53 Bit darstellen. Bei Verwendung von bitweisen Operationen wird dies auf 32 reduziert. Dies macht es schwierig, in C oder C ++ geschriebene Algorithmen zu implementieren, die 64-Bit-Zahlen verwenden. Für die Portierung von 64-Bit-Code sind Shims erforderlich, die die Leistung drastisch reduzieren können. Der Einfachheit und Effizienz halber habe ich nur Algorithmen in Betracht gezogen, die 32-Bit-Mathematik verwenden, da diese direkt mit JS kompatibel ist.

Nun zu den Generatoren. (Ich pflege die vollständige Liste mit Referenzen hier )


sfc32 (Einfacher schneller Zähler)

sfc32 ist Teil der PractRand- Suite zum Testen von Zufallszahlen (die es natürlich besteht). sfc32 hat einen 128-Bit-Status und ist in JS sehr schnell.

function sfc32(a, b, c, d) {
    return function() {
      a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0; 
      var t = (a + b) | 0;
      a = b ^ b >>> 9;
      b = c + (c << 3) | 0;
      c = (c << 21 | c >>> 11);
      d = d + 1 | 0;
      t = t + d | 0;
      c = c + t | 0;
      return (t >>> 0) / 4294967296;
    }
}

Mulberry32

Mulberry32 ist ein einfacher Generator mit einem 32-Bit-Status, der jedoch extrem schnell und von guter Qualität ist (der Autor gibt an, dass er alle Tests der gjrand- Testsuite besteht und einen vollständigen Zeitraum von 2 bis 32 hat, den ich jedoch nicht überprüft habe).

function mulberry32(a) {
    return function() {
      var t = a += 0x6D2B79F5;
      t = Math.imul(t ^ t >>> 15, t | 1);
      t ^= t + Math.imul(t ^ t >>> 7, t | 61);
      return ((t ^ t >>> 14) >>> 0) / 4294967296;
    }
}

Ich würde dies empfehlen, wenn Sie nur ein einfaches, aber anständiges PRNG benötigen und keine Milliarden von Zufallszahlen benötigen (siehe Geburtstagsproblem ).

xoshiro128 **

Seit Mai 2018 ist xoshiro128 ** das neue Mitglied der Xorshift-Familie von Vigna / Blackman (der auch xoroshiro geschrieben hat, das in Chrome verwendet wird). Es ist der schnellste Generator, der einen 128-Bit-Status bietet.

function xoshiro128ss(a, b, c, d) {
    return function() {
        var t = b << 9, r = a * 5; r = (r << 7 | r >>> 25) * 9;
        c ^= a; d ^= b;
        b ^= c; a ^= d; c ^= t;
        d = d << 11 | d >>> 21;
        return (r >>> 0) / 4294967296;
    }
}

Die Autoren behaupten, dass es Zufälligkeitstests gut besteht ( wenn auch mit Einschränkungen ). Andere Forscher haben darauf hingewiesen, dass einige Tests in TestU01 (insbesondere LinearComp und BinaryRank) nicht bestanden wurden. In der Praxis sollte es keine Probleme verursachen, wenn Floats verwendet werden (wie diese Implementierungen), kann jedoch Probleme verursachen, wenn Sie sich auf die rohen Low-Bits verlassen.

JSF (Jenkins 'Small Fast)

Dies ist JSF oder 'smallprng' von Bob Jenkins (2007), dem Typ, der ISAAC und SpookyHash gemacht hat . Es geht PractRand Tests und soll recht schnell, wenn auch nicht so schnell wie SFC sein.

function jsf32(a, b, c, d) {
    return function() {
        a |= 0; b |= 0; c |= 0; d |= 0;
        var t = a - (b << 27 | b >>> 5) | 0;
        a = b ^ (c << 17 | c >>> 15);
        b = c + d | 0;
        c = d + t | 0;
        d = a + t | 0;
        return (d >>> 0) / 4294967296;
    }
}

LCG (auch bekannt als Lehmer / Park-Miller RNG oder MCG)

LCG ist extrem schnell und einfach, aber die Qualität seiner Zufälligkeit ist so gering, dass eine unsachgemäße Verwendung tatsächlich Fehler in Ihrem Programm verursachen kann! Trotzdem ist es deutlich besser als einige Antworten, die vorschlagen, Math.sinoder zu verwenden Math.PI! Es ist allerdings ein Einzeiler, was schön ist :).

var LCG=s=>()=>(2**31-1&(s=Math.imul(48271,s)))/2**31;

Diese Implementierung wird als Minimalstandard- RNG bezeichnet, wie von Park-Miller 1988 und 1993 vorgeschlagen und in C ++ 11 als implementiert minstd_rand. Beachten Sie, dass der Status 31 Bit ist (31 Bit ergeben 2 Milliarden mögliche Zustände, 32 Bit ergeben das Doppelte). Dies ist genau die Art von PRNG, die andere zu ersetzen versuchen!

Es wird funktionieren, aber ich würde es nicht verwenden, es sei denn, Sie brauchen wirklich Geschwindigkeit und kümmern sich nicht um die Zufallsqualität (was ist überhaupt zufällig?). Ideal für einen Game Jam oder eine Demo oder so. LCGs leiden unter Samenkorrelationen, daher ist es am besten, das erste Ergebnis zu verwerfen einer LCG . Und wenn Sie darauf bestehen, eine LCG zu verwenden, kann das Hinzufügen eines Inkrementwerts die Ergebnisse verbessern, aber es ist wahrscheinlich eine Übung der Sinnlosigkeit, wenn es viel bessere Optionen gibt.

Es scheint andere Multiplikatoren zu geben, die einen 32-Bit-Zustand (vergrößerter Zustandsraum) anbieten:

var LCG=s=>()=>(s=Math.imul(741103597,s)>>>0)/2**32;
var LCG=s=>()=>(s=Math.imul(1597334677,s)>>>0)/2**32;

Diese LCG-Werte stammen von: P. L'Ecuyer: Eine Tabelle von linearen Kongruenzgeneratoren unterschiedlicher Größe und guter Gitterstruktur, 30. April 1997.

Bryc
quelle
5
Dies ist eine erstaunliche Antwort. Ich werde sicher darauf zurückkommen.
DavidsKanal
1
Ich glaube, die Werte, die Sie aus "Tabellen linearer Kongruenzgeneratoren ..." von Pierre L'ecuyer zitiert haben, könnten die maximale Ganzzahlgröße in Javascript überschreiten. Der maximale Startwert von (2 ^ 32-1) * 741103597 ≈ 3e18, der größer ist als die maximale int-Größe von JavaScript von ≈ 9e15. Ich denke, die folgenden Werte aus Pierre's Buch haben den größten Zeitraum innerhalb der einheimischen Grenzen : seed = (seed * 185852 + 1) % 34359738337.
Lachmanski
1
@Lachmanski stimmt, aber diese sind durch 32-Bit (und die Park-Miller 31-Bit) gebunden. Die Verwendung Math.imulermöglicht einen Überlauf wie bei der Multiplikation in C mit 32-Bit-Ganzzahlen. Was Sie vorschlagen, ist eine LCG, die den gesamten Bereich des JS-Integer-Raums nutzt. Dies ist definitiv auch ein interessantes Gebiet, das es zu erkunden gilt. :)
Bryc
1
Das ist fantastisch! Kann ich Ihren sfc32 einfach in ein LGPL-Programm kopieren?
user334639
4
@ blobber2 nicht sicher, was du meinst, aber der Originalcode stammt von hier (mit anderen): github.com/bryc/code/blob/master/jshash/PRNGs.md . mehr oder weniger ein Kern in einem Repository :-)
Bryc
39

Nein, aber hier ist ein einfacher Pseudozufallsgenerator, eine Implementierung von Multiply-with-Carry, die ich aus Wikipedia übernommen habe (wurde seitdem entfernt):

var m_w = 123456789;
var m_z = 987654321;
var mask = 0xffffffff;

// Takes any integer
function seed(i) {
    m_w = (123456789 + i) & mask;
    m_z = (987654321 - i) & mask;
}

// Returns number between 0 (inclusive) and 1.0 (exclusive),
// just like Math.random().
function random()
{
    m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
    m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
    var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
    result /= 4294967296;
    return result;
}

EDIT: Behebung der
Startfunktion durch Zurücksetzen von m_z EDIT2: Schwerwiegende Implementierungsfehler wurden behoben

Antti Kissaniemi
quelle
3
Hat jemand diese Funktion auf ihre Zufälligkeit getestet?
Justin
3
Dies ist der MWC- Zufallsgenerator (Multiplikation mit Übertrag) mit einer ziemlich langen Periode. Adaptiert von Wikipedia Zufallszahlengeneratoren
Michael_Scharf
10
Die seedFunktion setzt den Zufallsgenerator nicht zurück, da die mz_zVariable beim random()Aufruf geändert wird. Setzen Sie daher mz_z = 987654321(oder einen anderen Wert) inseed
Michael_Scharf
Wenn ich es mit meinem Zufallsfarbgenerator (HSL) verwende, werden nur grüne und cyanfarbene Farben erzeugt. Der ursprüngliche Zufallsgenerator generiert alle Farben. Es ist also nicht dasselbe oder es funktioniert nicht.
Tomas Kubes
@Michael_Scharf 1) Der Samenwechsel m_w, nicht m_z. 2) Beide m_wund werden m_zbasierend auf ihren vorherigen Werten geändert, sodass das Ergebnis geändert wird.
ESL
26

Der Algorithmus von Antti Sykäri ist nett und kurz. Ich habe anfangs eine Variation vorgenommen, die Math.random von Javascript ersetzte, wenn Sie Math.seed (s) aufrufen, aber dann bemerkte Jason, dass die Rückgabe der Funktion besser wäre:

Math.seed = function(s) {
    return function() {
        s = Math.sin(s) * 10000; return s - Math.floor(s);
    };
};

// usage:
var random1 = Math.seed(42);
var random2 = Math.seed(random1());
Math.random = Math.seed(random2());

Dies gibt Ihnen eine weitere Funktionalität, die Javascript nicht hat: mehrere unabhängige Zufallsgeneratoren. Dies ist besonders wichtig, wenn mehrere wiederholbare Simulationen gleichzeitig ausgeführt werden sollen.


quelle
3
Wenn Sie die Funktion zurückgeben, anstatt sie so einzustellen Math.random, dass Sie mehrere unabhängige Generatoren haben, oder?
Jason Goemaat
1
Achten
jocull
Wie können dadurch erzeugte Zufälligkeiten wiederholt werden? Es gibt jedes Mal neue Zahlen
SMUsamaShah
jedes Mal , wenn Sie tun , Math.seed(42);es setzt die Funktion, wenn Sie also tun var random = Math.seed(42); random(); random();erhalten Sie 0.70..., dann 0.38.... Wenn Sie es zurücksetzen, indem Sie var random = Math.seed(42);erneut anrufen, erhalten random()Sie beim nächsten Anruf 0.70...erneut und beim nächsten Mal 0.38...erneut.
WOUNDEDStevenJones
1
Bitte benutzen Sie dies nicht. Bitte nehmen Sie sich die Zeit, stattdessen eine lokale Variable mit dem Namen zu verwenden, randomanstatt eine native Javascript-Funktion zu überschreiben. Das Überschreiben Math.randomkann dazu führen, dass der JIST-Compiler den gesamten Code nicht optimiert.
Jack Giffin
11

Bitte sehen Sie Pierre L'Ecuyers Arbeiten, die bis in die späten 1980er und frühen 1990er Jahre zurückreichen. Es gibt auch andere. Wenn Sie kein Experte sind, ist es ziemlich gefährlich, selbst einen (Pseudo-) Zufallszahlengenerator zu erstellen, da die Wahrscheinlichkeit hoch ist, dass die Ergebnisse statistisch nicht zufällig sind oder nur einen kurzen Zeitraum haben. Pierre (und andere) haben einige gute (Pseudo-) Zufallszahlengeneratoren zusammengestellt, die einfach zu implementieren sind. Ich benutze einen seiner LFSR-Generatoren.

https://www.iro.umontreal.ca/~lecuyer/myftp/papers/handstat.pdf

Phil Troy

user2383235
quelle
1
Tolle Antwort, aber nicht im Zusammenhang mit Javascript :)
Nikolay Fominyh
3
Der Code zur Implementierung der Arbeit von Professor L'Ecuyer ist öffentlich für Java verfügbar und kann von den meisten Programmierern problemlos in Javascript übersetzt werden.
user2383235
6

Wenn Sie einige der vorherigen Antworten kombinieren, ist dies die gesetzte Zufallsfunktion, nach der Sie suchen:

Math.seed = function(s) {
    var mask = 0xffffffff;
    var m_w  = (123456789 + s) & mask;
    var m_z  = (987654321 - s) & mask;

    return function() {
      m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
      m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;

      var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
      result /= 4294967296;
      return result;
    }
}

var myRandomFunction = Math.seed(1234);
var randomNumber = myRandomFunction();
user3158327
quelle
4
Dies führt zu sehr ähnlichen Ergebnissen zu Beginn der Sequenz mit verschiedenen Samen. Zum Beispiel Math.seed(0)()return 0.2322845458984375und Math.seed(1)()return 0.23228873685002327. Beides m_wund m_zje nach Samen zu ändern scheint zu helfen. var m_w = 987654321 + s; var m_z = 123456789 - s;erzeugt eine schöne Verteilung der ersten Werte mit verschiedenen Samen.
undefiniert
1
@undefined Das von Ihnen beschriebene Problem wurde seit der letzten Bearbeitung behoben. Es war ein Fehler in der MWC-Implementierung.
Bryc
Funktioniert jetzt gut, ab Januar 2020. Seed mit 0, erhalten Sie 0,7322976540308446. Samen mit 1, 0,16818441334180534, mit 2: 0,6040864314418286, mit 3: 0,03998844954185188. Danke euch beiden!
Eureka
3

Es ist ganz einfach, einen eigenen Pseudozufallsgenerator zu schreiben.

Der Vorschlag von Dave Scotese ist nützlich, aber, wie andere betonten, nicht ganz gleichmäßig verteilt.

Es liegt jedoch nicht an den ganzzahligen Argumenten der Sünde. Es liegt einfach an der Reichweite der Sünde, die zufällig eine eindimensionale Projektion eines Kreises ist. Wenn Sie stattdessen den Winkel des Kreises nehmen würden, wäre er gleichmäßig.

Verwenden Sie also anstelle von sin (x) arg (exp (i * x)) / (2 * PI).

Wenn Ihnen die lineare Reihenfolge nicht gefällt, mischen Sie sie ein wenig mit xor. Der eigentliche Faktor spielt auch keine Rolle.

Um n Pseudozufallszahlen zu erzeugen, könnte man den folgenden Code verwenden:

function psora(k, n) {
  var r = Math.PI * (k ^ n)
  return r - Math.floor(r)
}
n = 42; for(k = 0; k < n; k++) console.log(psora(k, n))

Bitte beachten Sie auch, dass Sie keine Pseudozufallssequenzen verwenden können, wenn echte Entropie benötigt wird.

Lajos Bodrogi
quelle
Ich bin kein Experte, aber sequentielle Samen folgen einem konstanten Muster . Farbige Pixel sind> = 0,5. Ich vermute, es iteriert immer und immer wieder über den Radius?
Bryc
1

Math.randomNein, aber die Ran- Bibliothek löst dies. Es hat fast alle denkbaren Verteilungen und unterstützt die Erzeugung von gesetzten Zufallszahlen. Beispiel:

ran.core.seed(0)
myDist = new ran.Dist.Uniform(0, 1)
samples = myDist.sample(1000)
Ulf Aslak
quelle
-1

Ich habe eine Funktion geschrieben, die eine gesetzte Zufallszahl zurückgibt. Sie verwendet Math.sin, um eine lange Zufallszahl zu haben, und verwendet den Startwert, um Zahlen daraus auszuwählen.

Verwenden :

seedRandom("k9]:2@", 15)

Es gibt Ihre gesetzte Zahl zurück. Der erste Parameter ist ein beliebiger Zeichenfolgenwert. dein Same. Der zweite Parameter gibt an, wie viele Ziffern zurückgegeben werden.

     function seedRandom(inputSeed, lengthOfNumber){

           var output = "";
           var seed = inputSeed.toString();
           var newSeed = 0;
           var characterArray = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','y','x','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','U','R','S','T','U','V','W','X','Y','Z','!','@','#','$','%','^','&','*','(',')',' ','[','{',']','}','|',';',':',"'",',','<','.','>','/','?','`','~','-','_','=','+'];
           var longNum = "";
           var counter = 0;
           var accumulator = 0;

           for(var i = 0; i < seed.length; i++){
                var a = seed.length - (i+1);
                for(var x = 0; x < characterArray.length; x++){
                     var tempX = x.toString();
                     var lastDigit = tempX.charAt(tempX.length-1);
                     var xOutput = parseInt(lastDigit);
                     addToSeed(characterArray[x], xOutput, a, i); 
                }                  
           }

                function addToSeed(character, value, a, i){
                     if(seed.charAt(i) === character){newSeed = newSeed + value * Math.pow(10, a)}
                }
                newSeed = newSeed.toString();

                var copy = newSeed;
           for(var i=0; i<lengthOfNumber*9; i++){
                newSeed = newSeed + copy;
                var x = Math.sin(20982+(i)) * 10000;
                var y = Math.floor((x - Math.floor(x))*10);
                longNum = longNum + y.toString()
           }

           for(var i=0; i<lengthOfNumber; i++){
                output = output + longNum.charAt(accumulator);
                counter++;
                accumulator = accumulator + parseInt(newSeed.charAt(counter));
           }
           return(output)
      }
Tyler Hudson
quelle
1
Die dadurch erzeugten Folgen von Zahlen nähern sich nicht wirklich den Eigenschaften von Folgen von Zufallszahlen an. Generieren Sie damit 15 Zahlen und die resultierende Zeichenfolge beginnt zum Beispiel fast immer mit einer 7 für fast jeden Schlüssel.
Gabriel
-2

Ein einfacher Ansatz für einen festen Samen:

function fixedrandom(p){
    const seed = 43758.5453123;
    return (Math.abs(Math.sin(p)) * seed)%1;
}
Carlos Oliveira
quelle
-6

Für eine Zahl zwischen 0 und 100.

Number.parseInt(Math.floor(Math.random() * 100))
Lord Elrond
quelle
3
Bei der Frage geht es darum, so zu säen Math.random, dass jedes Mal, wenn Math.randommit demselben Samen gesät wird, dieselbe aufeinanderfolgende Reihe von Zufallszahlen erzeugt wird. Bei dieser Frage geht es nicht um die tatsächliche Verwendung / Demonstration von Math.random.
Jack Giffin