Week 11 (2025/7/4)¶
今週の目的
グラフのデータを探索する。
今週のキーワード
- キューを用いた幅優先探索の実装
- 最短パスの発見
- スタックを用いた深さ優先探索の実装
今回はグラフの探索プログラムとして、幅優先探索と深さ優先探索を実装する。 幅優先探索は、グラフの各点において、隣接する未訪問点全てを連続して訪問していく探索である。 一方、 深さ優先探索は、隣接する未訪問点を一つ選び、前進操作を繰り返していく探索である。
課題1:幅優先探索で全てのノードを辿る¶
前々回実装したGraph
クラスを継承して、あるノードから全てのノードを幅優先探索で探索するsearch_with_BFS
メソッドを備えたGraphSearch
クラスを定義せよ。
GraphSearch
クラスの仕様は、以下の通りである。
GraphSearchクラス
class GraphSearch()
Graph
クラスのサブクラス
グラフ上のノードを探索することができるクラス
インスタンス変数
- busstops: バス停情報を格納するための辞書データ(key: バス停ID、value:
Stop
インスタンス)
search_with_BFS(start)
指定されたノードから幅優先探索で全ノードを探索し最長パスを出力するメソッド
パラメータ
- start: 幅優先探索の開始ノードのID(文字列)
trace_longest_path(parents)
最長のパスを表示するメソッド
パラメータ
- parents: 前進操作の出発点のノードと辿ったエッジを格納するための辞書データ(key: 前進操作の目的地のノード、value: 前進操作の出発地のノードと辿ったエッジのタプル)
また、GraphSearch
クラスには、バス停IDとバス停名を関連付けられるように、全てのバス停のStop
インスタンスを格納するリストをインスタンス変数(変数名:busstops
)として追加せよ。最後に、バスの路線データ(kyotocitybus_line.dat
)とバス停データ(kyotocitybus_stop.dat
)を読み込んでGraphSearch
インスタンスを作成し、このインスタンスを用いてED01_1914から全ノードを幅優先探索して、最長(最大ホップ数)のパスを出力せよ。
府道横大路まで37ホップ:立命館大学前 --[快速202号系統]--> 小松原児童公園前 --[快速202号系統]--> 衣笠校前 --[快速202号系統]--> 北野白梅町 --[快速202号系統]--> 西ノ京円町 --[快速202号系統]--> 西大路御池 --[快速202号系統]--> 西大路三条 --[11号系統]--> 西大路四条 --[快速202号系統]--> 西大路五条 --[快速202号系統]--> 西大路七条 --[快速202号系統]--> 西大路駅前 --[快速202号系統]--> 羅城門 --[特18号系統]--> 唐戸町 --[特18号系統]--> 千本十条 --[42号系統]--> 市民防災センター前 --[19号系統]--> 上鳥羽 --[19号系統]--> 鳥羽大橋北詰 --[19号系統]--> 城南宮 --[19号系統]--> 国道赤池 --[19号系統]--> 下鳥羽城ノ越町 --[19号系統]--> 国道下鳥羽 --[22号系統]--> 国道大手筋 --[20号系統]--> 八丁畷 --[22号系統]--> 羽束師志水町 --[22号系統]--> 菱川 --[南2号系統]--> 樋爪口 --[南2号系統]--> 免許試験場前 --[20号系統]--> 上樋爪 --[20号系統]--> 樋爪町 --[20号系統]--> 水垂町 --[20号系統]--> 宮前橋西詰 --[20号系統]--> 納所町 --[20号系統]--> 納所北城堀 --[20号系統]--> 納所岸ノ下 --[20号系統]--> 富ノ森 --[20号系統]--> 南横大路 --[20号系統]--> 洛水高校前 --[20号系統]--> 府道横大路
課題2:最短パスを見つける¶
課題1で作成したGraphSearch
クラスに、スタート地点から目的地までの最短パスを見つけるfind_shortest_path
メソッドを追加せよ。
find_shortest_path
メソッドの仕様は、以下の通りである。
find_shortest_pathメソッド
find_shortest_path(start, goal)
指定されたノードから目的地への最短パスを出力するメソッド
パラメータ
- start: 開始ノードのID(文字列)
- goal: 目的地ノードのID(文字列)
最後に、kyotocitybus_line.dat
とkyotocitybus_stop.dat
のデータを読み込んだGraphSearch
インスタンスを用いて、ED01_1914からED01_4089までの最短パスを出力せよ。
ヒント
幅優先探索は、スタート地点から1ホップで行ける全てのノード、2ホップで行ける全てのノード、...というように近いノードから網羅的に訪問していく探索である。したがって、指定した目的地までの最短パスを求めるには、目的地を見つけるまで幅優先探索を行えばよい。
課題3:深さ優先探索で全ノードを辿る¶
課題1で作成したGraphSearch
クラスに、あるノードから全部のノードを深さ優先探索で探索するsearch_with_DFS
メソッドを追加せよ。
search_with_DFS
メソッドの仕様は、以下の通りである。
search_with_DFSメソッド
search_with_DFS(start)
指定されたノードから深さ優先探索で全ノードを探索し最長パスを出力するメソッド
パラメータ
- start: 深さ優先探索の開始ノードのID(文字列)
最後に、kyotocitybus_line.dat
とkyotocitybus_stop.dat
のデータを読み込んだGraphSearch
インスタンスを用いて、ED01_1914から全ノードを深さ優先で探索し、最長(最大ホップ数)のパスを出力せよ。課題1と結果が異なることに注意せよ。
ヒント
深さ優先探索は、後退操作でどのノードに戻ればいいか記憶するために、前進操作時にスタックに出発地のノードを格納する必要がある。
中桂まで237ホップ:立命館大学前 --[快速202号系統]--> 小松原児童公園前 --[快速202号系統]--> 衣笠校前 --[快速202号系統]--> 北野白梅町 --[10号系統]--> 府立体育館前 --[10号系統]--> 等持院道 --[10号系統]--> 等持院南町 --[10号系統]--> 妙心寺北門前 --[10号系統]--> 京福妙心寺駅前 --[10号系統]--> 御室仁和寺 --[10号系統]--> 福王子 --[10号系統]--> 鳴滝本町 --[10号系統]--> 宇多野病院前 --[10号系統]--> ユースホステル前 --[10号系統]--> 山越 --[10号系統]--> 山越中町 --[11号系統]--> 山越東町 --[11号系統]--> 太秦開日町 --[11号系統]--> 広沢御所ノ内町 --[11号系統]--> 嵯峨中学前 --[11号系統]--> 嵯峨嵐山駅前 --[11号系統]--> 嵯峨瀬戸川町 --[11号系統]--> 嵯峨小学校前 --[11号系統]--> 野々宮 --[11号系統]--> 嵐山天龍寺前 --[11号系統]--> 嵐山 --[11号系統]--> 角倉町 --[11号系統]--> 下嵯峨 --[11号系統]--> 車折神社前 --[11号系統]--> 有栖川 --[11号系統]--> 生田口 --[11号系統]--> 帷子ノ辻 --[11号系統]--> 太秦開町 --[11号系統]--> 太秦広隆寺前 --[11号系統]--> 太秦東口 --[11号系統]--> 蚕ノ社 --[11号系統]--> 庚申前 --[11号系統]--> 山ノ内 --[11号系統]--> 西大路三条 --[11号系統]--> 西大路四条 --[11号系統]--> 四条御前通 --[11号系統]--> 四条中新道 --[11号系統]--> 壬生寺道 --[11号系統]--> 四条大宮 --[11号系統]--> 四条堀川 --[11号系統]--> 四条西洞院 --[11号系統]--> 四条烏丸 --[100円循環]--> 烏丸三条 --[100円循環]--> 烏丸御池 --[100円循環]--> 堺町御池 --[100円循環]--> 京都市役所前 --[100円循環]--> 河原町三条 --[100円循環]--> 四条河原町 --[11号系統]--> 四条京阪前 --[11号系統]--> 三条京阪前 --[5号系統]--> 役所前 --[10号系統]--> 河原町丸太町 --[10号系統]--> 裁判所前 --[10号系統]--> 烏丸丸太町 --[10号系統]--> 府庁前 --[10号系統]--> 堀川丸太町 --[10号系統]--> 丸太町智恵光院 --[10号系統]--> 千本丸太町 --[10号系統]--> 千本出水 --[10号系統]--> 千本中立売 --[10号系統]--> 千本今出川 --[206号系統]--> 千本上立売 --[206号系統]--> 乾隆校前 --[206号系統]--> 千本鞍馬口 --[206号系統]--> ライトハウス前 --[206号系統]--> 千本北大路 --[北8号系統]--> 佛教大学前 --[北8号系統]--> 旭ヶ丘 --[北8号系統]--> 紫野泉堂町 --[北8号系統]--> 常徳寺前 --[北8号系統]--> 下緑町 --[北8号系統]--> 上堀川 --[特37号系統]--> 東高縄町 --[特37号系統]--> 下鳥田町 --[特37号系統]--> 北大路堀川 --[特37号系統]--> 北大路新町 --[特37号系統]--> 北大路バスターミナル --[臨号系統]--> 出町柳駅前 --[203号系統]--> 百万遍 --[206号系統]--> 京大正門前 --[206号系統]--> 近衛通 --[206号系統]--> 熊野神社前 --[206号系統]--> 東山二条 --[206号系統]--> 東山仁王門 --[206号系統]--> 東山三条 --[206号系統]--> 知恩院前 --[206号系統]--> 祇園 --[207号系統]--> 東山安井 --[207号系統]--> 清水道 --[207号系統]--> 五条坂 --[207号系統]--> 馬町 --[207号系統]--> 東山七条 --[臨号系統]--> 博物館三十三間堂前 --[臨号系統]--> 七条京阪前 --[臨号系統]--> 七条河原町 --[臨号系統]--> 京都駅前 --[特81号系統]--> 塩小路高倉 --[特81号系統]--> 京都駅八条口アバンティ前 --[特81号系統]--> 大石橋 --[特81号系統]--> 札ノ辻 --[特81号系統]--> 十条竹田街道 --[特81号系統]--> 勧進橋 --[特81号系統]--> 深草下川原町 --[特81号系統]--> 竹田久保町 --[特81号系統]--> 竹田出橋 --[特81号系統]--> 七瀬川町 --[特81号系統]--> 竹田城南宮道 --[特81号系統]--> 西墨染通 --[特81号系統]--> 棒鼻 --[特81号系統]--> 住吉 --[特81号系統]--> 西丹波橋 --[特81号系統]--> 西板橋 --[特81号系統]--> 肥後町 --[特81号系統]--> 西大手筋 --[特81号系統]--> 京橋 --[特81号系統]--> 中書島 --[特81号系統]--> 下三栖 --[特81号系統]--> 横大路車庫前 --[南8号系統]--> 国道大手筋 --[南8号系統]--> 三栖公園前 --[南3号系統]--> 伏見警察署前 --[南3号系統]--> 油小路丹波橋 --[南3号系統]--> 城南宮東口 --[特南2号系統]--> パルスプラザ前 --[特南2号系統]--> 国道赤池 --[特南2号系統]--> 赤池 --[特南2号系統]--> 上鳥羽塔ノ森 --[特南2号系統]--> 久我 --[南1号系統]--> 菱妻神社前 --[南1号系統]--> 久我石原町 --[特13号系統]--> 東土川橋 --[特13号系統]--> 国道東土川 --[特13号系統]--> 久世殿城町 --[特13号系統]--> 下久世 --[特南1号系統]--> 久世大薮町 --[特南1号系統]--> 久世工業団地前 --[78号系統]--> 築山 --[13号系統]--> 久世橋西詰 --[特13号系統]--> 久世橋東詰 --[特18号系統]--> 石原団地前 --[特18号系統]--> 吉祥院嶋高町 --[特18号系統]--> 上鳥羽馬廻 --[特18号系統]--> 吉祥院池田町 --[特18号系統]--> 吉祥院蒔絵町 --[特18号系統]--> 上鳥羽村山町 --[特18号系統]--> 上ノ町 --[特18号系統]--> 五丁橋 --[特18号系統]--> 千本十条 --[特18号系統]--> 唐戸町 --[特18号系統]--> 羅城門 --[特18号系統]--> 東寺南門前 --[特18号系統]--> 九条大宮 --[特18号系統]--> 東寺東門前 --[特18号系統]--> 七条大宮 --[特33号系統]--> 七条堀川 --[特33号系統]--> 下京区総合庁舎前 --[16号系統]--> 八条油小路 --[16号系統]--> 八条大宮 --[16号系統]--> 六孫王神社前 --[16号系統]--> 東寺西門前 --[16号系統]--> 御土居 --[16号系統]--> 八条中学前 --[16号系統]--> 西寺前 --[16号系統]--> 洛陽工業高校前 --[208号系統]--> 西大路九条 --[208号系統]--> 西大路駅前 --[特13号系統]--> 西大路八条 --[特13号系統]--> 西大路七条 --[特33号系統]--> 月読橋 --[特33号系統]--> 大門町 --[特33号系統]--> 川勝寺 --[特33号系統]--> 桂大橋 --[特33号系統]--> 桂離宮前 --[特33号系統]--> 下桂 --[特南1号系統]--> 桂消防署前 --[特南1号系統]--> 桂高校前 --[特南1号系統]--> 莚田町 --[特南1号系統]--> 自衛隊前 --[特南1号系統]--> 川島六ノ坪町 --[特南1号系統]--> 高田町 --[西4号系統]--> 物集女 --[西4号系統]--> 第二回生病院前 --[西4号系統]--> 北福西町一丁目 --[西5号系統]--> 京都明徳高校前 --[西8号系統]--> 三ノ宮街道 --[西6号系統]--> 桂イノベーションパーク前 --[西6号系統]--> 京大桂キャンパス前 --[西6号系統]--> 桂御陵坂 --[西6号系統]--> 東桂坂 --[西6号系統]--> 峰ヶ堂町三丁目 --[西6号系統]--> 桂坂センター前 --[西5号系統]--> 桂坂口 --[西5号系統]--> 国道沓掛口 --[西5号系統]--> 新林池公園 --[西8号系統]--> 新林センター前 --[西8号系統]--> 新林公団住宅前 --[西8号系統]--> 東新林町 --[特西3号系統]--> 洛西バスターミナル --[西8号系統]--> 境谷大橋 --[特33号系統]--> 小畑川公園北口 --[特33号系統]--> 国道中山 --[特33号系統]--> 三ノ宮 --[特33号系統]--> 公会堂前 --[特33号系統]--> 樫原 --[69号系統]--> 月見ヶ丘 --[69号系統]--> 千代原口 --[73号系統]--> 平和台町 --[73号系統]--> 上桂前田町 --[73号系統]--> 上桂御正町 --[73号系統]--> 西大橋西詰 --[73号系統]--> 西京極 --[80号系統]--> 西京極運動公園前 --[80号系統]--> 光華女子学園前 --[84号系統]--> 葛野大路高辻 --[84号系統]--> 四条葛野大路 --[臨号系統]--> 京都外大前 --[臨号系統]--> 南広町 --[臨号系統]--> 日新電機前 --[臨号系統]--> 梅津段町 --[臨号系統]--> 長福寺道 --[臨号系統]--> 梅津西浦町 --[臨号系統]--> 梅ノ宮神社前 --[臨号系統]--> 松尾橋 --[29号系統]--> 松尾大社前 --[29号系統]--> 松室北河原町 --[29号系統]--> 苔寺道 --[29号系統]--> 松尾大利町 --[69号系統]--> 上桂駅前 --[69号系統]--> 上桂西居町 --[69号系統]--> 上野橋 --[70号系統]--> 上桂東ノ口 --[70号系統]--> 桂徳大寺 --[70号系統]--> 中桂