[解決済み] Random (Java 7)の 181783497276652981 と 8682522807148012 は何ですか?
質問
なぜ
181783497276652981
と
8682522807148012
で選ばれた
Random.java
?
以下は、Java SE JDK 1.7の関連するソースコードです。
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);
というわけで
new Random()
を呼び出すと、現在のquot;seed uniquifier"を受け取り、それをXORして
System.nanoTime()
. そして
181783497276652981
を使って別のシードユニークファイアを作成し、 次回のために保存します。
new Random()
が呼び出されたときのために保存されます。
リテラルは
181783497276652981L
と
8682522807148012L
は定数には置かれませんが、他の場所には現れません。
最初はコメントから簡単に手がかりが得られます。 その記事をオンラインで検索すると
実際の記事
.
8682522807148012
は論文には出てきませんが
181783497276652981
は別の数字の部分文字列として登場します。
1181783497276652981
であり、これは
181783497276652981
を持つ
1
が付加されています。
この論文では、次のように主張しています。
1181783497276652981
は線形合同生成器のための良いquot;merit"をもたらす数であると主張しています。 この数は単に Java に間違ってコピーされたのでしょうか? また
181783497276652981
は許容できる長さを持つのでしょうか?
また、なぜ
8682522807148012
が選ばれたのか?
どちらの番号もネットで検索しても説明はなく、ただただ
このページ
を削除したことにも気づきました。
1
の前にある
181783497276652981
.
この2つの数字と同じように機能する他の数字を選ぶことはできたでしょうか? その理由またはそうでない理由を教えてください。
どのように解決するのですか?
-
この数字は単にJavaに間違ってコピーされただけなのでしょうか?
はい、タイプミスのようです。
-
181783497276652981は受け入れられるメリットがあるのでしょうか?
これは論文で紹介されている評価アルゴリズムを使って判断することができます。しかし、quot;original"の数値のメリットはおそらくもっと高いでしょう。
-
そして、なぜ8682522807148012が選ばれたのでしょうか?
ランダムなようです。コードが書かれたときのSystem.nanoTime()の結果かもしれません。
-
この2つの数字と同じように機能する他の数字を選ぶことはできたのでしょうか?
すべての数字が同じように良いとは限りません。だから、ダメなのです。
シード戦略
JRE の異なるバージョンと実装の間には、デフォルトのシードスキーマに違いがあります。
public Random() { this(System.currentTimeMillis()); }
public Random() { this(++seedUniquifier + System.nanoTime()); }
public Random() { this(seedUniquifier() ^ System.nanoTime()); }
最初のものは、複数のRNGを連続して作成した場合、受け入れられません。もしそれらの作成時間が同じミリ秒の範囲に収まるなら、完全に同一のシーケンスを与えることになります。(同じシード => 同じシーケンス)
2つ目は、スレッドセーフではありません。複数のスレッドが同時に初期化した場合、同一のRNGを得ることができます。さらに、後続の初期化の種は相関する傾向があります。システムの実際のタイマー分解能に依存しますが、シード配列は線形に増加します (n、n+1、n+2、...)。で述べたように ランダム シードはどの程度異なる必要がありますか? および参照された論文 疑似乱数生成器の初期化におけるよくある不具合 という論文では、相関のあるシードは、複数の RNG の実際の配列の間に相関を発生させることができると述べています。
3 番目のアプローチでは、スレッドやその後の初期化においても、ランダムに分散された、したがって相関のないシードを作成します。 そのため、現在の java docs:
このコンストラクタは乱数生成器の種を このコンストラクタの他のどの呼び出しとも異なる可能性が非常に高い値です。 を設定します。
は "across threads" と "uncorrelated" によって拡張される可能性があります。
シード配列の品質
しかし、シードシーケンスのランダム性は、基礎となるRNGと同じくらい良いものでしかありません。 このJava実装でシードシーケンスに使用されているRNGは、c=0、m=2^64の乗法線形合同生成器(MLCG)を使用しています。(係数2^64は64ビット長整数のオーバーフローによって暗黙に与えられます) cが0であることと、2乗剰余であることから、品質(周期長、ビット相関など)が制限される。論文にあるように、全体のサイクル長以外に、各ビットは独自のサイクル長を持ち、それは下位のビットほど指数関数的に減少する。したがって、下位ビットは繰り返しパターンが小さくなる。(実際のRNGでは48ビットに切り詰められる前に,seedUniquifier()の結果はビット反転されるはずです)
しかし、これは高速です。不必要な比較ループや設定ループを避けるために、ループ本体は高速であるべきなのです。足し算、割り算をせず、掛け算だけという、この特殊なMLCGの使い方は、おそらくこのためでしょう。
そして、言及された論文は、1181783497276652981として、c=0およびm=2^64のための良い"multipliers"のリストを提示する。
すべてにおいて。JRE-developersの努力の賜物です。) しかし、typo があります。 (しかし、誰かが評価しない限り、先頭の 1 が欠けていることが実際にシード RNG を向上させる可能性もあります)。
しかし、いくつかの倍率は確実に悪くなっています。 "1" は一定のシーケンスを導きます。 "2"は1ビット動くシーケンスになります(何らかの相関があります)。 ...
RNG の配列間相関は、複数のランダム配列がインスタンス化され、さらに並列化される (モンテカルロ) シミュレーションに実際に関連しています。したがって、良いシーディング戦略は、独立したシミュレーションを実行するために必要です。そのため、C++11 標準では、"seeding" という概念を導入しています。 シードシーケンス という概念を導入し、相関のないシードを生成できるようにしました。
関連
-
Git Pull Failed マージされていないファイルがあるため、Pull できません。
-
アクセス制限の解決方法: ---- in Java
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] JavaScriptでランダムな文字列/文字を生成する
-
[解決済み] JavaScriptで特定の範囲のランダムな整数を生成する?
-
[解決済み] 乱数(int)を生成する方法を教えてください。
-
[解決済み] JavaScriptで2つの数値の間の乱数を生成する
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み】大文字と数字を含むランダムな文字列の生成
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
実行中にEclipseがポップアップする A Java Exception has occurred
-
アクセス制限です。タイプ 'JPEGCodec' は API ではない ☞My Blog Github ☜ ホームページを見る
-
型に解決できない エラー解決
-
Springの設定でxsdファイルのバージョン番号を設定しない方が良い理由
-
SLF4J: クラス・パスに複数のSLF4Jバインディングが含まれています。
-
ApplicationContextの起動エラーです。条件レポートを表示するには、アプリケーションを'de'で再実行します。
-
API の戻り値を処理するために ResponseEntity を使用する
-
Java JDKのダイナミックプロキシ(AOP)の使用と実装の原理分析
-
テストが空であるかどうかを判断するためのオプションの処理
-
ApiModel と @ApiModelProperty の使用法