Week 9 (2025/6/20)¶
今週の目的
データをグラフに格納する。
今週のキーワード
- グラフのデータ構造(エッジリスト、隣接リスト)
- 開放除去(エッジの削除)
- 点の除去
今回はグラフのデータ構造の一つである隣接リストを実装する。 隣接リストとは、各ノードの近傍をリストとして表現したデータ構造である。 近傍とは同じノードに隣接するノード(以降、隣接ノード)の集合である。 隣接リストでは、各ノードの近傍を隣接ノードとそれに接続するエッジのペアのリストとして表現する。
課題1:グラフを作る¶
隣接リストのデータ構造を実装したGraph
クラスを定義せよ。なお、グラフの各ノードの近傍は、隣接ノードとそれに接続するエッジからなるNeighbor
インスタンスのリストで実装する。また、全てのノードの近傍をまとめるのに辞書(キーがノードID、値が近傍)を用いよ。
Graph
クラスとNeighbor
クラスの仕様は、以下の通りである。
Graphクラス
class Graph()
隣接リストで実装したグラフのクラス
インスタンス変数
- node_list: グラフ上のノードリスト(辞書:key=ノードID(文字列), value=近傍(
Neighbor
インスタンスのリスト)) - num_nodes: グラフ上のノード数(整数)
- num_edges: グラフ上のエッジ数(整数)
add_node(id)
グラフにノードを追加するメソッド
パラメータ
- id: 追加するノードのID(文字列)
add_directed_edge(sid, tid, label)
ノードsid
からノードtid
にラベルlabel
付きの有向エッジを追加するメソッド
パラメータ
- sid: 追加するエッジの始点のノードID(文字列)
- tid: 追加するエッジの終点のノードID(文字列)
- label: 追加するエッジのラベル(文字列)
add_undirected_edge(sid, tid, label)
ノードsid
とノードtid
にラベルlabel
付きの無向エッジを追加するメソッド
パラメータ
- sid: 追加するエッジの一端のノードID(文字列)
- tid: 追加するエッジの他端のノードID(文字列)
- label: 追加するエッジのラベル(文字列)
get_node_list()
グラフのノードリストを返すメソッド
返り値
- ノードリストを返す(辞書:key=ノードID(文字列), value=近傍(
Neighbor
インスタンスのリスト))
get_neighborhood(id)
ノードid
の近傍を返すメソッド
パラメータ
- id: 近傍取得の対象となるノードID(文字列)
返り値
- 近傍を返す(
Neighbor
インスタンスのリスト)ただし、指定したid
のノードが無ければNone
を返す
get_num_nodes()
グラフのノード数を返すメソッド
返り値
- ノード数を返す(整数)
get_num_edges()
グラフのエッジ数を返すメソッド
返り値
- エッジ数を返す(整数)
print_graph()
グラフの隣接関係を表示するメソッド
Neighborクラス
class Neighbor()
隣接ノードのクラス
インスタンス変数
- id: 隣接ノードのID(文字列)
- label: 隣接ノードと接続するエッジのラベル
さらに、実装したGraph
クラスのインスタンスを用いて、kyotocitybus_line.dat
のデータを読み込み、グラフを生成せよ。kyotocitybus_line.dat
は、「バス停ID バス停ID 京都市 路線名」のフォーマットで表されたエッジリストである。
課題2:グラフのエッジを削除する¶
課題1で作成したGraph
クラスに、グラフのエッジを削除するremove_undirected_edge
メソッドを定義せよ。なお、グラフのエッジは両端のノードとラベルで一意に定まるとする。ラベルがNone
の場合は、指定した両端のノードの間のエッジを全て削除すること。
Graph
クラスのremove_undirected_edge
メソッドの仕様は、以下の通りである。
remove_undirected_edgeメソッド
remove_undirected_edge(sid, tid, label = None)
グラフからノードsid
とノードtid
の間のエッジを削除するメソッド
パラメータ
- sid: 削除するエッジの一端のノードID(文字列)
- tid: 削除するエッジの他端のノードID(文字列)
- label: 削除するエッジのラベル.省略可(文字列)
さらに、課題1でkyotocitybus_line.dat
のデータを読み込んだGraph
インスタンスから、ED01_1914とED01_1925間でM1号系統のラベルが付与されたエッジをremove_undirected_edge
メソッドで削除せよ。
ヒント
課題1で作成したグラフは無向グラフのため、両向きのエッジ(始点と終点が逆のもの)が存在するので両方とも削除すること。具体的には、指定した始点のノードの近傍から終点のノードを削除するだけでなく、終点のノードの近傍から始点のノードも削除すること。
課題3:グラフのノードを削除する¶
課題1で作成したGraph
クラスに、グラフのノードを削除するremove_node
メソッドを定義せよ。
なお、グラフのノードはノードIDで一意に定まるとする。
Graph
クラスのremove_node
メソッドの仕様は、以下の通りである。
remove_nodeメソッド
remove_node(id)
グラフからノードid
を削除するメソッド
パラメータ
- id: 削除するノードのノードID(文字列)
さらに、課題1でkyotocitybus_line.dat
のデータを読み込んだGraph
インスタンスから、ED01_1914のノードをremove_node
メソッドで削除せよ。
ヒント
ノードの削除だけでなく、接続しているエッジも全て削除しなければならないことに注意せよ。具体的には、ノードリストから指定したノードIDに対応する要素を削除するだけでなく、隣接ノードの近傍内の当該ノードも削除すること。