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

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

N/A
N/A
Protected

Academic year: 2021

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

Copied!
23
0
0

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

全文

(1)

2015/12/02 1

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

第 7 回:探索のためのデータ構造( 3 )

前半:最適 2 分探索木の構築(発展)

後半:ハッシュ表(基本)

(2)

第 7 回 探索のためのデータ構造( 2 )

n

今日の内容:

¨

今日は短い内容が二つあります。

¨

前半: (発展内容)最適

2

分探索木を学ぼう。

n 「発展内容」なので、わからないときは飛ばしても良いです。(試験にでません)

n これは、検索のみで挿入と削除をしないときに、平衡二分探索木(第6回)よりも検索時間が 短くなるデータ構造を見つける話です。表を埋めることで、計算を高速に行う「動的計画法」の 例です。興味ある人はどうぞ!

¨

後半:(基本内容)「ハッシュ表」を学ぼう。

n ハッシュ表は、平均的にO(1)時間で探索できる、実用的に効率が良い探索データ構造です。

n

ポイント

¨

前半:最適

2

分探索木の計算は、本当はけっこう難しいが(全部候補の木を探すと指数 時間かかる)、表を埋めていくことで、高速に計算できる。

¨

後半:「ハッシュ表」では、「ハッシュ関数」を用いて検索する方法を理解しよう。

¨

後半: ハッシュ表には、衝突回避法の違いで、「外部ハッシュ法」と「内部ハッシュ法」があ ります。「内部ハッシュ法」は、簡単な仕組みで手品のようにうまく、衝突を回避できます。

¨ C++

unordered_map

や、

java

HashMap

は、ハッシュ表で実装されています。

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

2

(3)

2015/12/02 3

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

第 7 回前半:探索のためのデータ構造( 3 )

前半: 最適 2 分探索木の構築(発展)

(4)

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

2015 2015/12/02

4 前回の復習

辞書に適したデータ構造とは?

次の3つの基本操作を伴う集合

S

辞書

(dictionary)

という。

1. member(x,S) : x∈S

ならば

yes, x S

ならば

no

を出力

2. Insert(x,S) : SをS∪{x}に更新

3. delete(x,S) : S

S

{x}

に更新

要するに検索と 挿入と削除が 高速に行える

データ構造

1.整列された配列

member

最悪時間計算量

O(log n)

insert, deleate

最悪時間計算量

O(n)

これは問題!

2.2分探索木

member,insert,delete

最悪時間計算量

O(n)

平均時間計算量

O(log n)

挿入の順番がランダム 3.平衡2分探索木 と仮定

AVL

木(全ての節点において、左部分木と右部分木の高さの差が1以内の2分探索木)

member,insert,delete

最悪時間計算量

O(log n)

(5)

5 本日の内容

Q

1.平衡2分探索木よりもっと良い2分探索木はあるのか?

検索のみの高速化なら可能!

検索される要素の確率分布が分かっているときに、その確率分布に対して,

検索にかかる時間が平均的に最も少なくなるような木を構築することが可能

最適2分探索木

Q2.

検索・挿入・削除の時間計算量は、

O(log n)

の壁を破れないか?

平均時間計算量なら可能!

ハッシュ表を用いれば、平均時間計算量を

O(1)

(定数時間)で行える。

ただし、ハッシュ表のサイズ

m

を格納要素数

n

のオーダー

O(n)

にとった場合に

O(1)を実現可能

ハッシュ表は最も実用的な辞書に適した構造

(6)

最適 2 分探索木の構築問題

n

入力:

¨ n

個のデータ値

a 1 < a 2 <…< a n

(実数値)

¨

データ値の出現確率の表

P

(右図)

n

タスク:

¨ n

個のデータ値を格納するすべての二分探索木の中か ら,表の出現確率に関して平均探索コストが最小とな

2

分決定木

T

(最適

2

分探索木)を求めよ

アルゴリズムとデータ構造 有村博紀

6

補足スライド

値の生成確率の表

P

(-∞,a1) 0.050

a1 0.050

(a1,a2) 0.050

a2 0.025

(a2,a3) 0.050

a3 0.125

(a3,a4) 0.050

a4 0.250

(a4,a5) 0.050

a5 0.075

(a5,a6) 0.050

a6 0.125

(a6,+∞) 0.050 1.000

n

補足

¨

平均探索時間は

,

X

を格納する頂点深さ

cost(X)

として

Cost(T) := Σ X:値または区間 P(X) cost(X)

¨

素朴な方法は,

S

を格納するすべての可能な二分探索木を すべてに対する総当たり.

