先週は経路の探索を行うダイクストラ法を学習しました。
ダイクストラ法において、疎なグラフ(つまりノード数に比べて エッジの数が少ないグラフ)を扱う場合には、 ノード間の接続関係を隣接行列で表現するよりも隣接リストで 表現すると、計算量のオーダーは変わりませんが、 実際の計算速度が速くなることが期待されます。
すなわち、ダイクストラ法において
Priority Queueは「ヒープ」と呼ばれる、 「特定のデータへのアクセスがO(log n)で可能」 なデータ構造です。
JavaではPriorityQueueクラスが標準ライブラリにありますので、 これを使ってPriority First Searchを記述してみましょう。
ノードの数が多い疎なグラフ routedata12.txt に対して、実行させた例を示します。 ここで用いた routedata12.txt は http://ynitta.com/class/algoC/routedata12.txt から入手できます。
routedata12.txt(一部) |
|
RunPFSearch.javaの実行例 |
|
RunDijkstra.java ではノードの接続関係を隣接行列で表現しているので、 メモリを多く使い、しかも実行時間が遅くなっています。 java処理系のデフォルトのヒープの大きさでは最後まで計算できないので、 4.0Gバイトまで拡張して計算させています。 計算にはかなり時間が掛かりました。
Priority First Searchを用いたRunPFSearch.java では、 ノードの接続関係を隣接リストで表現し、 未確定ノードの探索に高速化を施しているので 使用メモリも少く、実行時間も高速になっています。 デフォルトのヒープ(=ここでの「ヒープ」という用語は 「プログラムが実行中にデータを置くために確保したメモリ領域」のことです。 「ヒープ」という用語には2種類の異なる意味があるので注意が必要です。) の大きさで計算が可能で、 しかも実行時間は高速です。
以下の演習で routedata11.txtやroutedata12.txt を入力として RunDijkstra.javaを実行する場合は、 java のヒープの大きさを広げて下さい。
[実行例] time (java -Xmx4300M RunDijkstra < routedata11.txt)
また、プログラムの実行時間の表示に関してですが、 Mac上のtimeコマンドでは次のような表示となります。
real 0m1.611s ←この値を採用して下さい user 0m0.015s system 0m0.000sこのように3種類の値が表示されるはずですが、realとして表示されている 値を採用して下さい。mは分、sは秒を表していますので、上の例では 1.611秒ということになります。
作成したプログラムが正しく動作することを確認したら、それぞれの 提出先に提出しなさい。
提出した後は、正しく提出されていることを http://ynitta.com/class/algoC/local/handin/ で必ず確認しておいて下さい。
課題提出〆切は次回の講義の開始時刻です。
提出ファイル | PFSearch.java |
---|---|
コメント欄: | routedata11.txt, routedata12.txt をそれぞれ入力ファイルとしたときの、RunDijkstra.javaとRunPFSearch.javaの実行時間の比 |
提出先: | 「宿題提出Web:アルゴリズムc:課題4a」 http://ynitta.com/class/algoC/local/handin/up.php?id=kadai4a |
PFSearch.javaの欠けている部分に適切なコードを書きなさい。
RunDijkstra.javaを http://ynitta.com/class/algoC/routedata11.txt および http://ynitta.com/class/algoC/routedata12.txt に対して動作させて time コマンドで時間を測って下さい(これをaとします)。 ヒープ領域を広げないと「メモリが足りない」という 例外が起きて計算が途中で終了してしまい実行時間が 正しく計測できないので注意して下さい。
さらに、RunPFSearch.javaを http://ynitta.com/class/algoC/routedata11.txt および Http://ynitta.com/class/algoC/routedata12.txt に対して動作させて time コマンドで実行時間を測って下さい(これをbとします)。 ここで、「実行時間」とはtimeコマンドの出力行の最初の値 (realの左に表示されている値)とします。
RunPFSearchはRunDijkstraの何倍速いですか? 自分で測定した結果から、同じ入力に対する a/b をそれぞれ計算して答えて下さい。