アルゴリズムとデータ構造 - kochi-tech.ac.jp...h i 図4.4.1 二重連結グラフ...

15
アルゴリズムとデータ構造 2012712酒居敬一([email protected] ) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2012/index.html 1

Upload: others

Post on 20-Jan-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

アルゴリズムとデータ構造

2012年7月12日

酒居敬一([email protected])

http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2012/index.html 1

Page 2: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

各種の連結性の判定 (249ページ)

•  連結の強さを表現する概念 •  無向グラフ

– 二重連結 – 二重連結成分

•  有向グラフ – 強連結 – 強連結成分

2

Page 3: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

H I

図4.4.1 二重連結グラフ

図4.4.2 関節点と二重連結成分

二重連結 (250ページ)

グラフから1つの頂点と その頂点を端点とする すべての辺を除いて得られる グラフを考えたとき、どの頂点を 除いた場合でもグラフが連結 グラフであるとき、元のグラフは 二重連結であるという。

B C

• 二重連結成分とは、二重  連結な部分グラフのこと。 • 取り除くと非連結になる  頂点を関節点という。

3

Page 4: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

関節点検出のアルゴリズム (251ページ)

•  前提条件 – 関節点が検出されなければ、二重連結。 – 深さ優先探索の結果の木を仮定して、 子孫・祖先・部分木という言葉を使う。

•  場合分け – 頂点が木の根の場合

• 子が2個以上ならその頂点は関節点である。 – 頂点が木の根ではない場合(次のページ)

• 着目する3頂点の位置で2つに場合分けする。 –  いずれもAB間・BC間・CA間の道について考える。 4

Page 5: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

BはAの祖先、CはAの子孫、 という位置関係の場合。

(図 4.4.3 a)

• もしAが関節点ならば、 以下の2つは同じことを言っている 1.  BC間の道が必ずAを通ること 2. Cを含む部分木の中にAの祖先への 逆辺がないこと

• 図のように逆辺 (点線で表示)があれば、  Aを経由せずにBC間を移動できるので、  この場合はAは関節点ではない。

5

Page 6: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

BはAの子孫、CもAの子孫、 という位置関係の場合。

(図 4.4.3 b)

• 図のように、BとCの双方が、Aの祖先と Aを経由せずに連絡できれば、Aは 関節点ではない。この場合、Aを経由 せずにBとCが連絡できる。 • BとCがAを通らないと連絡できない のは、どちらかの部分木にAより上の 祖先を指す逆辺がないからであり、 Aが関節点になっている。

6

Page 7: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

public class Biconnected<E> { private int sequence; private int visit(Node<E> node){ node.setSequence(++this.sequence); int min = this.sequence; for(Node<E> neighbor: node.getEdges()){ if(neighbor.getSequence() == 0){ int m = visit(neighbor); min = Math.min(min, m); boolean artic; if (node.getSequence() == 1) { artic = (neighbor.getSequence() != 2); } else { artic = (m >= node.getSequence()); } if(artic) System.out.println("頂点" + node.getValue() + "は関節点"); } else if (neighbor.getSequence() < min){ min = neighbor.getSequence(); } } return min; } public void search(Node<E> start){ this.sequence = 0; visit(start); } } 7

根の子が2個以上(順序数が2より大きい) ときは、根が関節点。

隣接する未訪問の頂点に関しては、 深さ優先探索なので探索する。 その結果、訪問順が付けられる。

自分(node)の子から、祖先への逆辺 がなければ、自分は関節点。

隣接する訪問済みの頂点に関しては、 より祖先へ向かう辺(逆辺含む)の先の 頂点の順序数を保持する。

深く探索していく過程で、より祖先寄りの祖先への逆辺を 調べながら進んでいる。

Page 8: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

public static void main(String[] args) { System.out.println("図4.4.2"); for(Node<Character> node: test_data2){ node.reset(); } nodeA.connect(nodeC); nodeA.connect(nodeD); nodeB.connect(nodeC); nodeB.connect(nodeD); nodeC.connect(nodeE); nodeD.connect(nodeF); nodeD.connect(nodeG); nodeF.connect(nodeG); nodeE.connect(nodeH); nodeE.connect(nodeI); new Biconnected<Character>().search(nodeA); }

8

図4.4.2 頂点Dは関節点 頂点Eは関節点 頂点Eは関節点 頂点Cは関節点

H I

B C

Page 9: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

図4.4.5 強連結グラフ

図4.4.6 強連結成分への分割

強連結 (255ページ)

有向グラフの各頂点から任意の 頂点へ至る道が存在するとき、 この有向グラフを強連結であるという。