n 要素は昇順にソートされているとして良く,木の形だけ.

n 要素数がnのすべての可能な2分探索木の総数

= n

nくらい

¨

もっと効率よく解けないか?

=> 「動的計画法」

プログラミングコンテス トの問題風に*

*) 過去のプログラミングコンテストによく出題されている(例:KUPC2012)

a

4

a

3

a

6

a

1

a

2

a

5

v

0

v

1

v

2

v

3

v

4

v

5

v

6

(7)

基本的アイディア

n

ソートした

n

個のデータ値

a 1 < a 2 <…< a n

仮定を格納した 長さ

n

の配列

A

を考える

n

一つの部分木は,配列の部分区間

A[i..j]

に対する最適 部分木を求めれば良い.

n 2

分探索木は,真ん中の要素

A[k]

を選べば根が決まる

n A[i..j]

は,真ん中の要素

A[k]

二つの部分

A[i..k-1]

A[k+1..j]

に分割できる.

n

それぞれの最適木を求めれば良い?

n

表にして求める.

n

何個のマス目が必要?

7

a

k

T i,k-1 T k+1,j

(8)

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

2015 2015/12/02

8

最適 2 分探索木の定義 (1/2)

S={a 1 , a 2 ,…,a n } :

格納要素。ただし

a 1 <a 2 <

・・・

<a n

とする。

次の確率

(a 1 ,...,a n ), (β 0 ,...,β n )

が与えられていると仮定。

P{x=a i }=α i (i=1,2,…,n)

P{x<a 1 }=β 0 , P{a i <x<a i+1 }=β i (i=1,2,…,n-1), P{a n <x}=β n T :S

を節点要素としてもつ2分探索木

T

の各節点がちょうど2つの子をもつように

n+1

個の架空の点(外点)を導入。

節点

a i :

要素

a i

が割り当てられている節点

外点

v 0 :x<a 1

のときに

member(x,S)

により(仮想的に)たどり着く外点

外点

v i (i=1,2,…,n-1): a i <x<a i+1

のときに

member(x,S)

によりたどり着く外点 外点

v n :x>a n

のときに

member(x,S)

によりたどり着く外点

a

4

a

3

a

6

a

1

a

2

a

5

v

0

v

1

v

2

v

3

v

4

v

5

v

6

(9)

9

最適 2 分探索木の定義 (2/2)

S⊆X:

全順序集合

最適2分探索木

(optimal binary search tree)

とは 検索コスト

(member(x,S)

の平均時間計算量

)

が最小の2分探索木

最適2分探索木は次式で定義されるコスト

c

を最小化する2分探索木

T

である。

c(T)=Σα i (depth T (a i )+1)+Σβ i depth T (v i )

ただし、

depth T (u)

は2分探索木

T

における節点

u

の深さを表すものとする。

i=1

n n

i=0 ←

平均比較回数

a

4

a

3

a

6

a

1

a

2

a

5

v

0

v

1

v

2

v

3

v

4

v

5

v

6

(10)

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

2015 2015/12/02

10

最適2分探索木の構成法

T i,j :

節点

a i , a i+1 ,…,a j

からなる2分探索木

T i,j

のコストを同様に次のように定義する。

c(T i,j )=Σα p (depth Ti,j (a p )+1)+Σβ p depth Ti,j (v p )

T i,j

は根が節点

a k

であれば、ある木

T i,k-1

と木

T k+1,j

を用いて、左図のように表現できる。

c i,j =min Ti,j c(T i,j )

と定義する。最終的には

c(T)=c 1,n

となるような木

T

を求めればよい。

c i,j =min min min ( c(T i,k-1 )+Σ α p + Σ β p + α k + c(T k+1,j ) + Σ α p + Σ β p )

p=i

j j

p=i-1

a

k

T i,k-1 T k+1,j

k:i≦k≦j T

i,k-1

T

k+1,j

p=i p=i-1 p=k+1 p=k

k-1 k-1 j j

P{a i-1 <x<a k } P{a k <x<a j+1 }

=min (c i,k-1 + c k+1,j ) + Σα p + Σβ p

k:i≦k≦j p=i

j

p=i-1 j

よって最適な木

T i,j

のコスト

c i,j

はより小さな最適な木

T i,k-1 , T k+1,j (ikj)

コスト

c i,k-1 , c k+1,j

から求めることができる。

(11)

11

最適2分探索木の構成法 (

続き

)

c i,j =min (c i,k-1 + c k+1,j ) + Σα p + Σβ p

k:i≦k≦j p=i

j

