|
Java プラットフォーム 1.2 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 内部クラス | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
java.lang.Object | +--java.util.Random
Random クラスのインスタンスは、一連の擬似乱数を生成します。クラスでは 48 ビットのシードを使い、このシードは線形合同式で変更されます。詳細は Donald Knuth 著『準数値算法/乱数』の 3.2.1 を参照してください。
2 つの Random
インスタンスが同じシードで生成され、それぞれに対して同じメソッド呼び出しのシーケンスが生成される場合は、同じ番号のシーケンスが生成され返されます。このプロパティを保証するために、固有のアルゴリズムが Random クラスに指定されます。Java コードの絶対的な移植性の保持のために、Java の実装はここに示されている Random クラスのアルゴリズムをすべて使用する必要があります。ただし、Random クラスのサブクラスは、すべてのメソッドの一般規約に準拠したものであればほかのアルゴリズムも使用できます。
Random クラスによって実装されるアルゴリズムは、protected の 3 つの状態変数を使用します。また、各呼び出しで擬似乱数的に生成された最大 32 ビットを提供できる protected ユーティリティメソッドも使用します。
ほとんどのアプリケーションでは、クラス Math
の random
メソッドを使う方が簡単です。
Math.random()
, 直列化された形式コンストラクタの概要 | |
Random()
新しい乱数ジェネレータを作成します。 |
|
Random(long seed)
long 型のシードを使って乱数ジェネレータを作成します。
|
メソッドの概要 | |
protected int |
next(int bits)
次の擬似乱数を生成します。 |
boolean |
nextBoolean()
乱数ジェネレータのシーケンスを使って、一様分布の boolean 型の次の擬似乱数を返します。 |
void |
nextBytes(byte[] bytes)
ユーザが指定した数のランダムバイトを生成します。 |
double |
nextDouble()
乱数ジェネレータのシーケンスを使って、 0.0 〜 1.0 の範囲で一様分布の double 型の擬似乱数を返します。 |
float |
nextFloat()
乱数ジェネレータのシーケンスを使って、 0.0 〜 1.0 の範囲で一様分布の float 型の次の擬似乱数を返します。 |
double |
nextGaussian()
乱数ジェネレータのシーケンスを使って、平均 0.0 、標準偏差 1.0 のガウス (「正規」) 分布の double 型の擬似乱数を返します。
|
int |
nextInt()
乱数ジェネレータのシーケンスを使って、一様分布の int 型の擬似乱数を返します。 |
int |
nextInt(int n)
乱数ジェネレータのシーケンスを使って、0 から指定された値の範囲 (0 は含むが、その指定された値は含まない) で一様分布の int 型の擬似乱数を返します。 |
long |
nextLong()
乱数ジェネレータのシーケンスを使って、一様分布の long 型の次の擬似乱数を返します。 |
void |
setSeed(long seed)
単一の long 型のシードを使って、乱数ジェネレータのシードを設定します。 |
クラス java.lang.Object から継承したメソッド |
clone,
equals,
finalize,
getClass,
hashCode,
notify,
notifyAll,
toString,
wait,
wait,
wait |
コンストラクタの詳細 |
public Random()
public Random() { this(System.currentTimeMillis()); }
System.currentTimeMillis()
public Random(long seed)
long
型のシードを使って乱数ジェネレータを作成します。
擬似乱数ジェネレータの状態を保持するために next メソッドによって使用されます。public Random(long seed) { setSeed(seed); }
seed
- 初期シードsetSeed(long)
メソッドの詳細 |
public void setSeed(long seed)
long
型のシードを使って、乱数ジェネレータのシードを設定します。setSeed の一般規約では、シードとして引数 seed を使って作成されたばかりの状態と同じになるように、この乱数ジェネレータオブジェクトの状態を変更します。setSeed メソッドは Random クラスによって次のように実装されます。
Random クラスによる setSeed の実装は、指定されたシードの 48 ビットだけを使用していますが、一般には、メソッドは変更することにより、シード値として long 引数の 64 ビットすべてを使用することもできます。synchronized public void setSeed(long seed) { this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1); haveNextNextGaussian = false; }
seed
- 初期シードprotected int next(int bits)
next の一般規約では、int 型の値を返し、引数 bits が 1 〜 32 (1と 32 を含む) の範囲の場合は、戻り値の多くの下位ビットが (ほぼ) 独立に選択されたビット値になり、それぞれの値は (ほぼ) 均等に 0 または 1 になります。next メソッドは Random クラスによって次のように実装されます。
これは、D. H. Lehmer によって定義された、線形合同擬似乱数ジェネレータです。詳細は Donald Knuth 著『準数値算法/乱数』の 3.2.1 を参照してください。synchronized protected int next(int bits) { seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); return (int)(seed >>> (48 - bits)); }
bits
- ランダムビットpublic void nextBytes(byte[] bytes)
public int nextInt()
int
型の擬似乱数を返します。nextInt の一般規約では、1 つの int 型の値が擬似乱数として生成されて返されます。232 の可能なすべての int 値が (ほぼ) 均等な確率で生成されます。setSeed メソッドは Random クラスによって次のように実装されます。
public int nextInt() { return next(32); }
int
型擬似乱数public int nextInt(int n)
int
型の擬似乱数を返します。nextInt の一般規約では、指定された範囲内の 1 つの int 値が擬似乱数として生成されて返されます。n 個の可能なすべての int 値が (ほぼ) 均等な確率で生成されます。nextInt(int n) メソッドは Random クラスによって次のように実装されます。
public int nextInt(int n) { if (n<=0) throw new IllegalArgumentException("n must be positive"); if ((n & -n) == n) // i.e., n is a power of 2 return (int)((n * (long)next(31)) >> 31); int bits, val; do { bits = next(31); val = bits % n; } while(bits - val + (n-1) < 0); return val; }
上記の説明で「ほぼ」という言葉を使用しているのは、next メソッドが、独立に選択されたビットのソースとしてバイアスがないのは、近似的にだけ成立するからです。ランダムに選択されたビットの完全なソースであるとすれば、示されたアルゴリズムは指定された範囲から完全に一様に int 型の値を選択することになります。
このアルゴリズムは多少扱いずらい面があります。このアルゴリズムは一様でない分布になる値を拒絶します (2^31 が n で割れないことによる)。値が拒絶される確率は n によって異なります。最悪のケースは n=2^30+1 で、この場合、拒絶の確率は 1/2 になり、ループが強制終了するまでの予想される反復回数は 2 回です。
このアルゴリズムは、n が 2 の累乗であるケースを特別に処理します。このアルゴリズムは、基になる擬似乱数ジェネレータから適切な数の上位ビットを返します。特別な処理がない場合は、適切な数の「下位」ビットが返されます。このクラスで実装されているような線形合同擬似乱数ジェネレータは、下位ビットの値のシーケンスで周期が短いことが知られています。そのため、この特別なケースでは、n が 2 の小さな累乗である場合、このメソッドの連続した呼び出しによって返される値のシーケンスの長さが大幅に長くなります。
public long nextLong()
long
型の次の擬似乱数を返します。nextLong の一般規約では、1 つの long 型の値が擬似乱数として生成されて返されます。264 の可能なすべての long 値が (ほぼ) 均等な確率で生成されます。setSeed メソッドは Random クラスによって次のように実装されます。
public long nextLong() { return ((long)next(32) << 32) + next(32); }
long
型の次の擬似乱数public boolean nextBoolean()
boolean
型の次の擬似乱数を返します。nextBoolean の一般規約では、1 つの boolean 型の値が擬似乱数として生成されて返されます。true
と false
の値が (ほぼ) 等しい確率で生成されます。nextBoolean メソッドは、Random クラスによって次のように実装されます。
public boolean nextBoolean() {return next(1) != 0;}
boolean
型の次の擬似乱数public float nextFloat()
0.0
〜 1.0
の範囲で一様分布の float
型の次の擬似乱数を返します。nextFloat の一般規約では、0.0f 〜 1.0f の範囲 (0.0f は含むが、1.0f は含まない) から (ほぼ) 均等な確率で選択された 1 つの float 型の値が、擬似乱数として生成されて返されます。m x 2-24 という形式 (m は 224 未満の正の整数) の 224 の可能なすべての float 値が (ほぼ) 均等な確率で生成されます。setSeed メソッドは Random クラスによって次のように実装されます。
上記の説明で「ほぼ」という言葉を使用しているのは、next メソッドが近似的にだけ、独立して選択されたビットのバイアスのないソースであるためです。完全なソースまたはランダムに選択されたビットであるとすれば、示されたアルゴリズムは指定された範囲から完全に一様に float 型の値を選択することになります。public float nextFloat() { return next(24) / ((float)(1 << 24)); }
[以前のバージョンの Java では、結果は次のように誤って計算されました。
これでもある程度等しく思われますが、実際には、浮動小数点数の丸めでのバイアスのために多少のばらつきが生じるので、有効数字の下位ビットが、1 よりも 0 になることが多くなりがちでした。]return next(30) / ((float)(1 << 30));
0.0
〜 1.0
の範囲で一様分布の float
型擬似乱数public double nextDouble()
0.0
〜 1.0
の範囲で一様分布の double
型の擬似乱数を返します。 nextDouble の一般規約では、0.0d 〜 1.0d の範囲から (ほぼ) 均等な確率で選択された 1 つの double 値が擬似乱数として生成されて返されます。m x 2-53 という形式 (m は 253 未満の正の整数) の 253 の可能なすべての float 値が (ほぼ) 均等な確率で生成されます。setSeed メソッドは Random クラスによって次のように実装されます。
public double nextDouble() { return (((long)next(26) << 27) + next(27)) / (double)(1L << 53); }
上記の説明で「ほぼ」という言葉を使用しているのは、nextメソッドが近似的にだけ、独立して選択されたビットのバイアスのないソースであるためです。完全なソースまたはランダムに選択されたビットであるとすれば、示されたアルゴリズムは指定された範囲から完全に一様に double 型の値を選択することになります。
[以前のバージョンの Java では、結果は次のように誤って計算されました。
これでもある程度等しく思われますが、実際には、浮動小数点数の丸めでのバイアスのために大きなばらつきが生じるので、有効数字の下位ビットが 0 になることが 1 になることの 3 倍ありました。この程度のばらつきは実際には問題になりませんが、完全性を求めて修正を試みています。]return (((long)next(27) << 27) + next(27)) / (double)(1L << 54);
0.0
〜 1.0
の範囲で一様分布の double
型擬似乱数public double nextGaussian()
0.0
、標準偏差 1.0
のガウス (「正規」) 分布の double
型の擬似乱数を返します。
nextGaussian の一般規約では、平均 0.0、標準偏差 1.0 の (ほぼ) 通常の正規分布から選択された、1 つの double 型の値が擬似乱数として生成されて返されます。setSeed メソッドは Random クラスによって次のように実装されます。
これは、Donald E. Knuth 著『準数値算法/乱数』の 3.4.1 の C、アルゴリズム P で説明されている、G. E. P. Box、M. E. Muller、および G. Marsaglia の「polar method」を使用します。Math.log と Math.sqrt の呼び出しだけで 2 つの別々の値を生成することに注意してください。synchronized public double nextGaussian() { if (haveNextNextGaussian) { haveNextNextGaussian = false; return nextNextGaussian; } else { double v1, v2, s; do { v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0 v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0 s = v1 * v1 + v2 * v2; } while (s >= 1); double norm = Math.sqrt(-2 * Math.log(s)/s); nextNextGaussian = v2 * multiplier; haveNextNextGaussian = true; return v1 * multiplier; } }
0.0
、標準偏差 1.0
のガウス (「正規」) 分布の double
型擬似乱数
|
Java プラットフォーム 1.2 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 内部クラス | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |