• 検索結果がありません。

untitled

N/A
N/A
Protected

Academic year: 2021

シェア "untitled"

Copied!
18
0
0

読み込み中.... (全文を見る)

全文

(1)

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

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

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

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

2011

2011年

77月

44日

酒居敬一

酒居敬一

((

sakai.keiichi@kochi

[email protected]

tech.ac.jp

))

http://www info kochi

http://www info kochi--tech ac jp/k1sakai/Lecture/ALG/2011/index html

tech ac jp/k1sakai/Lecture/ALG/2011/index html

http://www.info.kochi

(2)

グラフの定義

(225ページ)

• グラフは頂点の集合と辺の集合からなる。

• グラフには有向グラフと無向グラフがある。

• グラフに対する 教科書4章の仮定

グラフに対する、教科書4章の仮定。

– (v, v)の形の辺(NDAのε遷移みたいなの)はない。

頂点 から

結ぶ辺は高

– 頂点uからvへ結ぶ辺は高々1つ。

• 辺の属性として数値を持つ場合、重みという。

属性 し 数値を持 場合、重み

う。

• いくつかの辺をつないでできる経路は道。

有向グラフでは辺はすべて同じ向きをたどる

– 有向グラフでは辺はすべて同じ向きをたどる。

• 頂点からその頂点自身への道は閉路。

• 木はグラフの一種。

(3)

グラフの定義

(つづき)

• 木が複数集まったグラフは森という。

木と木が なが ていなくてもいい

– 木と木がつながっていなくてもいい。

• 頂点につながる辺の数を次数という。

– 有向グラフでは、入次数・出次数と区別する。

• 正則グラフでは全頂点の次数が同じ

• 正則グラフでは全頂点の次数が同じ。

– このときの次数をグラフの次数とする場合がある。

• ハイパーキューブなど

• グラフ全体を組織的に調べることを探索という。

グラフ全体を組織的に調

る とを探索という。

– ただし、単に頂点を訪問するだけ、かもしれない。

(4)

グラフアルゴリズムの計算量

グラフアルゴリズムの計算量

• 頂点数をnとしたときの最大の辺の数mは、

無向グラフでは

有向グラフでは

2

/

)

1

(

2

=

×

=

C

n

n

m

n

)

1

(

×

=

n

n

m

• 辺の数が最大のものを完全グラフという。

辺の数が0でもグラ である

)

