13

Java/Android でポーカー カードのデッキをシャッフルする必要がある場合はCollections.shuffle(List<?> list)、もちろん を使用します。私は今までこれを行ってきましたが、結果は受け入れられるように見えました。しかし、そうではありません。

この論文で概説されているように、52 あります。52 枚のカードのポーカー デッキの可能なユニークなシャッフル。これは約 2^226 になります。

しかし、デフォルトでは48 ビットのシードCollections.shuffle(List<?> list)を使用するため、2^48 の一意のシャッフルしか作成できません。これは、考えられるすべてのシャッフルのほんの一部です!new Random()3.49*10^(-52)

では、正しい方法でカードをシャッフルするにはどうすればよいでしょうか。

を使い始めSecureRandomたけど、やっぱりこれでいいの?

List<Card> cards = new ArrayList<Card>();
...
SecureRandom secureRandom;
try {
    secureRandom = SecureRandom.getInstance("SHA1PRNG");
}
catch (NoSuchAlgorithmException e) {
    secureRandom = new SecureRandom();
}
secureRandom.nextBytes(new byte[20]); // force SecureRandom to seed itself
Collections.shuffle(cards, secureRandom);
4

5 に答える 5

4

特定のスターティング アレンジメントから 2 48 の異なるハンドしか得られない場合がありますが、毎回同じアレンジメントで開始する必要はありません。

おそらく、デッキ (ポーカー ハンド、ブラックジャックなど) が完成した後は、不確定な順序になり、それらの再配置のいずれかが適切になります。

また、プログラムを開始するたびに決まった配置から開始することが心配な場合は、終了時に順序を保持し、次回は再ロードしてください。

いずれにせよ、2 48は依然として膨大な数の可能性 (約 280,000,000,000,000) であり、カード ゲームには十分すぎるほどです。あなたが深刻な統計学者や暗号学者でない限り、あなたが持っているものは問題ないはずです.

于 2013-05-03T14:52:58.603 に答える
2

を使用していますがSecureRandom、まだ限定状態です。その入力シードの範囲が 52 より小さい限り! 完全にランダムにすることはできません。

実際、SHA1PRNGは 160 ビット シードされています。つまり、まだ十分にランダムではありません。このリンクをたどってください。何年も前に、と呼ばれるサードパーティのライブラリを使用して解決策がありますUnCommons Math

于 2013-05-03T14:47:05.067 に答える
1

真のランダム性が必要な場合は、疑似乱数ジェネレーターをスキップして、大気圏ノイズから生成された乱数などのより良いものを使用できます。

random.orgは、その方法で生成された乱数を独自のソフトウェアに統合するためのAPIを提供しています。

于 2013-05-03T15:23:51.570 に答える
0

リンクした記事から回答を盗む:

START WITH FRESH DECK
GET RANDOM SEED
FOR CT = 1, WHILE CT <= 52, DO
X = RANDOM NUMBER BETWEEN CT AND 52 INCLUSIVE
SWAP DECK[CT] WITH DECK[X]

乱数ジェネレーターは優れたものであり、できればハードウェアを使用して、予期せずに選択した 64 ビット シードを使用する必要があります。

于 2013-05-03T14:53:30.623 に答える
0

デッキを本当にシャッフルする方法は?

いくつかのシャッフル手法があります。

いずれか (ストリッピング/オーバーハンド):

Cut the deck in two
    Add a small (pseudorandom) amount of one half to the front of the front of the other
    Add a small (pseudorandom) amount of one half to the front of the back of the other
Do this until one hand is empty
Repeat

または (リフル):

Cut the deck in two
    Set down a small (pseudorandom) portion of one half
    Set down a small (pseudorandom) portion of the other
Do this until both hands are empty, and you have a new deck
Repeat

上記の私のリンクで詳しく説明されているように、これに加えてさらに多くのことがあります。


それにもかかわらず、非常に多くの組み合わせがあるため、完璧なシャッフル アルゴリズムでさえ、宇宙が存在する時間内にすべて2*10^50の順列を探索し終えるために、1 秒あたりに一意の順列を探索するマシンが必要になります。最新のコンピューターは、2019 年までに 1 ExaFLOPs ( 1 秒あたりの浮動小数点演算) しか達成できないと予測されています。1*10^18

人間のシャッフルもその範囲の可能性を探求することはありません.そしてあなたは、(最も基本的なレベルで)人間のシャッフルをシミュレートしていると思いますよね?ディーラーが、インクリメンタルに並べられたデッキを 1 回のシャッフルで降順にシャッフルできる可能性が高いと思いますか? 1回のシャッフルで、奇数の前に偶数のランクでデッキを分割するには?

2^48同じ方法で継続的にシードしない限り、各シャッフルでその位相空間の(非常に)小さなサブセクション(可能な乱数)に自分自身を制限することは容認できないとは思いません.

52 枚のカード デッキのカードの順序は、正確に 52 の階乗 (省略形で 52 と表されます!) あります。これは、およそ 8×10 67の可能な順序、つまり具体的に は次のとおり80,658,175,170,943,878,571,660,636,856,403,766,975,289,505,440,883,277,824,000,000,000,000です。
この数字の大きさは、ランダムに選択され、真にランダム化された 2 つのデッキが、宇宙の歴史においてさえ、同じになる可能性が非常に低いことを意味します。ただし、ランダム化されたデッキ内のすべてのカードの正確な順序は予測できませんが、十分にランダム化されていないデッキについて確率論的な予測を行うことは可能かもしれません.
ウィキペディア

また、1992 年に Bayer & Diaconis がデッキを適切にランダム化するには 7 回のシャッフルが必要であることを証明したことも注目に値します

于 2013-06-29T00:30:48.913 に答える