今日の講義で学ぶこと グラフとネットワーク(5) • グラフの探索 ~グラフの探索~ グラフの探索(search) – 深さ優先探索(DFS, Depth-First Search ) – 幅優先探索(BFS, Breadth-First Search ) 3/18 【定義】与えられたグラフの全ての点と辺 を、組織的に訪問することをグラフの探索 という。 代表的な探索手法としては、大別すると、次 の 2 つのアルゴリズムがある • 深さ優先探索(DFS, Depth-First Search ) • 幅優先探索(BFS, Breadth-First Search ) 【注】与えられたグラフ G = (V,E) の全域木が得られる。 また、O(|V|+|E|) で動作するように実装できる。 アルゴリズムの記述 2/18 5/18 探索アルゴリズムの枠組み 4/18 • 連結無向グラフ G = (V,E) を想定する • 探索中、各点は、未訪問 (unvisited) の状態から、訪問済 (visited) を経て、最後に走査済 (scanned) の状態へ変化する • 各辺は、未操作の状態から走査済へ変化する • 捜索は任意の 1 点 s を選び、その点を訪問済とすることか ら始まる • 各反復では、訪問済である点を 1 つ選びその点に接続する 未走査の辺を 1 つ選び走査する。走査した辺は走査済とし、 他方の端点は(未訪問なら)訪問済とする • ある点に接続する全ての辺が走査済になると、その点は走 査済となる • 全ての点と辺が走査済になった時点で探索は終了する アルゴリズム GraphSearch 入力:無向連結グラフ G = (V,E), 始点 s∈V 出力:訪問順序 V → Z+ , 探索木 T ⊆E 6/18 • NUM(v) は、点 v の訪問順序を与える番号 1. k:=1, NUM(s):=1, 全ての点と辺は未走査である。 また、s 以外の点は未訪問である。T:=φ • 訪問済の点 v に接続する 1 つの辺 (v,w) が 選ばれ、w が未訪問であった場合、辺 (v,w) を集合 T に記憶しておく 2. 訪問済の点が存在する限り、次の手順を反復する (存在しなければ、ステップ 3 へ進む) 訪問済の点 v を 1 つ選ぶ。v から接続する未走査の辺 の1つ {v,w} を選び、その状態を走査済とする。このとき、 点 w が未訪問であれば、 k:=k+1, NUM(w):=k, T:=T∪{{v,w}} とし、さらに w を訪問済とする。点 v について、接続す る辺が全て走査済であれば走査済とする。点 w について も同様 • 計算終了時、辺集合 T は G の全域木の一つ になっているので、これを s を根とする有 向木とみなす。この木を探索木(search tree)と呼ぶ。 3. NUM と T を出力したのち計算終了 7/18 深さ優先探索(Depth-First Search) • アルゴリズム GraphSearch のステップ 2 に おいて、訪問済みの点 v を選ぶ基準を「もっと も新しく訪問済になった点」としたもの • 縦型探索、線形探索 (linear search) 、後入れ先 出探索 (last-in-first-out search, LIFO 探索) とも 呼ばれる • ある点 v を訪問したとき、まだ未走査の辺が v に接続していればそちらへ探索を進め、未走査 の辺がない場合は、v へ最初に到達した辺を逆 戻りする、という挙動を繰り返すもの 8/18 アルゴリズム DFS 入力:無向連結グラフ G = (V,E), 始点 s∈V 出力:訪問順序 V → Z+ , 探索木 T ⊆E 1. v:=s, k:=1, NUM(s):=1, 全ての点と辺は未走査である。 また、s 以外の点は未訪問である。T:=φ 2. 訪問済の点 v を 1 つ選ぶ。 (a) v に接続する未走査の辺があれば 1 つ {v,w} を選び走査し、 その状態を走査済とする。このとき、点 w が未訪問であれば、 k:=k+1, NUM(w):=k, T := T∪{{v,w}} とし、さらに w を訪問済とし、 v :=w として 2 へ戻る。 点 w が訪問済であれば、そのまま 2 へ戻る。 (b) v から接続する辺が全て走査済ならば、点 v を走査済とした 後 v へ最初に訪問した点 (y,v)∈T を v から y へ後戻りする。 このとき、y = s ならばステップ 3 へ進む。 3. NUM と T を出力したのち計算終了。 【練習問題】次のグラフを、頂点 s を始点として 深さ優先探索(DFS)しなさい。 9/18 DFSの計算量 10/18 無向連結グラフ G = (V,E) を深さ優先探索 するとき ・時間計算量 O(|V| + |E|) ・空間計算量 O(|V|) 【注】大規模なグラフでは探索木のパスが長すぎ て探索が終わらないことがある。 ⇒ 深さ制限探索など 11/18 幅優先探索(Breadth-First Search) • アルゴリズム GraphSearch のステップ 2 に おいて、訪問済みの点 v を選ぶ基準を「もっと も過去に訪問済になった点」としたもの • 横型探索、先入れ先出し探索 (first-in-first-out search, FIFO 探索) とも呼ばれる • 訪問済の点を、いったん集合 Q に格納するが、 Q は先に入った順に取り出すという性質を持つ。 このようなデータ構造は、待ち行列 (queue) あるいは、先入れ先出しリスト (first-in-first-out list) と呼ぶことが命名の由来 12/18 アルゴリズム BFS 入力:無向連結グラフ G = (V,E), 始点 s∈V 出力:訪問順序 V → Z+ , 探索木 T ⊆E 1. v:=s, Q:=φ, k:=1, NUM(s):=1, 全ての点と辺は未走査。 また、s 以外の点は未訪問である。T:=φ 2. 現在の訪問点 v に対して次の手順を実行する。 (a) v に接続する未走査の辺があれば 1 つ {v,w} を選び走査し、 その状態を走査済とする。このとき、点 w が未訪問であれば、 k:=k+1, NUM(w):=k, T := T∪{{v,w}} とし、さらに w を訪問済とし、w を Q の最後尾へ格納して 2 へ戻る。点 w が訪問済であれば、そのまま 2 へ戻る。 (b) v から接続する辺が全て走査済のときは、Q:=φ ならば ステップ 3 へ進む。そうでなければ、Q の先頭の y を Q から 取り除き点 v :=y として 2 へ戻る。 3. NUM と T を出力したのち計算終了。 13/18 【練習問題】次のグラフを、頂点 s を始点として 幅優先探索(BFS)しなさい。 14/18 BFSの計算量 無向連結グラフ G = (V,E) を幅優先探索 するとき ・時間計算量 O(|V| + |E|) ・空間計算量 O(|V| + |E|) 【注】一般に、深さ優先探索の空間計算量の方が 幅優先探索の空間計算量よりもずっと小さい 深さ優先探索の空間計算量 O(|V|) 15/18 ナップサック問題(Knapsack problem) n = 2 の場合の探索木 ナップサックに、荷物を入れていく。 荷物は、n 個あり、それぞれの重さは a1, a2, …, an であるとする。ナップサックの容量を C と するとき、出来るだけ沢山の荷物を入れる にはどの品物を入れれば良いか? 【注1】ここでは、重さの意味で「沢山」 【注2】設定を変えた多くのバーションがある 【注3】クラスNPに属す典型的な問題 【例題】a1=5, a2=4, a3=3, C=8 の探索木を 幅優先探索しなさい。 a1 を入れる w=5 a2 を入れる w=9 3 1 w=5 4 w=4 5 2 17/18 w=0 a2 を入れない w=0 6 w>C 探索不要 (枝刈り) ○ ○ a1 を入れるか? × × a2 を入れるか? ○ × a1 だけをナップサックに入れる a1 を入れない a2 を入れる a2 を入れない 16/18 【練習問題】探索を最後まで実行し、 最適解を求めなさい。 【解答例】 18/18
© Copyright 2024 ExpyDoc