(

• 辺の数が0でもグラフである。

• 密なグラフか、疎なグラフか。

密なグラフか、疎なグラフか。

– 次数がある程度以下なら疎と考える。

• 「ある程度」とは 問題に依存する

• 「ある程度」とは、問題に依存する。

• CCC(Cude Connected Cycle)なら次数は3。疎?

人工的なネ トワ クか 自然なネ トワ クか

• 人工的なネットワークか、自然なネットワークか。

(5)

グラフの表現法

(230ページ)

• 隣接行列

頂点から頂点

の接続の有無や辺の重みを持

– 頂点から頂点への接続の有無や辺の重みを持つ

– 密なグラフにはいい

• 配列やListやSetやMapによる表現

– 正則グラフなら配列

– 正則グラフなら配列

– 二分探索木のような順序木のグラフならList

– 無向グラフならListでもSetでもMapでもいい

• MapならKeyを接続先の頂点、Valueを重みにするなど

• 計算で求める

– 配列上のヒープソートの 部分順序つき二分木

– 配列上のヒ プソ トの、部分順序つき二分木

– スパコン内部ネットワークなど

(6)

1101

0101

0100

0101

1100

1101

0100

1100

0110

0111

1110

1111

0000

0001

1000

1001

1011

0011

0010

1010

(7)

深さ優先探索

(234ペ ジ)

(234ページ)

図4

.3.2 a

図4 3 2 b

図4

.3.2 b

•木の辺(実線で表示)

•逆辺(点線で表示)

図4

.3.3

•逆辺(点線で表示)

•連結グラフなら木が得られ、

そうでなければ森が得られる

(8)

public class Node<E> {

private E value; // 頂点の値

private Collection<Node<E>> edges; // 有向辺 i t b l isit d

public boolean isVisited() { return visited;

}

bli id s tVisit d(b l ) { private boolean visited;

private int sequence;

private boolean searching;

public Node(E value, Collection<Node<E>> edges) {

public void setVisited(boolean v) { this.visited = v;

}

public int getSequence() {

p ( , g ) { this.value = value; this.edges = edges; reset(); } p g q () { return sequence; }

public void setSequence(int s) { this s qu nc s;

}

public void reset(){ this.visited = false; this.sequence = 0;

this.sequence = s; }

public boolean isSearching() { return searching; q this.edges.clear(); this.searching = false; } public E getValue() { // 頂点の値を得る g }

public void setSearching(boolean s) { this.searching = s;

} public E getValue() { // 頂点の値を得る。

return value; }

public Collection<Node<E>> getEdges(){

}

public void connect(Node<E> to){

this.edges.add(to); //無向辺を追加 if( !to.getEdges().contains(this) ){ p g g (){ return this.edges; } ( g g () ( ) ){ to.getEdges().add(this); } }

public void connectTo(Node<E> to){

8

グラフの頂点を表すクラス

4.3と4.4で使う)

public void connectTo(Node<E> to){ this.edges.add(to); //有向辺を追加 }

(9)

private static Node<Character> nodeA = new Node<Character>('A', new LinkedList<Node<Character>>()); private static Node<Character> nodeB = new Node<Character>('B', new LinkedList<Node<Character>>()); private static Node<Character> nodeC = new Node<Character>('C', new LinkedList<Node<Character>>()); private static Node<Character> nodeD = new Node<Character>('D', new LinkedList<Node<Character>>()); pr vate stat c Node haracter nodeD new Node haracter ( D , new L nkedL st Node haracter ()); private static Node<Character> nodeE = new Node<Character>('E', new LinkedList<Node<Character>>()); private static Node<Character> nodeF = new Node<Character>('F', new LinkedList<Node<Character>>()); private static Node<Character> nodeG = new Node<Character>('G', new LinkedList<Node<Character>>()); private static Collection<Node<Character>> test data = new LinkedList<Node<Character>>();

p _ w L L ();

static {

test_data.add(nodeA); test_data.add(nodeB); test data.add(nodeC);

public class DepthFirstSearch {

private static <E> void visit(Node<E> node){ node.setVisited(true); _ ( ); test_data.add(nodeD); test_data.add(nodeE); test_data.add(nodeF); test_data.add(nodeG); node.setV s ted(true); System.out.print(node.getValue());

for(Node<E> neighbor: node.getEdges()){

if(neighbor.isVisited()) continue; // 訪問済み S t t i t(" ") _ ( ); } System.out.print(" -> "); visit(neighbor); } }}

public static <E> void search(Collection<Node<E>> graph){ for(Node<E> node: graph){

if(node.isVisited()) continue; // 訪問済み S st t i tl ( d tV l () "から探索します ");

テストデータのうち、

グラフの頂点とその集合

System.out.println(node.getValue() + "から探索します。"); visit(node); System.out.println(); } 9 } } }

深さ優先探索のプログラム

(10)

public static void main(String[] args) { System.out.println("図4.3.2");

for(Node<Character> node: test_data){

d s t() bli i id i ( i [] ) { node.reset();

}

nodeA.connect(nodeC); nodeA.connect(nodeD);

public static void main(String[] args) { System.out.println("図4.3.3");

for(Node<Character> node: test_data){

node reset(); public static void main(String[] args) { ( ); nodeA.connect(nodeB); nodeC.connect(nodeE); nodeC.connect(nodeF); n d D c nn ct(n d B); node.reset(); } nodeA.connect(nodeC); nodeA.connect(nodeD); d A t( d B)

public static void main(String[] args) { System.out.println("図4.3.4");

for(Node<Character> node: test_data){ node.reset(); nodeD.connect(nodeB); nodeD.connect(nodeF); nodeE.connect(nodeG); nodeE.connect(nodeF); nodeA.connect(nodeB); nodeC.connect(nodeF); nodeC.connect(nodeE); nodeD.connect(nodeB); } nodeA.connectTo(nodeC); nodeA.connectTo(nodeD); nodeA connectTo(nodeE); ( ) search(test_data); } nodeD.connect(nodeB); nodeD.connect(nodeF); nodeE.connect(nodeG); nodeE.connect(nodeF); h(t t d t ) nodeA.connectTo(nodeE); nodeC.connectTo(nodeB); nodeB.connectTo(nodeA); nodeD.connectTo(nodeC); search(test_data); } nodeD.connectTo(nodeE);nodeF.connectTo(nodeA); nodeF.connectTo(nodeG); search(test data);

図4.3.2

search(test_data); }

図4 3 3

Aから探索します。

A -> C -> E -> G -> F -> D -> B

図4.3.4

Aから探索します。

10

図4.3.3

Aから探索します。

A -> C -> F -> D -> B -> E -> G

A -> C -> B -> D -> E

Fから探索します。

F -> G

(11)

•上昇辺

子孫から祖先

向かう辺

子孫から祖先へ向かう辺

無向グラフでは逆辺

•下降辺

祖先から子孫へ向かう辺

祖先から子孫へ向かう辺

無向グラフでは逆辺

•交差辺

上昇辺でも下降辺でもない辺

図4

.3.4 a

連結グラフとは グラフ全体が

交差辺

上昇辺でも下降辺でもない辺

連結グラフとは、グラフ全体が

つながっていること。無向グラフ

では、深さ優先探索で全ての

頂点をたどる事ができれば連結

上昇辺

頂点をたどる事ができれば連結

グラフである。

しかし 有向グラフでは必ずしも

下降辺

しかし、有向グラフでは必ずしも

そうとはならない。

図4

.3.4 b

交差辺

(12)

public class DirectedDepthFirstSearch<E> { private int sequence;

private void visit(Node<E> node){

d s tVisit d(t )

有向グラフの深さ優先探索

node.setVisited(true); node.setSequence(++this.sequence); node.setSearching(true); System.out.print(node.getValue());

有向グラフの深さ優先探索

(240ページ)

y p ( g ());

for(Node<E> neighbor: node.getEdges()){ if(neighbor.getSequence() == 0){

System.out.print(" -> "); isit(n i hb ); // 木の辺 visit(neighbor); // 木の辺

} else if (neighbor.getSequence() > node.getSequence()) {

System.out.print(" 下降辺(" + node.getValue() + ", " + neighbor.getValue() + ")"); } else if (neighbor.isSearching()){

} ( g g()){

System.out.print(" 上昇辺(" + node.getValue() + ", " + neighbor.getValue() + ")"); } else {

System.out.print(" 交差辺(" + node.getValue() + ", " + neighbor.getValue() + ")"); }}

}}

node.setSearching(false); }

public void search(Collection<Node<E>> graph){

p ( g p ){

this.sequence = 0;

for(Node<E> node: graph){

if(node.getSequence() == 0){

System out println(node getValue() + "から探索します "); System.out.println(node.getValue() + から探索します。 ); visit(node);

System.out.println(); }}}}

(13)

public static void main(String[] args) { S st m ut println("図4 3 4");

System.out.println("図4.3.4");

for(Node<Character> node: test_data){ node.reset(); }} nodeA.connectTo(nodeC); nodeA.connectTo(nodeD); nodeA.connectTo(nodeE); nodeC connectTo(nodeB); nodeC.connectTo(nodeB); nodeB.connectTo(nodeA); nodeD.connectTo(nodeC); nodeD.connectTo(nodeE);( ) nodeF.connectTo(nodeA); nodeF.connectTo(nodeG); new DirectedDepthFirstSearch<Character>().search(test_data); }}

図4.3.4

Aから探索します

Aから探索します。

A -> C -> B 上昇辺(B, A) -> D 交差辺(D, C) -> E 下降辺(A, E)

Fから探索します。

F 交差辺(F

A)

> G

13

F 交差辺(F, A) -> G

(14)

トポロジカルソート

(242ページ)

(242ページ)

•Topology は「位相」のこと。トポロジカルソートのときはこちら。

•Phase も「位相」と訳せます。ベクタの位相はこちら。

⎤ ⎡5

たとえば、ベクターがあったとします。

⎥ ⎤ ⎢ ⎡2 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 0 5 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 0 0

大きさ0

大きさを比較することは

⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 0 0 ⎥ ⎦ ⎢ ⎣0 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 4 3 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 0 2 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 2 0 ⎤ ⎡5 ⎡3⎤ ⎡0⎤

大きさ2

できますが、大きさが同じ

だからといって同じベクター

であるとは限りませんよね?

⎦ ⎣0 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 2 0 ⎦ ⎣4 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 0 5 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 4 3 ⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 5 0

大きさ

5

全要素間で順序がつけられる → 全順序関係

⎥ ⎦ ⎤ ⎢ ⎣ ⎡ 5 0

全要素間で順序

けられる

全順序関係

一部の要素間に順序がつけられる → 半順序関係

同じだけど同じじゃない、というのは順序がつけられて

4.3.6 DAG

(Directed Acyclic Graph)

ません。そういうデータは、DAGで保持することができる。

(15)

幅優先探索

(244ペ ジ)

(244ページ)

図4

.3.2 a

図4

.3.7

(16)

public class BreadthFirstSearch {

public static <E> void search(Collection<Node<E>> graph){

Queue<Node<E>> queue = new LinkedList<Node<E>>(); // FIFO f (N d E d h){

for(Node<E> node: graph){ if(node.isVisited()){ continue; // 訪問済み }} queue.add(node); // enqueue node.setVisited(true); while( !queue.isEmpty() ){ N d <E> n xt qu u m (); // d qu u Node<E> next = queue.remove(); // dequeue System.out.print("頂点" + next.getValue());

for(Node<E> neighbor: next.getEdges()){ if( neighbor.isVisited() ){( g () ){ continue; } queue.add(neighbor); // enqueue neighbor setVisited(true); neighbor.setVisited(true);

System.out.print(" 辺(" + next.getValue() + ", " + neighbor.getValue() + ")"); } System.out.print(" -> ");y p ( ) } System.out.println(); } }} } 16

(17)

public static void main(String[] args) { System.out.println("図4.3.7");

for(Node<Character> node: test_data){ d s t() node.reset(); } nodeA.connect(nodeC); nodeA.connect(nodeD);( ); nodeA.connect(nodeB); nodeC.connect(nodeE); nodeC.connect(nodeF); n d D c nn ct(n d B); nodeD.connect(nodeB); nodeD.connect(nodeF); nodeE.connect(nodeG); nodeE.connect(nodeF);( ) search(test_data); }

図4.3.7

頂点A 辺(A, C) 辺(A, D) 辺(A, B) ->

頂点C 辺(C

E) 辺(C

F) ->

頂点C 辺(C, E) 辺(C, F) >

頂点D ->

頂点B ->

頂点E 辺(E, G) ->

17

頂点E 辺(E, G) >

頂点F ->

頂点G ->

(18)

public class DepthFirstSearchStack {

public static <E> void search(Collection<Node<E>> graph){

St k N d E t k St k N d E () // LIFO Stack<Node<E>> stack = new Stack<Node<E>>(); // LIFO for(Node<E> node: graph){

if(node.isVisited()){ continue; // 訪問済み continue; // 訪問済み } stack.push(node); // push node.setVisited(true); hil ( ! t k t () ){ while( !stack.empty() ){

Node<E> next = stack.pop(); // pop System.out.print("頂点" + next.getValue());

for(Node<E> neighbor: next.getEdges()){ for(Node E ne ghbor next.getEdges()){

if( neighbor.isVisited() ){ continue; } t k dd( i hb ) // h stack.add(neighbor); // push neighbor.setVisited(true); } System.out.print(" -> ");y m p ( );

BreadthFirstSearchのFIFO(リスト)を

LIFO(スタック)に変えたもの

} System.out.println(); } }

LIFO(スタック)に変えたもの。

この変更により、幅優先探索だったプログラムが

深さ優先探索プログラムになる。

(247ページ)

} } 18

(247

ジ)

参照

関連したドキュメント

Keywords: Learning Process, Instructional Design, Learning Analytics, Time-Series Clustering, Dynamic Time

Causation and effectuation processes: A validation study , Journal of Business Venturing, 26, pp.375-390. [4] McKelvie, Alexander &amp; Chandler, Gaylen &amp; Detienne, Dawn

Previous studies have reported phase separation of phospholipid membranes containing charged lipids by the addition of metal ions and phase separation induced by osmotic application

It is separated into several subsections, including introduction, research and development, open innovation, international R&amp;D management, cross-cultural collaboration,

UBICOMM2008 BEST PAPER AWARD 丹   康 雄 情報科学研究科 教 授 平成20年11月. マルチメディア・仮想環境基礎研究会MVE賞

During the implementation stage, we explored appropriate creative pedagogy in foreign language classrooms We conducted practical lectures using the creative teaching method

講演 1 「多様性の尊重とわたしたちにできること:LGBTQ+と無意識の 偏見」 (北陸先端科学技術大学院大学グローバルコミュニケーションセンター 講師 元山

1) A novel large-scale tactile sensing system at low cost for robot links: The research proposes an accomplished tactile sensing system for robot links with a large sensing area