Javaエバンジェリストがお届けするホットな話題
5分でわかる今週のJava ホットトピック
水曜日 3 07, 2007
今週のクイズ(4) Again!:シャッフル

前回のクイズ シャッフル、ですが、今気づけば肝心の問題の部分が何か、が良くわからない状態になっていました。大変失礼いたしました。もう一度問題をご紹介します。

シャッフル/シャッフル/シャッフル

public class Shuffle {
public static <T> void shuffle(T[] a) {
Random r = new Random();
for (int i = 0; i < a.length; i++) {
int j = r.nextInt(a.length);
int k = r.nextInt(a.length);

swap(a, j, k);
}
}
public static <T> void swap(T[] a, int i, int j) {
if (i != j) {
T tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}

こ のプログラムは配列の内容をランダムに再配置するというプログラムです。ためしに Integer[] a = {1, 2, 3} という配列をこのプログラムを使って6,000回シャッフルし、その組み合わせの出現数を数えてみると次のようになりました。

[1, 2, 3]=1129, [1, 3, 2]=1029, [2, 1, 3]=1021, [2, 3, 1]=853, [3, 1, 2]=886, [3, 2, 1]=1082}

さて、この結果から判断できるのは次の4つのうちどれでしょうか。

  • (1) 乱数なのでこの程度の偏りは偶然。もう一度実行すると別のパターンに偏る。
  • (2) java.util.Random の乱数は周期性があるので、特定のパターンに偏りが出る。
  • (3) java.util.Random の代わりに java.security.SecureRandom を使うと偏りは小さくなる。
  • (4) このアルゴリズムでは常に特定のパターンに偏る。 

投稿されたコメント:

線形合同法のjava.util.Randomではjとkの値が0~2では乱数分布に広がりがなく、forステートメント内でのswapメソッドでの配列要素の交換も画一的です。よってjava.security.SecureRandomのgetInstance()でもっと用途に適したアルゴリズムを指定したいところです。

Posted by jyagi on 3月月 10日, 2007年 at 10:07 午後 JST #

コメント
コメントは無効になっています。
過去の記事
« 12月 2009
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
今日
Click me to subscribeこのブログを購読する(RSS)
検索

リンク
 

Today's Page Hits: 71