ビンソートも分布数え上げソートも、キーがある範囲にある場合にだけ利用 可能です。すなわち、キーの種類が多すぎると使うことができません。
キーの種類が多い場合は、キーを分割して、小さいキー(サブキー, subkey)に対する 「安定な」ソートを(下の桁から上の桁へと)繰り返し適用することによって ソートを行います。 これが「基数ソート(Radix Sort)」です。
サブキーでソートするアルゴリズムは安定であれば何でも構わないのですが、 $O(n)$ のアルゴリズム、つまり分布数え上げソートを使うのが普通です。 キーの分割は、分布数え上げソートの実行回数と作業領域の大きさを 考慮して決めることになります。
下の RadixSortData クラスは、キーの最大ビット幅がデフォルトでは 16ビットになっています。すなわち、デフォルトではキーは $0$ 〜 $65535$ ($= 2^{16}-1$)の値を取ることができます。 この値はsetKeyBitWidth()メソッドで変更できます。
下の RadixSort クラスは、サブキーのビット幅がデフォルトでは 4ビットになっています。すなわち、デフォルトではキーを 4ビットずつのサブキーに分割してソートすることになります。 この値はsetSubKeyBitWidth()メソッドで変更できます。
radixsortdata0.txt |
|
RunRadixSort.javaの実行例 |
|
出力がわかりにくいので、わかりやすいように縦に並べてみました。 下の桁から4ビットずつ選んではソートしている様子がわかると思います。 この例では、16bitのキーを4bitずつに分割してソート繰り返すので、 全体としては4回の繰り返しでソートが終了します。
ソート前 | Pass 1 | Pass 2 | Pass 3 | Pass 4 |
2f38:要素0 2fb7:要素1 9328:要素2 a400:要素3 000f:要素4 0002:要素5 0844:要素6 ef85:要素7 289a:要素8 2f30:要素9 |
a400:要素3 2f30:要素9 0002:要素5 0844:要素6 ef85:要素7 2fb7:要素1 2f38:要素0 9328:要素2 289a:要素8 000f:要素4 |
a400:要素3 0002:要素5 000f:要素4 9328:要素2 2f30:要素9 2f38:要素0 0844:要素6 ef85:要素7 289a:要素8 2fb7:要素1 |
0002:要素5 000f:要素4 9328:要素2 a400:要素3 0844:要素6 289a:要素8 2f30:要素9 2f38:要素0 ef85:要素7 2fb7:要素1 |
0002:要素5 000f:要素4 0844:要素6 289a:要素8 2f30:要素9 2f38:要素0 2fb7:要素1 9328:要素2 a400:要素3 ef85:要素7 |
作成したプログラムが正しく動作することを確認したら、それぞれの 提出先に提出しなさい。
提出した後は、正しく提出されていることを http://ynitta.com/class/algoB/local/handin/ で必ず確認しておいて下さい。
課題提出〆切は次回の講義開始時刻です。
提出ファイル | RadixSort.java |
---|---|
コメント欄: | RunRadixSort.javaに例と同じデータを与えた時の出力 |
提出先: | 「宿題提出Web:アルゴリズムB:課題8a」 http://ynitta.com/class/algoB/local/handin/up.php?id=kadai8a |
上記の RadixSortData.java, RadixSort.java, RunRadixSort.java を自分で入力し、 動作させてみましょう。 途中経過を表示させてみて、動作を確実に理解して下さい。
RadixSortDataクラスについて。
RadixSortクラスについて
提出ファイル | RunRadixSort2.java |
---|---|
コメント欄: | http://ynitta.com/class/algoB/radixsortdata2.txt を入力として与えたときの出力と実行速度。 |
提出先: | 「宿題提出Web:アルゴリズムB:課題8b」 http://ynitta.com/class/algoB/local/handin/up.php?id=kadai8b |
入力として、40bitの整数が複数個与えられる。 ただし、これらの整数値は10桁の16進数で表現されている。
与えられたデータのうちから、小さい方から3個と、大きい方から 3個を選び表示するプログラム RunRadixSort2.java を作成しなさい。 1行に1個の数字を、小さい順に10桁の16進数として 出力するものとする。
ソートする際には SubKeyのビット幅を8bitに設定した状態でRadixSortクラスの sortメソッドを利用することを条件とします。
入力データの形式は次の通り。
$N$
$H_{1,1} ~~ H_{1,2} ~~ H_{1,3} ~~ \cdots ~~ H_{1,10}$
$H_{2,1} ~~ H_{2,2} ~~ H_{2,3} ~~ \cdots ~~ H_{2,10}$
$\cdots$
$H_{N,1} ~~ H_{N,2} ~~ H_{2,3} ~~ \cdots ~~ H_{N,10}$
$N$ はデータの個数である。 $H_{i,j}$ は $0 \mbox{〜} 9$, $a \mbox{〜} f$の間の1文字を表す。 すなわち、$H_{i,1} ~~ H_{i,2} ~~ \cdots ~~ H_{i,10}$ の並びは長さ10の文字列であり、10桁の16進数を表す。
$6 \leqq N \leqq 1000000$が成り立っていると仮定して構わない。
$0000000000_{\mbox{(16進数)}} \leqq H_{i,1} ~~ H_{i,2} ~~ \cdots ~~ H_{i,10} \leqq ffffffffff_{\mbox{(16進数)}}$
100万個の40bitデータが http://ynitta.com/class/algoB/radixsortdata2.txt に用意されている。 これを入力として与えたときの出力と実行時間を答えなさい。
[注意1]10桁の16進数は40bitなので、int やIntegerでは扱えないことに注意して下さい。 longや Longを使うことになります。
[注意2]RadixSortクラスは RadixSortDataオブジェクトの配列をソートしますが、 今回はRadixSortDataオブジェクトの key だけに着目すればよいので、 生成したRadixSortDataオブジェクトの dataフィールドには元の16進数 の文字列表現を入れておくものとします。
[注意3]CPUにもよりますが、radixsortdata2.txtの処理は数秒(2〜4秒)程度で終わるはずです。
[注意4]環境によってはJava実行環境のHeapが足りなくなってエラーを起こすことがあります。 その場合はHeap空間を広げて実行させます。 java の -Xmxオプションでヒープの最大サイズを指定します。
[使用例]ヒープの最大値を128Mバイトに設定して実行する例 $ time (java -Xmx128M RunRadixSort2 < radixsortdata2.txt)
radixsortdata1.txt |
|
RunRadixSort2.javaの実行例 |
|
Keyの長さを40ビット、SubKeyの長さを8ビットに設定して基数ソートを行ったので、 5回SubKeyによるソートを行っています。 16進数で2桁ずつ、すなわち8ビットずつに分割されたキーで ソートされていく様子を下の表に示します。
初期状態 | Pass 1 | Pass 2 | Pass 3 | Pass 4 | Pass 5 |
39ae5489f0 9912c8a11d 00be1ffc83 3504ed8352 5db6b7f7b4 99d036bbf4 88ba7e51cb ac0df9dc08 65cd216015 7e3f816f94 |
ac0df9dc08 65cd216015 9912c8a11d 3504ed8352 00be1ffc83 7e3f816f94 5db6b7f7b4 88ba7e51cb 39ae5489f0 99d036bbf4 |
88ba7e51cb 65cd216015 7e3f816f94 3504ed8352 39ae5489f0 9912c8a11d 99d036bbf4 ac0df9dc08 5db6b7f7b4 00be1ffc83 |
00be1ffc83 65cd216015 99d036bbf4 39ae5489f0 88ba7e51cb 7e3f816f94 5db6b7f7b4 9912c8a11d 3504ed8352 ac0df9dc08 |
3504ed8352 ac0df9dc08 9912c8a11d 7e3f816f94 39ae5489f0 5db6b7f7b4 88ba7e51cb 00be1ffc83 65cd216015 99d036bbf4 |
00be1ffc83 3504ed8352 39ae5489f0 5db6b7f7b4 65cd216015 7e3f816f94 88ba7e51cb 9912c8a11d 99d036bbf4 ac0df9dc08 |