p=i-1 j

T i,i-1

a i-1 <x<a i

に対する木であり外点

v i-1

のみからなる木である。

コストの定義よりc

i,i-1 =c(T i,i-1 )=0となる。

したがって、まとめると以下の漸化式が得られる。

c i,i-1 =0

for 1≦i≦j≦n for 1≦i≦n

この漸化式より、

c 1,n

およびそのコストを達成する最適2分探索木

T

動的計画法を使って時間計算量

O(n 2 )

で計算可能。

動的計画法とは

対象となる問題の部分問題の解を計算して記憶しておき、

それらを用いて元の問題の解を計算する技法

上記漸化式の場合、

c i,j

の値の計算には、

j’-i’<j-i

である

c i’,j’

しか使わない。したがって、

j-i

の値が小さな

c i,j

から順に計算すれば各

c i,j

O(j-i+1)

で求めることができる。

(12)

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

2015 2015/12/02

12

S={a 1 ,a 2 ,a 3 ,a 4 ,a 5 }

α 123 =0.1, α 45 =0.2, β 01345 =0.05

の場合

0

0

0

0

0

0 c i,j

の値

k=1 0.2

k=2 0.2

k=3 0.2

k=4 0.3

k=5 0.3

k=1 0.55

k=2 0.55

k=4 0.85

k=2 0.9

k=4 1.2

k=2 1.6

k=4 1.7 k=4 1 2.2

2 3 4 5 6 i

0 1 2 3 4 5 j

-1 0

1 2

3 4 j-i

k=3 1.1 k=4 0.65

c 2,4 = min {c 2,1 +c 3,4 , c 2,2 +c 4,4 , c 2,3 +c 5,4 } + (α 234 ) + (β 1234 )

= min {0.65, 0.5, 0.55}

+ 0.4 + 0.2

= 1.1

(

最小は

c 2,2 +c 4,4

k=3

のとき)

a

4

a

2

a

5

a

1

a

3

最適2分探索木は

(13)

13

最悪時間計算量は O(n 2 )

j-i=h

の場合、

n-h

個の

c i,j

を計算しなければならない。

1つの

c i,j

を求めるのに

h+1

個の候補から最小値を計算するので、全体では

O(Σ(n-h)(h+1))=O(n 3 )

となるが、最小候補をもっと絞り込むことができるため工夫をすれば

O(n 2 )

の最悪時間計算量で計算可能である。

c i,j

を最小にする候補の木

T i,j

の根節点

a k

は、

i≦k≦j

よりさらに絞り込めて

r i,j-1 ≦k≦r i+1,j

であることが知られている。ただし、

r i,j

は最適な木

T i,j

の根節点の

インデックス、つまり

a m

を最適な木

T i,j

の根節点とすると

r i,j =m

である。

この事実を使うと上の計算は以下のようになる。

h=0 n-1

O (r i+ 1,i+hr i,i+h−1 + 1)

i=1 n−h

h=0 n−1

# ∑

$ % &

' ( = O (r n−h+ 1,nr 1,h + nh

h=0 n− 1

)

#

$ % &

' ( = O(n 2 )

(14)

2015/12/02

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

2015 14

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

第 7 回:探索のためのデータ構造( 3 )

後半:ハッシュ表

(15)

15 前回の復習

辞書に適したデータ構造とは?

次の3つの基本操作を伴う集合

S

辞書

(dictionary)

という。

1. member(x,S) : x∈S

ならば

yes, x S

ならば

no

を出力

2. Insert(x,S) : SをS∪{x}に更新

3. delete(x,S) : S

S

{x}

に更新

要するに検索と 挿入と削除が 高速に行える

データ構造

1.整列された配列

member

最悪時間計算量

O(log n)

insert, deleate

最悪時間計算量

O(n)

これは問題!

2.2分探索木

member,insert,delete

最悪時間計算量

O(n)

平均時間計算量

O(log n)

挿入の順番がランダム 3.平衡2分探索木 と仮定

AVL

木(全ての節点において、左部分木と右部分木の高さの差が1以内の2分探索木)

member,insert,delete

最悪時間計算量

O(log n)

(16)

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

2015 2015/12/02

16 本日の内容

Q2.

検索・挿入・削除の時間計算量は、O(log n)の壁を破れないか?

平均時間計算量なら可能!

ハッシュ表を用いれば、平均時間計算量を

O(1)

(定数時間)で行える。

ただし、ハッシュ表のサイズmを格納要素数nのオーダーO(n)にとった場合に

O(1)

を実現可能

ハッシュ表は最も実用的な辞書に適した構造

