2011-05-01 7 views
2

質問がありますが、Javaで2^21のランダムな一意の数値を生成するためにどのようなアルゴリズムを使用できますか? math.random以外に乱数を生成する別のライブラリがjavaにありますか?Javaで何百万という非繰り返し乱数を生成する

ありがとうございます!

+0

サンプルサイズはどのくらいですか?明らかに2^21より大きい... –

+0

セットがマテリアライズドでユニークである必要がある場合、1から2^21までの数字のシャッフルが機能します(メモリが大量に必要になります)。 –

+3

ユニークであれば、本当にランダムではない、今はそれらですか?あなたのリストを見ると、次の数字を正確に予測することができます。範囲のサイズがセットのサイズによって制限されている場合、最後のセットで100%可能性のある予測があります。これは本当にランダムではありません! – corsiKa

答えて

2

重要な問題は、あなたが「数字」で何をミーンんさを見てみましょうか?一般的に、しかし、この問題は最初の部分は、第二部は、によって解決することができる 簡単です 「番号のリストを生成するランダムな順序にこれを入れて、それらの最初の2^21を取る」によって解決することができる

fisher yates algorithm 実際の問題は、非常に大きなスペースを使いたい場合です。 データ構造を使用して、外見は配列のように見えますが、内部的にはハッシュテーブルベースの疎配列表現を使用して表されます。さらに、セルからの読み込みを試みているときに、ハッシュで何かをヒットしなかった場合は、単にそのセルのインデックスを返します。

変更したフィッシャーイェーツこのレイジーアプローチは、ランダム、非を生成index変数に対して2^21で停止し、index及びアレイの「長さ」(整数の数)

間の確率変数jを使用しますO(n)時間とO(n)空間の任意の種類の数の繰り返しリスト。ここでnは生成しようとしている配列の長さです。それがあなたができる最高です。あなたはカウンターを暗号化するためにFormat-Preserving Encryptionを使用することができフィッシャーイエーツhttp://en.wikipedia.org/wiki/Fisher-Yates_shuffle

0

の説明については

。あなたのカウンターは0から上向きになり、暗号化はあなたの好きな基数と幅の一見無作為な値に変えます。

ブロック暗号は、通常、例えば、 64または128ビット。しかし、Format-Preserving Encryptionでは、AESのような標準的な暗号を取って、必要な基数と幅(例えば、基数2、幅21のアルゴリズム)を使って、より狭い幅の暗号を作ることができます暗号は堅牢です。

(暗号アルゴリズムが1:1マッピングを作成するため)衝突がないことが保証されています。また可逆(2方向マッピング)なので、結果の数値を取り、始めたカウンター値に戻ることができます。

AES-FFXは、これを達成するための標準的な提案方法の1つです。

関連する問題