2 基礎的な管理(管理の基盤) - HACCP関連情報 …...第2章 基礎的な管理(管理の基盤) 9 カンピロバクター属菌 黄色ブドウ球菌 汚染源
情報システム基盤学基礎 1
description
Transcript of 情報システム基盤学基礎 1
1
情報システム基盤学基礎1
アルゴリズムとデータ構造 第6回
Elements of Information Systems Fundamentals1
目次 : 今日やること
2
文字列のアルゴリズム文字列照合
• Knuth-Morris-Pratt のアルゴリズム
• Boyer-Moore のアルゴリズム
• Rabin-Karp のアルゴリズム
文字列照合とは ?
3
Input: テキスト T n 文字の配列 パターン P m 文字の配列 Output: 文字列中でパターンが現れる位置 pos (一番小さい位置)
a b a
c a b a b a cb dテキスト T :パターン P :
文字列照合アルゴリズ
ム
文字列照合アルゴリズ
ム3
2 3 4 5 6 7 81 9
応用:Web ページ上でのキーワード検索
遺伝子データ上でのキーワード検索
P[1]=T[pos]P[2]=T[pos+1] …P[m]=T[pos+m-1]
Naive アルゴリズム
4
アイデア :
T 中の各文字について , パターン P が出現していないかどうか調べる
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la
l g o la b g o l a h cla g a
NAIVE-STRING-MATCHER(T, P)1 for s ← 1 to n-m+1
23
for j ← 1 to m if P[ j ] != T [ s+j-1 ] break;
4 if j ==m+1 return s as pos
l g o la
sPos.
計算時間:
O(m(n-m+1))
Naive アルゴリズムの欠点
5
文字列 T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
s
マッチング時に得られた情報を活用してない
⇒ マッチング位置の後退が発生
• 2文字目は「 l 」• 3文字目は「 g 」
a と一致しない
a と一致しない
パターン P :
l g o la l g o la
無駄無駄
いきなり4文字目までずらすべき
×
Knuth-Morris-Pratt のアルゴリズム(KMP アルゴリズム )
過去のマッチング時の情報を利用して文字比較回数削減 マッチング位置を後退させない
Pの何文字目でマッチングが失敗したかで以下を決定 Tの現在のマッチング位置をPの何文字目と合わせてマッチン
グ作業を再開するか Tのマッチング位置は不変⇒後退しない
P は必ず右にずれる 配列 next はTによらず事前計算可能⇒表に記憶
6
𝑛𝑒𝑥𝑡 [𝑘]=𝛽マッチング開始位置
何文字目で間違ったか()
マッチング失敗時の動作
7
文字列 T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
s
1. k 文字目で失敗⇒ next[k] を参照2. P を右にずらす: 分
Tの現在のマッチング位置を P の next[4] 文字目と重ねる
3. 現在のマッチング位置から照合再開
パターン P :
l g o la
×
next[4]=1
マッチング失敗時の動作
8
文字列 T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla a l
s
1. k 文字目で失敗⇒ next[k] を参照2. P を右にずらす:
Tの現在のマッチング位置が P の next[k] 文字目と重ねる
3. 現在のマッチング位置から照合再開
パターン P :
l loaa
×
next[4]=2 の例
Tによらず事前計算できる理由 文字目でマッチングが間違ったという条件から
T の直前の文字がわかる P 自身に含まれる
9
文字列 T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o da a l g o l h cla g a
l g o la l g o la
l g o la l g o la
l g o la l g o la
パターン P :
l g o la l g o la
𝑘=4
𝑘=2
𝑘=5
next の計算 next[1] : 0 に設定。特殊扱い
1 文字も一致しないで間違った 文字列Tの現在のマッチング位置が変化
next[k]: : (T内)一致箇所の最後 (suffix) : Pの先頭 (prefix)
10パターン P :
l a l ga
開始位置
next[1] 0
next[2] 1
next[3] 1
next[4] 2
next[5] 3
la
l a lak=5
k=3
l a l ga
:Tのマッチング位置
KMP アルゴリズムの疑似コード
11
KMP(T, P) t←1 // T 内のマッチング位置 p←1 // P 内のマッチング位置
while (t)
if (P[ p ] == T [ t ]) { t++; p++; if(p==m+1) // m 文字連続マッチ成功 } else{ // マッチング失敗 if(next[p]==0) t++; //1 文字目で失敗 , p=1 のまま else p=next[p]; //P をずらしてマッチング開始位置設定。 }
ここまで来たら照合失敗 ;
計算量(文字比較回数)=2n
動作例
12
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
P :
l a l ga2 3 4 51
k=4
開始位置
next[1] 0
next[2] 1
next[3] 1
next[4] 2
next[5] 3×○○○
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
P :
l a l ga2 3 4 51
×
k=2
○
動作例
13
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
P :
l a l ga2 3 4 51
開始位置
next[1] 0
next[2] 1
next[3] 1
next[4] 2
next[5] 3×
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
P :
l a l ga2 3 4 51
×
k=1
k=1
動作例
14
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
P :
l a l ga2 3 4 51
開始位置
next[1] 0
next[2] 1
next[3] 1
next[4] 2
next[5] 3
15
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
P :
k=5 l a l ga2 3 4 51
開始位置
next[1] 0
next[2] 1
next[3] 1
next[4] 2
next[5] 3
×○○○○
l a l ga2 3 4 51
P :
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
○○
16
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
P :
k=5 l a l ga2 3 4 51
開始位置
next[1] 0
next[2] 1
next[3] 1
next[4] 2
next[5] 3
×○○○○
l a l ga2 3 4 51
P :
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
○○
17
l a l ga2 3 4 51
P :
T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a l a lh a l a l g h cla a d
○○ ○○ ○
18
KMPアルゴリズムのまとめマッチング失敗時 Tの現在のマッチング位置をPの何文字目と合
わせてマッチング作業を再開するかを決定 Pを右にずらすことに相当 Pのみを用いて next[k] を事前計算
Tのマッチング位置は絶対に後退しない
Tのすべての文字は必ず1度は比較される ⇒改良余地
Boyer-Moore のアルゴリズム KMP: Pの1文字目から後ろへ比較をすすめる
Boyer-Moore: P の最後の文字から前に比較を進める
19
パターン P :
l g o la l g o la
パターン P :
l g o la l g o la
失敗時にPをずらす方向はTの後方( KMP と一緒)
Boyer-Moore のアルゴリズム
20
アイデア1:
T 中の各文字について , パターン P が出現していないかどうかを後ろから調べる
アイデア2:
文字比較をさぼれるところはスキップする
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la
l g o la b g o l a h cla g a
l g o la
l g o la
基本的な流れ s
基本的な流れ
Boyer-Moore のアルゴリズム
21
アイデア1:
T 中の各文字について , パターン P が出現していないかどうかを後ろから調べる
アイデア2:
文字比較をさぼれるところはスキップする
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la
l g o la b g o l a h cla g a
l g o la
s
l g o la
基本的な流れ
Boyer-Moore のアルゴリズム
22
アイデア1:
T 中の各文字について , パターン P が出現していないかどうかを後ろから調べる
アイデア2:
文字比較をさぼれるところはスキップする
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la
l g o la b g o l a h cla g a
l g o la
s
l g o la
基本的な流れ
Boyer-Moore のアルゴリズム
23
アイデア1:
T 中の各文字について , パターン P が出現していないかどうかを後ろから調べる
アイデア2:
文字比較をさぼれるところはスキップする
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la
l g o la b g o l a h cla g a
l g o la
s
l g o la
基本的な流れ
Boyer-Moore のアルゴリズム
24
アイデア1:
T 中の各文字について , パターン P が出現していないかどうかを後ろから調べる
アイデア2:
文字比較をさぼれるところはスキップする
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la
l g o la b g o l a h cla g a
l g o la
sAns.
l g o la
なぜ後ろから調べるか1文字目で間違えた時のスキップ幅を大きくできる KMP: Pの先頭から後ろへ
Pにない文字が出現⇒1文字しかずらせない
Boyer-Moore: P の最後から前へ Pにない文字が出現⇒Pを大きくずらせる
25
パターン P :
e v e rn
文字列 T :
2 3 4 5 6 7 81 9 10
l g o lh blh g a
パターン P :
e v e rn
文字列 T :
2 3 4 5 6 7 81 9 10
l g o lh blh g a
T[1..4] は比較されない
26
l g o la e v e rn
文字列 T :
“ h”のせいでマッチしないことが明らか
s = 1
e v e rns = 2
e v e rns = 3
e v e rns = 4
e v e rns = 5
e v e rns =6
パターン中に現れない文字で間違えたら ? ⇒ 大きくずらせる
Skip
マッチの可能性あり
文字列 T :
2 3 4 5 6 7 81 9 10
l g o lh blh g a
s
文字列 T :
2 3 4 5 6 7 81
l g oobl a g
l g oa
パターン P :
文字比較のサボり方
27
2つのやり方がある
Case 1:T のマッチング位置の文字情報からスキップ幅決定 Case 2: 2文字目以降でミスした時
• 過去に一致した文字の情報からスキップ幅決定
文字列 T :
2 3 4 5 6 7 81
l g oobl a g
l g oa
パターン P :
Case 1: Case 2:
Case 1: T のマッチング位置の文字 情報からスキップ幅決定
28
l g o la e v e rn
文字列 T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o za b g n e v e rla g a
“z” のせいでマッチしないことが明らか
s = 5
e v e rns = 6
e v e rns = 7
e v e rns = 8
e v e rns = 9
e v e rns = 10
パターン中に現れない文字で間違えたら ? ⇒ m 文字ずらす
Skip
マッチの可能性あり
いくつ Skip してよいか ? の情報⇒ 全ての文字について前処理で計算しておいて , テーブル
に保存29
文字列 T :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o na b g n e v e rla g a
パターン中に現れる文字で間違えたら ? ⇒
その文字が現れるところまでずらす
l g o la e v e rn
“n” のせいでマッチしないことが明らか
s = 5
e v e rns = 6
e v e rns = 7
e v e rns = 8
e v e rns = 9
Skipマッチの可能性あり( n が初めて出現)
1 つずつずらしていった
とき , n が初めて出現するところまで Skip
Case 1: T のマッチング位置の文字 情報からスキップ幅決定
スキップ幅の計算
文字 n e v r その他skip[] 4 1 2 5 5
30
for 任意のアルファベット c skip[c]=m;for skip[P[i]]=m-i;
l g o la e v e rn
2文字目以降でミスした時用
31
Case 2: 2文字目以降でミスした時
「 4 文字目で間違った」という事実からわかること T の後ろ 3 文字は a,b,c T の後ろから 4 文字目は X ではない
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a b c
17 18 19 20 21 22 23
z
a b cx
P のみでわかる
32
Case 2: 2文字目以降でミスした時
「k文字目で間違った」という事実からわかること T の後ろ k-1 文字 T の後ろから k 文字目は P[m-k+1] ではない
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a b c
17 18 19 20 21 22 23
z
a b cx
P のみでわかる
いくつ Skip してよいか ? の情報⇒ 全てのについて前処理で計算しておいて , テーブルに保存
Case 2: 2文字目以降でミスした時
33
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a b c
17 18 19 20 21 22 23
z
Y a b ca b c x
Case 2a: 途中まで正解した部分と同じ文字列が現れる
途中まで正解途中まで正解と同じ !!
Y a b ca b c xSkip
• 「途中まで正解部分」と , それの“分身”がそろう • 「途中まで正解部分」の1文字前と分身の1文字前は異なる
ようにスキップ
ここが X ならマッチ可能性なし
Case 2: 2文字目以降でミスした時Case 2a が成立しない時
34
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a b c
17 18 19 20 21 22 23
z
a b cb c x
Case 2b: パターンの末尾と先頭が同じ
先頭と同じ !!末尾と同じ !!
a b cb c xSkip
末尾と先頭をそろえる
Case 2: 2文字目以降でミスした時
35
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
a b c
17 18 19 20 21 22 23
z
a b cx
Case 2c: Case 2a にも 2b にも当てはまらない
途中まで正解した部分と同じ文字列は現れない
a b cxSkip
パターンの長さ分( m 文字分)だけ skip させる
これらのアイデアに基づくと , 文字の比較回数が 4n 回に抑えられる (証明は難しいので省
略)
疑似コード
36
Boyer Moore(T, P) skip[]: Case1 に対応するスキップ幅 (事前計算) next[1..m]: Case2 に対応するスキップ幅(事前計算)
t = m // T 内のマッチング位置の初期化 while (t) p= m // P内のマッチング位置 if (P[ p ] == T [ t ]) { t = t-1; p = p-1; if(p==0) // m 文字連続マッチ成功 } else{ // マッチング失敗 t = t + max(skip[T[t]], next[p]+m-p) //t のマッチング位置を右へ }
ここまで来たら照合失敗 ;
計算量(文字比較回数)=4n実用上はKMPより高速
Rabin-Karp アルゴリズム ( アイデアだけ)
37
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o laH(“algol”)=3
H(“algol”)=3ハッシュ値が等しい
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
38
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
Ans.
ハッシュ値が等しいので, 1 文字ずつ比較 一致したので,出力
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
39
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値を計算H(“algol”)=3
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
40
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値を計算H(“algol”)=3
H(“algaa”)=0
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
41
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値を比較H(“algol”)=3
H(“algaa”)=0
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
42
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値が等しくないので, 1 文字ずつの比較を スキップ
H(“algol”)=3
H(“algaa”)=0
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
43
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値が等しくないので, 1 文字ずつの比較を スキップ
H(“algol”)=3
H(“lgaal”)=0
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
44
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値が等しくないので, 1 文字ずつの比較を スキップ
H(“algol”)=3
H(“gaalg”)=6
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
45
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o laH(“algol”)=3
H(“aalgo”)=3ハッシュ値が等しい
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
46
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値が等しいので, 1 文字ずつ比較
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
47
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値が等しいので, 1 文字ずつ比較 一致しないので,次へ
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
48
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o laH(“algol”)=3
H(“algol”)=3ハッシュ値が等しい
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
49
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
ハッシュ値が等しいので, 1 文字ずつ比較
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
50
アイデア
文字列 T :
パターン P :
2 3 4 5 6 7 81 9 10 11 12 13 14 15 16
l g o la b g o l a h cla g a
l g o la
s
l g o la
Ans.
ハッシュ値が等しいので, 1 文字ずつ比較 一致したので,出力
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
Rabin-Karp アルゴリズム ( アイデアだけ)
51
テキストの文字数が n,パターンの文字数が m のとき, 平均,最良の実行時間は O(n) 最悪性能は O(nm) となる ※ごく稀に最悪性能になるので,広く用いられない
複数のパターンを検索するときに有効 q個のパターンのいずれかとの一致を検索する計算量も O(n)
パターン P が現れるか調べる際に, 先にハッシュ値を比較し, 等しい場合にのみ 1 文字ずつ比較する
ハッシュ (Hash)値を利用するアルゴリズム
第3回:レポート課題
Prim のアルゴリズムを実装し、以下のグラフの最小全域木を求めよ。余裕があれば、クラスカルのアルゴリズムも実装し、 s からの最短経路を求めてください。
出題: H25年5月22日締切: 6月12日提出先: IS棟2F事務ポスト(コード、実行結果をA4で提出。プログラムにコメントも付けること。) 52
6
811
8
5 2
6
3
4 7
41
5
9
s
b
h
i
c
g
d
f
e