酒居敬一(sakai.keiichi@kochi-tech.ac.jp) アルゴリズムとデータ構造 2011年7月7日 酒居敬一(sakai.keiichi@kochi-tech.ac.jp) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2011/index.html.

Slides:



Advertisements
Similar presentations
組合せ最適化輪講 2.3 連結性 川原 純. 2.3 連結性 内容 – グラフ上の節点をすべてたどるアルゴリズム 計算機上でのグラフの表現 – 強連結成分を求めるアルゴリズム トポロジカル順序を求める方法も – k- 連結、 k- 辺連結について – 2- 連結グラフの耳分解について.
Advertisements

2015 年度 有限幾何学 期末試験 次の各問に答えよ.( (1), (2), (3), (4), (5), (7), (8), (10) は答えだけでよい) (1) 有向閉路が存在しない位数 4 のトーナメントを描け. (2) 内点の個数が 10 個の正則 2 分木の葉の個数を求めよ. (3) グラフ.
区間グラフにおける区間表現からMPQ-treeを効率よく構成するアルゴリズム
2009/12/4 グラフ (2) 第10講: 平成21年12月4日 (金) 4限 E252教室 コンピュータアルゴリズム.
アルゴリズムとデータ構造 2012年6月27日
アルゴリズムとデータ構造1 2008年7月22日
アルゴリズムとデータ構造 2013年6月18日
アルゴリズムとデータ構造1 2005年7月8日
アルゴリズムとデータ構造 2010年7月5日
    有限幾何学        第8回.
アルゴリズムとデータ構造 2012年7月26日
アルゴリズムとデータ構造 2012年7月19日
アルゴリズムとデータ構造 2012年6月14日
データ構造とアルゴリズム 第6回の2 木 ~ データ構造(3)~.
第11講: 平成18年12月 8日 (金) 4限 E352教室 グラフ (1).
第4章 空間解析 2.ネットワーク分析 (3) ネットワーク構造分析
s a b f c e d 2016年度 有限幾何学 期末試験 問1:15点
大岩 元 慶応大学環境情報学部 二分木 データ構造とプログラミング(10) 大岩 元 慶応大学環境情報学部
アルゴリズムとデータ構造 2011年6月14日
アルゴリズムとデータ構造 2011年6月20日
アルゴリズム入門.
アルゴリズムとデータ構造 2013年7月18日
アルゴリズムとデータ構造 2012年7月12日
アルゴリズムとデータ構造 2011年7月4日
アルゴリズムとデータ構造 2012年6月28日
アルゴリズムとデータ構造 2011年6月27日
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2013年7月16日
アルゴリズムとデータ構造1 2006年7月4日
離散数学 08. グラフの探索 五島.
Ibaraki Univ. Dept of Electrical & Electronic Eng.
アルゴリズムとプログラミング (Algorithms and Programming)
コンパイラ 2012年11月15日
二分探索木における要素削除 データ構造とプログラミング(10)
アルゴリズムとデータ構造1 2005年7月1日
アルゴリズムとデータ構造 2011年7月12日
b f c a d e g h a b c d e f g 図1 図2 2012年度 有限幾何学 期末試験
アルゴリズムとデータ構造 2012年7月17日
データ構造と アルゴリズム 第六回 知能情報学部 新田直也.
離散数学 07. 木 五島.
アルゴリズムとデータ構造1 2009年7月9日
アルゴリズムとデータ構造1 2005年7月5日
プログラミング 4 整列アルゴリズム.
アルゴリズムとデータ構造1 2005年6月24日
アルゴリズムとデータ構造 2010年6月21日
アルゴリズムとデータ構造 2010年7月26日
アルゴリズムとデータ構造 2011年7月21日
プログラミング 4 木構造とヒープ.
アルゴリズムとデータ構造 2011年7月8日課題の復習
コンパイラ 2011年10月20日
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとデータ構造 2011年6月23日
情報知能学科「アルゴリズムとデータ構造」
アルゴリズムとデータ構造 2012年7月2日
アルゴリズムとデータ構造 2011年7月11日
アルゴリズムとデータ構造1 2008年7月24日
アルゴリズムとデータ構造 2011年6月28日
アルゴリズムとデータ構造1 2006年6月23日
アルゴリズムとデータ構造 2013年7月1日
アルゴリズムとデータ構造1 2009年7月2日
アルゴリズムとデータ構造 2013年7月2日
アルゴリズムとデータ構造 2013年7月8日
2009/11/27 グラフ (1) 第9講: 平成21年11月27日 (金) 4限 E252教室 コンピュータアルゴリズム.
平面走査法を使った 一般線分の 交点列挙アルゴリズム
アルゴリズムとデータ構造 2012年6月25日
立方体の切り口の形は?  3点を通る平面はただ1つに決まります。
アルゴリズムとデータ構造 2012年6月21日
ねらい 数値積分を例題に、擬似コードのアルゴリズムをプログラムにする。
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
アルゴリズムとデータ構造 2012年7月9日
Presentation transcript:

酒居敬一(sakai.keiichi@kochi-tech.ac.jp) アルゴリズムとデータ構造 2011年7月7日 酒居敬一(sakai.keiichi@kochi-tech.ac.jp) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2011/index.html

各種の連結性の判定 (249ページ) 連結の強さを表現する概念 無向グラフ 二重連結 二重連結成分 有向グラフ 強連結 強連結成分