部分グラフのうち、強連結であって、 しかもそれ以上頂点を追加すると 強連結でなくなるものを強連結成分という。

9

Page 10: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

強連結成分への分割アルゴリズム (256ページ)

ü 有向グラフの深さ優先探索の応用である。 ü 下降辺は強連結性に貢献しない。

ü 下降辺の両端の頂点について、祖先から子孫へ 木の辺から成る道がすでに存在する。

ü 上昇辺の両端の頂点は同じ強連結成分に属す。 ü 木の辺と上昇辺で閉路を作る。

ü 木の辺で下降し、上昇辺で上昇して元に戻れる。

ü 交差辺は、単純ではない。 ü 強連結成分に属す・属さないの2種類がある。

10

Page 11: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

図4.4.7 深さ優先探索の木と強連結成分の関係 (木の辺だけを見たときは木)

• 深さ優先探索の木の上で強連結成分を表す。 • 実際は下降辺・上昇辺・交差辺も存在してて、  それらとともに強連結成分を作っている。

• 各強連結成分に最初に訪問した頂点   =その部分木の根。

• 部分木の根からその子孫に到達可能。 • 部分木が強連結成分なら、  木の辺を0回以上通った後で  上昇辺か交差辺を通って根に戻れる。

• 深さ優先探索の木の葉から、上昇辺  や交差辺を通ってその葉の祖先に  たどり着くことができ、そういう祖先の  うちで最も根に近いものを求める。

• 教科書のlowlink変数

強連結成分を見つけたら、 この辺を木からはずす。 11

Page 12: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

public class StrongComponent<E> { private int sequence; private Stack<Node<E>> stack = new Stack<Node<E>>(); private int visit(Node<E> node){ node.setSequence(++this.sequence); int min = this.sequence; stack.push(node); for(Node<E> neighbor: node.getEdges()){ int m; if(neighbor.getSequence() == 0) m = visit(neighbor); else m = neighbor.getSequence(); min = Math.min(min, m); } if(min == node.getSequence()){ Node<E> component; do { component = stack.pop(); System.out.print(component.getValue() + " "); component.setSequence(Integer.MAX_VALUE); } while (component != node); System.out.println(); } return min; } public void search(Collection<Node<E>> graph){ this.sequence = 0; this.stack.clear(); for(Node<E> node: graph) if(node.getSequence() == 0) visit(node); }}

12

訪問順seq

この根からつながる 強連結成分を取り出す。

隣の頂点が訪問済みの場合は、 そこからたどれる最も根に 近い頂点の訪問順を更新する。 訪問済みなので木の辺じゃない。

未訪問の場合は探索を進める。

深さ優先探索し終わった後、 調べてみたら、 強連結成分の根だった (seq=lowlink)

教科書のlowlink

交差辺経由で探索されないようにする。

Page 13: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

public static void main(String[] args) { System.out.println("図4.4.9"); for(Node<Character> node: test_data2){ node.reset(); } nodeA.connectTo(nodeB); nodeA.connectTo(nodeC); nodeB.connectTo(nodeE); nodeB.connectTo(nodeF); nodeC.connectTo(nodeF); nodeC.connectTo(nodeG); nodeD.connectTo(nodeA); nodeE.connectTo(nodeD); nodeE.connectTo(nodeH); nodeF.connectTo(nodeE); nodeG.connectTo(nodeH); nodeH.connectTo(nodeI); nodeI.connectTo(nodeH); new StrongComponent<Character>().search(test_data2); }

13

図4.4.9 I H G C F D E B A

図 4.4.9 プログラムの実行例 (実線は木の辺、点線はそれ以外の辺)

Page 14: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

擬似コード (Pseudocode)

•  擬似プログラムともいう。 •  アルゴリズムを既存のプログラミング言語に似せて書いたもの。 – かつてはPascalやFortran、今はJava?

•  要点だけ書くのでそのまま動く保障はない。 – 教科書のコードはかなり完成度が高い。 –  Javaだと、どこでも動くコードを書きやすい。

14

Page 15: アルゴリズムとデータ構造 - kochi-tech.ac.jp...H I 図4.4.1 二重連結グラフ 図4.4.2 関節点と二重連結成分 二重連結 (250ページ) グラフから1つの頂点と

期末試験 •  教室: C101 (いつものA107は使えません)

•  日時: 2012年7月30日16時30分~18時00分 – 入室限度: 16時50分まで – 退出可能: 17時00分より

•  持ち込み可 – 教科書・資料(自筆・コピー問わず)は持ち込み可 – 人間・パソコン・携帯電話・PHSなど持ち込み不可

•  学生証必携 – 持っていない場合は教務で発行してもらうこと

15