2011-10-26 21 views
17

私はJavaで乱数を生成したいと思いますが、私はMath.random()のような既存のメソッドを使用すべきですが、私の質問は次のとおりです。私のアプリケーションを実行するたびに? 例:生成された配列である:0.9、0.08,0.6 ので、私はこのシーケンスが、私はこの方法を実行するたびに生成されることを望む...乱数の同じシーケンスの生成

答えて

29

確かに - ちょうどいつもの代わりにMath.random()を使用してのRandomのインスタンスを作成し、

Random random = new Random(10000); // Or whatever seed - maybe configurable 
int diceRoll = random.nextInt(6) + 1; // etc 

タイミングが予測できなくなるため、アプリケーションに複数のスレッドが含まれていると、処理が困難になることに注意してください。

Randompseudo-random number generatorです。言い換えれば、新しい結果を求めるたびに、内部状態を操作してランダムに見えるシーケンスを与えますが、シード(実際には現在の内部州)それは完全に予測可能です。

+2

スレッドの場合は、各スレッドに独自のランダム(固定シードあり)または1つのランダム(固定シードあり)からそれぞれの事前に作成されたリストを少数だけ使用することができます。しかし、スレッドがお互いにやりとりする場合、このアプローチはもう働きません。 – Stefan

6

乱数ジェネレータをシードする必要があります。

Random random = new Random(aFixedNumber); 
random.nextInt(); // will always be the same 
24

同じシードを繰り返し使用する例です。

public static void main(String... args) throws IOException { 
    printDoublesForSeed(1); 
    printDoublesForSeed(128); 
    printDoublesForSeed(1); 
    printDoublesForSeed(128); 
} 

private static void printDoublesForSeed(long seed) { 
    double[] doubles = new double[10]; 
    Random rand = new Random(seed); 
    for (int j = 0; j < doubles.length; j++) { 
     doubles[j] = (long) (rand.nextDouble() * 100)/100.0; 
    } 
    System.out.println("doubles with seed " + seed + " " + Arrays.toString(doubles)); 
} 

プリント

doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93] 
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47] 
doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93] 
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47] 

EDITランダムシードの面白い虐待。

public static void main(String ... args) { 
    System.out.println(randomString(-6225973)+' '+randomString(1598025)); 
} 

public static String randomString(int seed) { 
    Random rand = new Random(seed); 
    StringBuilder sb = new StringBuilder(); 
    for(int i=0;i<5;i++) 
     sb.append((char) ('a' + rand.nextInt(26))); 
    return sb.toString(); 
} 

プリント

hello world 
+2

+1明確な説明のために。 – mre

+2

私はこんにちは世界の例が好きです。私は、正しいものを見つけるためにすべての可能な種子をブルートフォースする良い解決策はないと思いますか?編集:Doh明らかに、私は最初のコーヒーを得る前に物事を書くべきではありません: – Voo

+0

私はちょうどブルートフォースを使いました。 ;) –

4

Math.randomクラスjava.util.Randomの単なるラッパーです。最初にMath.randomと呼び出すと、クラスjava.util.Randomのインスタンスが作成されます。

ほとんどのAPIでは、乱数ジェネレータが公開されていません。これは、ソフトウェアで実装できないためです。代わりに、擬似ランダム番号ジェネレータを使用します。これらのジェネレータは、一連の数式を使用してランダムな数のシーケンスを生成します。これはjava.util.Randomの機能です。しかし、すべての擬似乱数ジェネレータはで始まり、最初にとなる必要があります。同じアルゴリズムを使用し、同じシードを使用する2つの疑似乱数ジェネレータがある場合、同じ出力が生成されます。

デフォルトでは、java.util.Randomは1970年1月1日からのミリ秒をシードとして使用します。そのため、プログラムを起動するたびに、別の番号が生成されます(Javaを1ミリ秒以下で起動するように管理しない限り)。だから、あなたの問題を解決するには、独自のjava.util.Randomインスタンスを作成し、自分でそれをシードすることです:

import java.util.Random; 

class ... { 
    Random randomNumberGenerator = new Random(199711); 

    public void ...() 
    { 
     int randomInt = randomNumberGenerator.nextInt(); 
     double randomDouble = randomNumberGenerator.nextDouble(); 
    } 
} 

randomNumberGeneratorは常に(限り、あなたはシードを変更しないように、同じ数列を吐き出すます199711)。

0

数字をアプリにハードコードします。これはより多くのメモリを必要としますが、はるかに高速です。

乱数を端末に印刷して、コードにコピーして貼り付けてください。

あなたのしたことを説明するコメントを残してください。そうしないと、情報のない読者には黒い魔法のように見えます。