二重連結 F A D G C B E H I (250ページ) 図4.4.1 二重連結グラフ グラフから1つの頂点と その頂点を端点とする 図4.4.1 二重連結グラフ G グラフから1つの頂点と その頂点を端点とする すべての辺を除いて得られる グラフを考えたとき、どの頂点を 除いた場合でもグラフが連結 グラフであるとき、元のグラフは 二重連結であるという。 C B E 図4.4.2 関節点と二重連結成分 H I 二重連結成分とは、二重  連結な部分グラフのこと。 取り除くと非連結になる  頂点を関節点という。

関節点検出のアルゴリズム 前提条件 場合分け 関節点が検出されなければ、二重連結。 (251ページ) 前提条件 関節点が検出されなければ、二重連結。 深さ優先探索の結果の木を仮定して、 子孫・祖先・部分木という言葉を使う。 場合分け 頂点が木の根の場合 子が2個以上ならその頂点は関節点である。 頂点が木の根ではない場合(次のページ) 着目する3頂点の位置で2つに場合分けする。 いずれもAB間・BC間・CA間の道について考える。

BはAの祖先、CはAの子孫、 という位置関係の場合。 もしAが関節点ならば、 以下の2つは同じことを言っている BC間の道が必ずAを通ること (図 4.4.3 a) A B C もしAが関節点ならば、 以下の2つは同じことを言っている BC間の道が必ずAを通ること Cを含む部分木の中にAの祖先への 逆辺がないこと 図のように逆辺 (点線で表示)があれば、  Aを経由せずにBC間を移動できるので、  この場合はAは関節点ではない。

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

根の子が2個以上(順序数が2より大きい) ときは、根が関節点。 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); 隣接する未訪問の頂点に関しては、 深さ優先探索なので探索する。 その結果、訪問順が付けられる。 根の子が2個以上(順序数が2より大きい) ときは、根が関節点。 自分(node)の子から、祖先への逆辺 がなければ、自分は関節点。 隣接する訪問済みの頂点に関しては、 より祖先へ向かう辺(逆辺含む)の先の 頂点の順序数を保持する。 深く探索していく過程で、より祖先寄りの祖先への逆辺を 調べながら進んでいる。

H I A B C E D F G 図4.4.2 頂点Dは関節点 頂点Eは関節点 頂点Cは関節点 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); 図4.4.2 頂点Dは関節点 頂点Eは関節点 頂点Cは関節点

強連結 (255ページ) 部分グラフのうち、強連結であって、 しかもそれ以上頂点を追加すると 強連結でなくなるものを強連結成分という。 図4.4.5 強連結グラフ 有向グラフの各頂点から任意の 頂点へ至る道が存在するとき、 この有向グラフを強連結であるという。 図4.4.6 強連結成分への分割

強連結成分への分割アルゴリズム 有向グラフの深さ優先探索の応用である。 下降辺は強連結性に貢献しない。 (256ページ) 有向グラフの深さ優先探索の応用である。 下降辺は強連結性に貢献しない。 下降辺の両端の頂点について、祖先から子孫へ 木の辺から成る道がすでに存在する。 上昇辺の両端の頂点は同じ強連結成分に属す。 木の辺と上昇辺で閉路を作る。 木の辺で下降し、上昇辺で上昇して元に戻れる。 交差辺は、単純ではない。 強連結成分に属す・属さないの2種類がある。

図4.4.7 深さ優先探索の木と強連結成分の関係 (木の辺だけを見たときは木) 深さ優先探索の木の上で強連結成分を表す。 実際は下降辺・上昇辺・交差辺も存在してて、  それらとともに強連結成分を作っている。 各強連結成分に最初に訪問した頂点   =その部分木の根。 部分木の根からその子孫に到達可能。 部分木が強連結成分なら、  木の辺を0回以上通った後で  上昇辺か交差辺を通って根に戻れる。 深さ優先探索の木の葉から、上昇辺  や交差辺を通ってその葉の祖先に  たどり着くことができ、そういう祖先の  うちで最も根に近いものを求める。 教科書のlowlink変数 強連結成分を見つけたら、 この辺を木からはずす。 図4.4.7 深さ優先探索の木と強連結成分の関係 (木の辺だけを見たときは木)

そこからたどれる最も根に 近い頂点の訪問順を更新する。 訪問済みなので木の辺じゃない。 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); }} 訪問順seq 教科書のlowlink 未訪問の場合は探索を進める。 隣の頂点が訪問済みの場合は、 そこからたどれる最も根に 近い頂点の訪問順を更新する。 訪問済みなので木の辺じゃない。 深さ優先探索し終わった後、 調べてみたら、 強連結成分の根だった (seq=lowlink) 交差辺経由で探索されないようにする。 この根からつながる 強連結成分を取り出す。

C E A D B F I G H 図4.4.9 I H G 図 4.4.9 プログラムの実行例 C F D E B A 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); C E A D B F I G H 図4.4.9 I H G C F D E B A 図 4.4.9 プログラムの実行例 (実線は木の辺、点線はそれ以外の辺)

擬似コード (Pseudocode) 擬似プログラムともいう。 アルゴリズムを既存のプログラミング言語に似せて書いたもの。 かつてはPascalやFortran、今はJava? 要点だけ書くのでそのまま動く保障はない。 教科書のコードはかなり完成度が高い。 Javaだと、どこでも動くコードを書きやすい。

期末試験 教室: C101 日時: 2011年7月25日16時30分~18時00分 持ち込み可 学生証必携 入室限度: 16時50分まで 退出可能: 17時00分より 持ち込み可 教科書・資料(自筆・コピー問わず)は持ち込み可 人間・パソコン・携帯電話・PHSなど持ち込み不可 学生証必携 持っていない場合は教務で発行してもらうこと