(17)

17

ハッシング

ハッシュ表

(hash table)

とは

ハッシュ関数

h

を使って、要素

x

があらかじめ準備した

m

個の場所のうち、

位置

h(x)

に格納される表

[ハッシュ関数のもつべき性質]

・関数値の高速な算出が可能である

・要素となりうる

x

に対して、ハッシュ値

h(x)

m

個の位置にできるだけ偏りなく分布すること

[よく用いられるハッシュ関数]

x

が整数の場合

h(x)=x%m (x

m

で割った余り

)

・xが文字列の場合

h(x)=(Σord(x[i]))%m

ただし、

ord(a)

は文字

a

の整数コード

(ASCII, JIS, EUC

)

であり、

k

x

の文字列長

hash

は英語で「ごた混ぜにする」という意味。

i=0 k-1

一般にデータはいろいろな周期のものを含んでいるため、

m

がデータの周期を約数にもつと関数値の衝突が起こり やすくなる。そのため

m

としては素数を選ぶことが多い。

しかし、どのようなハッシュ関数を選んでも衝突は避けられない!

(18)

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

2015 2015/12/02

18 衝突対処法

異なる要素

x,y

に対し、ハッシュ値が等しくなる

(h(x)=h(y))

ことがある。

そのような場合の対処法として次の2つがある。

1.

外部ハッシュ法、チェイニング

(open hashing, chaining)

同じハッシュ値をもつ要素を、

その値に対応するバケットに格納する。

バケットは連結リストで実現できる。

2.

内部ハッシュ法、オープンアドレッシング

(closed hasing, open addressing) x

を格納しようとしたときに、位置

h(x)

がすでに

使われている場合、新しいハッシュ値

h i (x) (i=1,2,…)

次々と求め、最初に見つかった空いている位置

h i (x)に格納する。h i

としては、以下の関数などが使われる。

h i (x)=(h(x)+i)%m

h(x)=x%m

の場合の

2 32

5 55 15

insert(15,S)

2 32

5

55

15

(19)

19

外部ハッシュ法の基本操作

member(x,S) h(x)に対応するバケット内で値がxのものを探し、見つかればyes、

見つからなければ

no

を返す。

Insert(x,S) h(x)

に対応するバケット内で値が

x

のものを探し、見つかれば何もしない、

見つからなければバケットに追加。

delete(x,S) h(x)

に対応するバケット内で値が

x

のものを探し、見つかれば削除、

見つからなければ何もしない。

基本操作の時間計算量

α=n/m :

占有率

(n:

格納要素数

, m:

バケット数

)

最悪時間計算量

O(n)

(

全ての要素が同じハッシュ値をもつ場合

)

平均時間計算量

O(α)

(n=O(m)

であれば

O(1))

2 32

5 55 15

member(12,S)

h(12)=2 no

Insert(15,S)

h(15)=5

18 88 48

delete(88,S)

h(88)=8 48

(20)

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

2015 2015/12/02

20 内部ハッシュ法の基本操作

member(x,S)

位置

h(x)

から探し始め、

h(x),h 1 (x),h 2 (x),…

の順でその位置の要素が

x

等しいかをチェックする。等しいものがみつかったら

yes

を返す。位置

h i (x)

が空き

(“empty”)

となるまでチェックし、見つからなければ

no

を返す。

Insert(x,S)

位置

h(x)

から探し始め、

h(x),h 1 (x),h 2 (x),…

の順でその位置の要素が

x

等しいかをチェックする。位置

h i (x)

が空き

(“empty”)

となるまでチェックし、

x

と等しい要素が見つかれば何もしない。みつからなければ、検索途中で 見つけた空き

(“empty” or “deleted”)

x

を格納する。

delete(x,S)

位置

h(x)

から探し始め、

h(x),h 1 (x),h 2 (x),…

の順でその位置の要素が

x

等しいかをチェックする。位置

h i (x)

が空き

(“empty”)

となるまでチェックし、

x

と等しい要素が見つかれば削除し”

deleted”

のフラグを立てる。みつから なければ何もしない。

基本操作の時間計算量

α=n/m :

占有率

(n:

格納要素数

, m:

バケット数

)

最悪時間計算量

O(n)

(

全ての要素が同じハッシュ値をもつ場合

)

平均時間計算量

O(1/(1-α)) (x

が表にない場合

)

O(-(1/α)log(1-α)) (x

が表にある場合

)

どちらの場合も

n=O(m)

であれば、

O(1)

deleted empty

2 32 deleted

5 55 empty empty

15

member(12,S)

