2010-01-27 17 views
9

Ist es möglich, von .NET, die genaue Randomisierung, die Java verwendet, nachzuahmen? Ich habe einen Seed, und ich möchte in der Lage sein, die gleichen Ergebnisse in C# und Java zu erhalten, wenn Sie eine Zufallszahl erstellen.C#/Java-Nummer Randomisierung

+0

Und wie zufällig ist das? ... Einfach fragen .. –

+0

@Filip: Ich denke, es ist implizit, dass er nur stochastische Zufälligkeit will. –

+0

Ich denke du hast Recht. –

Antwort

5

Wenn Sie den Quellcode der Klasse java.util.Random für Ihre Java-Implementierung haben, können Sie ihn problemlos nach .NET portieren.

Wenn Sie beide Anwendungen (Java und .NET) für die Verwendung eines bestimmten Zufallszahlengenerators benötigen, sollten Sie einen in beiden Plattformen implementieren und stattdessen verwenden, da die vom System bereitgestellte Version möglicherweise das Verhalten ändert eines Updates. (Sieht aus wie die Java-Spezifikation beschreibt genau das Verhalten seiner PRNG.)

+0

Aber ist nicht der Algorithmus ein Implementierungsdetail und wahrscheinlich zwischen Versionen/Implementierungen zu ändern ?IMO wäre es besser, einen benutzerdefinierten Algorithmus sowohl in Java als auch in C# zu implementieren, um konsistente Ergebnisse zu erhalten. – dtb

+0

@ dtb: Dachte über die gleiche Sache nach. Wenn es zu Testzwecken temporär ist, würde das ausreichen. Ansonsten, ja, sollten Sie Ihre eigenen implementieren. –

+4

@ dtb: Der Algorithmus ist in der Dokumentation der Java-Random-Klasse angegeben und daher eine Spezifikation. Die Implementierungsdetails können sich ändern, aber ich bezweifle stark, dass die tatsächliche Sequenz, die von ihr generiert wird, in einer zukünftigen Version enthalten sein wird. Wenn überhaupt, ist es wahrscheinlicher, dass sie eine andere PRNG in einer separaten Klasse hinzufügen. Aber angesichts Javas beabsichtigten Umfang und ausgereifter Bibliotheken, die tatsächlich eine gute Arbeit für die Pseudozufallszahlengenerierung leisten, bezweifle ich, dass das sowieso passieren wird. – Joey

0

Nun, Sie können in den Quellcode für Random.java suchen und kopieren Sie den Algorithmus, Konstanten usw.etc, aber Random verwendet System.nanoTime in seinem Konstruktor erhalten Sie also nicht die gleichen Ergebnisse.

Von java.util.Random

öffentlich Random() { diese (++ seedUniquifier + System.nanoTime()); }

Ich wäre überhaupt nicht überrascht, wenn die Quelle in C# Ihnen etwas Ähnliches zeigen würde.

Edit: Ignorieren, wie bereits erwähnt wurde, der Konstruktor, der einen Input-Seed übernimmt, greift niemals auf die Zeit zu.

+2

Er verwendet für beide den gleichen Startwert, daher ist der Standardstartwert in der Java-Implementierung irrelevant. –

+0

Es verwendet es nur, wenn Sie keinen Seed haben, gibt es 2 Konstruktoren 'Random()' - Nimmt nichts und verwendet 'Environment.TickCount' und' Random (int32 num) ', die Ihren Samen anstelle des TickCount nimmt. –

0

Vielleicht wäre es sinnvoll, einen eigenen einfachen Pseudozufallszahlengenerator zu implementieren? Auf diese Weise haben Sie die vollständige Kontrolle und können denselben Samen liefern, um in beiden Umgebungen die gleichen Ergebnisse zu erzielen. Wahrscheinlich ein bisschen mehr Arbeit als die Portierung von einem zum anderen.

1

Wenn Sie keinen kryptografisch sicheren Pseudozufallszahlengenerator benötigen, würde ich mich für die Mersenne twister entscheiden. Sie finden den Quellcode für C# here und Java here.

+1

Das war jedoch nicht die Frage. Und 'java.util.Random' ist auch nicht kryptografisch sicher, so dass es offensichtlich nicht h (is | er) betrifft ;-) – Joey

+1

Es war nicht die Frage sondern seit *" die exakte Randomisierung nachzuahmen, die Java benutzt "* scheint schwer Unmöglich zu tun, konzentrierte ich mich auf * "Ich würde gerne in der Lage sein, die gleichen Ergebnisse sowohl in C# und Java" * zu erhalten. –

-2

Eine andere Möglichkeit könnte sein, Ihre Zufallszahlen einmal von einer Plattform in eine Datei zu schreiben und dann Ihre Zufallszahlen für beide Plattformen aus dieser Datei zu laden, oder Sie könnten sie von einem Dienst wie random.org

laden
5

Sie müssen den Quellcode nicht lesen. Die Formel ist ein Ein-Liner und in den documentation for java.util.Random.

gegeben

Hier ist eine teilweise Übersetzung:

[Serializable] 
public class Random 
{ 
    public Random(UInt64 seed) 
    { 
     this.seed = (seed^0x5DEECE66DUL) & ((1UL << 48) - 1); 
    } 

    public int NextInt(int n) 
    { 
     if (n <= 0) throw new ArgumentException("n must be positive"); 

     if ((n & -n) == n) // i.e., n is a power of 2 
      return (int)((n * (long)Next(31)) >> 31); 

     long bits, val; 
     do 
     { 
      bits = Next(31); 
      val = bits % (UInt32) n; 
     } 
     while (bits - val + (n - 1) < 0); 

     return (int) val; 
    } 

    protected UInt32 Next(int bits) 
    { 
     seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); 

     return (UInt32)(seed >> (48 - bits)); 
    } 

    private UInt64 seed; 
} 

Beispiel:

Random rnd = new Random(42); 
Console.WriteLine(rnd.NextInt(10)); 
Console.WriteLine(rnd.NextInt(20)); 
Console.WriteLine(rnd.NextInt(30)); 
Console.WriteLine(rnd.NextInt(40)); 
Console.WriteLine(rnd.NextInt(50)); 

Output auf beiden Plattformen ist 0, 3, 18, 4, 20.

Verwandte Themen