h(12)=2

no insert(12,S)

h(12)=2

12

delete(12,S)

(21)

21 内部ハッシュ法の平均時間計算量の証明

x

が表にない場合

h 0 (x)(=h(x)),h 1 (x),…の順にハッシュ値の計算を行うものとする。

位置

h i (x)

で初めて空を見つける確率は

n(n-1)

・・・

(n-i+1)(m-n) m(m-1)・・・(m-i+1)(m-i)

である。(ただし、

i=0

のとき、上式は

(m-n)/m

をあらわすものとする。)

したがって、要素の比較回数の期待値は、

比較回数の定数倍の時間で計算できるので平均時間計算量は

O(1/(1-α)) (i +1) n(n − 1)  (n − i +1)(m − n )

m(m − 1)  (m − i + 1)(m − i )

i=0 n

= (i +1)

i=0 n

m(m n(n 1) 1) (n (m i i +1) + 1) # $ % 1 m n i i & ' (

= (i + 1)

i=0 n

m(m n(n 1) 1) (n (m i i +1) + 1) i

i=1 n+1

m(m n(n −1) −1) (n (m i i + +1) 1)

n(n − 1)  (n − i + 1) m(m − 1)  (m − i +1)

i=0 n

n

m

#

$ % &

' (

i

i=0

= 1

1 − n m

= 1

1 − α

(22)

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

2015 2015/12/02

22 内部ハッシュ法の平均時間計算量の証明 (続き)

x

が表にある場合

比較回数の期待値は、

n

個の異なる要素を空の表に 格納するのに必要な比較回数

の平均に等しい。したがって

比較回数の定数倍で計算できるので、平均時間計算量は

O(- log(1-α))

(証明終わり)

1 α

確率

p

で生起する事象が

k

回目で初めて生起するとした場合、

k

の期待値は

1/p

である という事実を使っている。つまり、確率

(m-i)/m

で生起する事象では、

k

の期待値は

m/(m-i)

である。

1

n m

… y= m

m-x

1 n

m

mi ≤ 1 n

m mx

0

n i=0

n−1

dx

= m

n ln m

mn = − 1

α ln(1 α )

(23)

第 7 回 探索のためのデータ構造( 2 )

n

今日の内容:

¨

今日は短い内容が二つあります。

¨

前半: (発展内容)最適

2

分探索木を学ぼう。

n 「発展内容」なので、わからないときは飛ばしても良いです。(試験にでません)

n これは、検索のみで挿入と削除をしないときに、平衡二分探索木(第6回)よりも検索時間が 短くなるデータ構造を見つける話です。表を埋めることで、計算を高速に行う「動的計画法」の 例です。興味ある人はどうぞ!

¨

後半:(基本内容)「ハッシュ表」を学ぼう。

n ハッシュ表は、平均的にO(1)時間で探索できる、実用的に効率が良い探索データ構造です。

n

ポイント

¨

前半:最適

2

分探索木の計算は、本当はけっこう難しいが(全部候補の木を探すと指数 時間かかる)、表を埋めていくことで、高速に計算できる。

¨

後半:「ハッシュ表」では、「ハッシュ関数」を用いて検索する方法を理解しよう。

¨

後半: ハッシュ表には、衝突回避法の違いで、「外部ハッシュ法」と「内部ハッシュ法」があ ります。「内部ハッシュ法」は、簡単な仕組みで手品のようにうまく、衝突を回避できます。

¨ C++

unordered_map

や、

java

HashMap

は、ハッシュ表で実装されています。

23

参照

関連したドキュメント

This paper proposes that the two-way interpretation of an indet-mo shown in (88) results from the two structural positions that an indet-mo can occur in: an indet-mo itself

つまり、p 型の語が p 型の語を修飾するという関係になっている。しかし、p 型の語同士の Merge

[*]留意種(選定理由①~⑥は P.11 参照) [ ○ ]ランク外 [-]データ無し [・]非分布. 区部

信号を時々無視するとしている。宗教別では,仏教徒がたいてい信号を守 ると答える傾向にあった

・ 総務班は,本部長が 5 号機 SE31

RPV 代替温度計は N-10 ノズル内、 RPV 外側壁面より 5cm 程度内 側に設置→既設 RPV 底部温度計と同様に、 RPV

建屋構造 鉄⾻造、鉄筋コンクリート、鋼板コンクリート等、遮蔽機能と⼗分な強度を有 する構造

参考第 1 表 中空断面構造物の整理結果(7 号炉 ※1 ) 構造物名称 構造概要 基礎形式 断面寸法