Aritalab:Lecture/Automata/TM

From Metabolomics.JP
< Aritalab:Lecture | Automata(Difference between revisions)
Jump to: navigation, search
m (チューリング機械)
m
 
(6 intermediate revisions by one user not shown)
Line 1: Line 1:
 +
[[Aritalab:Lecture/Automata|形式言語理論のトップページヘ]]
 
==チューリング機械==
 
==チューリング機械==
  
Line 5: Line 6:
 
オートマトンとの根本的な違いはテープ上に自由に読み書きができる点です。
 
オートマトンとの根本的な違いはテープ上に自由に読み書きができる点です。
  
 +
===決定性1テープチューリング機械===
 
まず、決定性の1テープチューリング機械 (DTM: Deterministic one-tape Turing Machine) を定義しましょう。
 
まず、決定性の1テープチューリング機械 (DTM: Deterministic one-tape Turing Machine) を定義しましょう。
  
Line 15: Line 17:
 
テープはあらかじめ空白で埋められているとし、初期状態は q<sub>0</sub> です。
 
テープはあらかじめ空白で埋められているとし、初期状態は q<sub>0</sub> です。
 
状態遷移関数は
 
状態遷移関数は
: &delta;(q<sub>0</sub>, 0) = (q<sub>1</sub>, 0, +1)  
+
: &delta;(q<sub>0</sub>, 0) = (q<sub>1</sub>, 1, +1)  [状態、テープ記号、ヘッド位置]
のように与えます。これは状態 q<sub>0</sub> のときにヘッド下に記号 0 があれば、次の状態 q<sub>1</sub> に移動してヘッドの記号を 1 に書き換え、ヘッドを右に 1 だけ移動させるという意味します。これが 1 ステップ分の動作です。
+
のように与えます。これは状態 q<sub>0</sub> のときにヘッド下に記号 0 があれば、次の状態 q<sub>1</sub> に移動してヘッド位置の記号を 1 に書き換え、ヘッドを右に 1 だけ移動させるという意味します。これが 1 ステップ分の動作です。
 
TM のコンディションは現在状態 q 、テープの開始位置から現在のヘッド位置までの内容全て s, 現在のヘッド位置からテープの終了位置までの内容全て t を三つ組みにした (q, s, t) で一意に指定できます。これを様相といいます。
 
TM のコンディションは現在状態 q 、テープの開始位置から現在のヘッド位置までの内容全て s, 現在のヘッド位置からテープの終了位置までの内容全て t を三つ組みにした (q, s, t) で一意に指定できます。これを様相といいます。
 
様相 S<sub>1</sub> から S<sub>2</sub> に1ステップで移動できるとき、S<sub>1</sub> &rArr; S<sub>2</sub> と書きます。
 
様相 S<sub>1</sub> から S<sub>2</sub> に1ステップで移動できるとき、S<sub>1</sub> &rArr; S<sub>2</sub> と書きます。
入力列 x に対して、ある受理状態 f &isin; F と何らかのテープ記号列 y, z &isin; &Gamma;<sup>*</sup> が存在して、(q<sub>0</sub>, &epsilon;, x) &rArr;...&rArr; (q, y, z) であれば、 x は受理されたといいます。
+
入力列 x に対して、ある受理状態 q<sub>f</sub> &isin; F と何らかのテープ記号列 y, z &isin; &Gamma;<sup>*</sup> が存在して、(q<sub>0</sub>, &epsilon;, x) &rArr;...&rArr; (q<sub>f</sub>, y, z) であれば、 x は受理されたといいます。
 
受理されない語に対して、TM は停止しない場合もありえます。  
 
受理されない語に対して、TM は停止しない場合もありえます。  
  
;入力された二進数が4の倍数であることを認識するDTM
+
;例:入力された二進数が4の倍数であることを認識するDTM
 
<center>
 
<center>
 +
{|
 +
|
 +
;DTM の仕様
 
&Gamma; = { 0, 1, b }, &Sigma; = {0, 1}<br/>
 
&Gamma; = { 0, 1, b }, &Sigma; = {0, 1}<br/>
Q = {q<sub>0</sub>, q<sub>1</sub>, q<sub>2</sub>,
+
Q = {q<sub>0</sub>, q<sub>1</sub>, q<sub>2</sub>, q<sub>Y</sub>, q<sub>N</sub>}
q<sub>3</sub>, q<sub>Y</sub>, q<sub>N</sub>}
+
| &nbsp;
 
+
|
 
{| class="wikitable"
 
{| class="wikitable"
| q || 0 || 1 || b
+
|+ 状態遷移関数
 +
|-
 +
! q || 0 || 1 || b
 
|-
 
|-
| q<sub>0</sub>
+
! q<sub>0</sub>
 
| (q<sub>0</sub>, 0, +1)  
 
| (q<sub>0</sub>, 0, +1)  
 
| (q<sub>0</sub>, 1, +1)
 
| (q<sub>0</sub>, 1, +1)
 
| (q<sub>1</sub>, b, -1)
 
| (q<sub>1</sub>, b, -1)
 
|-
 
|-
| q<sub>1</sub>
+
! q<sub>1</sub>
 
| (q<sub>2</sub>, b, -1)
 
| (q<sub>2</sub>, b, -1)
| (q<sub>3</sub>, b, -1)
+
| (q<sub>N</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
|-
 
|-
| q<sub>2</sub>
+
! q<sub>2</sub>
 
| (q<sub>Y</sub>, b, -1)
 
| (q<sub>Y</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
|-
 
|-
| q<sub>3</sub>
 
| (q<sub>N</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
| (q<sub>N</sub>, b, -1)
 
 
|}
 
|}
</center>
+
|
このDTMを
+
 
<center>
+
 
{| style="border-collapse:collapse; text-align:center"
 
{| style="border-collapse:collapse; text-align:center"
 +
|+ サンプル入力
 +
|-
 
| || || ||  
 
| || || ||  
 
|style="text-align:left"| ↓
 
|style="text-align:left"| ↓
Line 62: Line 66:
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:5em"| 01の列
+
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 1
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| ...
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
Line 68: Line 75:
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:3em"| .....
 
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:3em"| .....
 
|-
 
|-
 +
|}
 
|}
 
|}
 
</center>
 
</center>
と書いてあるテープ上で01列の開始部分(左端)を初期ヘッド位置としてスタートさせましょう。
 
すると10の入力にかかわらずヘッド位置を +1 させていき、b を見つけた時点で -1 移動して戻ります。戻った位置が 0 なら更にもうひとつ戻り、二つ 0 が続いたときのみ q<sub>Y</sub> 状態になります。
 
  
; 文字列の長さの差を計算するDTM
+
例として 1...00 と書いてあるテープ上で01列の開始部分(左端)を初期ヘッド位置としてスタートさせます。
 +
# 初期状態 q<sub>0</sub>
 +
## テープの入力が0でも1でも、初期状態 q<sub>0</sub> のままヘッドを +1 します
 +
## 初期状態で b をみつけたら、状態 q<sub>1</sub> に移動してヘッドを b の左隣に動かします
 +
# 状態 q<sub>1</sub>
 +
## ヘッド位置に 0 があれば2桁目を判定するため q<sub>2</sub> に移動してヘッドを b の左隣に動かします
 +
## ヘッド位置に 1 や b があれば、受理状態 q<sub>N</sub> に移動します
 +
# 状態 q<sub>2</sub>
 +
## ヘッド位置に 0 があれば受理状態 q<sub>Y</sub> に移動し、それ以外は NO
 +
 
 +
つまり、10 の入力文字列にかかわらずヘッド位置を +1 させていき、b を見つけた時点で &minus;1 戻ります。戻った位置が 0 なら更にもうひとつ戻り、二つ 0 が続いたときのみ q<sub>Y</sub> 状態になります。
 +
 
 +
;例:文字列の長さの差(または引き算)を計算するDTM
 
<center>
 
<center>
 +
{|
 +
|
 
&Gamma; = { 0, 1, $, b }, &Sigma; = {0, 1}<br/>
 
&Gamma; = { 0, 1, $, b }, &Sigma; = {0, 1}<br/>
Q = { ちょっと複雑 }
+
状態集合 Q = { ちょっと複雑 }
 +
| &nbsp;
 +
|
 +
{| style="border-collapse:collapse; text-align:center"
 +
|-
 +
| ||
 +
|style="text-align:left"| ↓
 +
|-
 +
|style="border-bottom:1px solid; border-top:1px solid; width:3em"| .....
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| ...
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 1
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| ...
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| 0
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:1em"| b
 +
|style="border-bottom:1px solid; border-top:1px solid; border-left:1px solid; width:3em"| .....
 +
|-
 +
| ||
 +
|colspan="4"| m 個の0 ||
 +
|colspan="5"| n 個の0
 +
|}
 +
|}
 
</center>
 
</center>
  
プログラムを書き下すのは煩雑なので、ヘッドの動きだけで解説します。
+
プログラム(=状態遷移関数)を書き下すのは煩雑なので、ヘッドの動きだけで解説します。
 
二つの文字列の長さだけが 0<sup>m</sup>10<sup>n</sup> とテープに書かれていると仮定します。
 
二つの文字列の長さだけが 0<sup>m</sup>10<sup>n</sup> とテープに書かれていると仮定します。
ここで m - n &le; 0 ならその長さ分の0, m - n < 0 なら0を返すプログラムを考えます。
+
 
まずDTMは最初の 0 を $ に置き換え、右へ移動して 1 の右隣にある 0 を 1 に変えます。そして、次に左方向に $ に出会うまで戻ります。これを繰り返します。
+
ここで m - n > 0 ならその長さ分の 0 を返し、m - n &le; 0 なら長さ分の 1 を返すプログラムを考えます。
 +
まずDTMは最初の 0 を b に置き換え、右へ移動して 1 の右隣にある 0 を 1 に変えます。そして、次に左方向に b に出会うまで戻ります。これを繰り返します。
 
すると最後に
 
すると最後に
# 0<sup>n</sup> が全て 1 に書き換わり、右に 0 を探しに行って空白に出会う
+
# m > n の場合: 0<sup>m</sup> を n+1 回 b に書き換え、右に 0 を探しにいって空白 b に出会う
# 0<sup>m</sup> が全て 1 に書き換わり、左に 0 を探しに行って $ に出会う
+
# m &le; n の場合: 0<sup>n</sup> を m 回 1 に書き換え、左に 0 を探しに行って b に出会う
のどちらかに遭遇します。前者のときは、テープに n+1 個の $ が書き込まれているので右端の $ を 0 に書き換え、残った 1 を全て b にします。
+
のどちらかに遭遇します。前者のときは、テープに n+1 個の b が書き込まれているので一度左端に戻って最右の b を 0 に書き戻し、0 をこえて右側に移動し、残った 1 を全て b にします。
後者のときは、結果が 0 になるので、残った01の文字を全て b にします。
+
後者のときは右側に移動し、残った 1 を全て b に、更にその右に残った 0 を全て 1 に変えます。(このとき 0 が残っていない可能性もあり、その時の最終結果は全て b です。)
 +
 
 +
;例:文字列の長さの和(または足し算)を計算するDTM
 +
 
 +
二つの文字列の長さだけが 0<sup>m</sup>10<sup>n</sup> とテープに書かれていると仮定します。
 +
引き算に比較すると足し算は楽です。左端から 0<sup>m</sup> を 1 まで読み飛ばし、1 の位置に 0 を書き込みます。その次に、 0<sup>m</sup> を b まで読み飛ばし、b を見つけたら左隣に 1 マス戻って b を書き込んで終了します。
  
 
===多重トラックチューリング機械===
 
===多重トラックチューリング機械===

Latest revision as of 12:05, 7 May 2012

形式言語理論のトップページヘ

Contents

[edit] チューリング機械

計算量理論においてコンピュータのモデルとなるのが、チューリング機械 (TM: Turing Machine) です。 チューリング機械は無限の長さを持つテープと、テープに読み書きをおこなう有限制御部(ヘッド)から構成されます。 オートマトンとの根本的な違いはテープ上に自由に読み書きができる点です。

[edit] 決定性1テープチューリング機械

まず、決定性の1テープチューリング機械 (DTM: Deterministic one-tape Turing Machine) を定義しましょう。

DTMのプログラムは以下の4項目から構成されます。

  1. テープに書ける記号の集合 Γ
    DTMに入力される記号の集合 Σ ⊂ Γ と、空白記号 b ∈ Γ - Σ を含みます。
  2. 状態集合 Q
    ここには初期状態 q0 と、YES/NO に対応する受理状態 qY, qN が含まれます。
  3. 状態遷移関数 δ
    (Q - {qY, qN}) × Γ   →   Q × Γ × {-1, +1}.
  4. 入力文字列 x ∈ Σ*

テープはあらかじめ空白で埋められているとし、初期状態は q0 です。 状態遷移関数は

δ(q0, 0) = (q1, 1, +1)  [状態、テープ記号、ヘッド位置]

のように与えます。これは状態 q0 のときにヘッド下に記号 0 があれば、次の状態 q1 に移動してヘッド位置の記号を 1 に書き換え、ヘッドを右に 1 だけ移動させるという意味します。これが 1 ステップ分の動作です。 TM のコンディションは現在状態 q 、テープの開始位置から現在のヘッド位置までの内容全て s, 現在のヘッド位置からテープの終了位置までの内容全て t を三つ組みにした (q, s, t) で一意に指定できます。これを様相といいます。 様相 S1 から S2 に1ステップで移動できるとき、S1 ⇒ S2 と書きます。 入力列 x に対して、ある受理状態 qf ∈ F と何らかのテープ記号列 y, z ∈ Γ* が存在して、(q0, ε, x) ⇒...⇒ (qf, y, z) であれば、 x は受理されたといいます。 受理されない語に対して、TM は停止しない場合もありえます。

例:入力された二進数が4の倍数であることを認識するDTM
DTM の仕様

Γ = { 0, 1, b }, Σ = {0, 1}
Q = {q0, q1, q2, qY, qN}

 
状態遷移関数
q 0 1 b
q0 (q0, 0, +1) (q0, 1, +1) (q1, b, -1)
q1 (q2, b, -1) (qN, b, -1) (qN, b, -1)
q2 (qY, b, -1) (qN, b, -1) (qN, b, -1)
サンプル入力
..... b b b 1 ... 0 0 b b b .....

例として 1...00 と書いてあるテープ上で01列の開始部分(左端)を初期ヘッド位置としてスタートさせます。

  1. 初期状態 q0
    1. テープの入力が0でも1でも、初期状態 q0 のままヘッドを +1 します
    2. 初期状態で b をみつけたら、状態 q1 に移動してヘッドを b の左隣に動かします
  2. 状態 q1
    1. ヘッド位置に 0 があれば2桁目を判定するため q2 に移動してヘッドを b の左隣に動かします
    2. ヘッド位置に 1 や b があれば、受理状態 qN に移動します
  3. 状態 q2
    1. ヘッド位置に 0 があれば受理状態 qY に移動し、それ以外は NO

つまり、10 の入力文字列にかかわらずヘッド位置を +1 させていき、b を見つけた時点で −1 戻ります。戻った位置が 0 なら更にもうひとつ戻り、二つ 0 が続いたときのみ qY 状態になります。

例:文字列の長さの差(または引き算)を計算するDTM

Γ = { 0, 1, $, b }, Σ = {0, 1}
状態集合 Q = { ちょっと複雑 }

 
..... b 0 0 ... 0 1 0 0 0 ... 0 b .....
m 個の0 n 個の0

プログラム(=状態遷移関数)を書き下すのは煩雑なので、ヘッドの動きだけで解説します。 二つの文字列の長さだけが 0m10n とテープに書かれていると仮定します。

ここで m - n > 0 ならその長さ分の 0 を返し、m - n ≤ 0 なら長さ分の 1 を返すプログラムを考えます。 まずDTMは最初の 0 を b に置き換え、右へ移動して 1 の右隣にある 0 を 1 に変えます。そして、次に左方向に b に出会うまで戻ります。これを繰り返します。 すると最後に

  1. m > n の場合: 0m を n+1 回 b に書き換え、右に 0 を探しにいって空白 b に出会う
  2. m ≤ n の場合: 0n を m 回 1 に書き換え、左に 0 を探しに行って b に出会う

のどちらかに遭遇します。前者のときは、テープに n+1 個の b が書き込まれているので一度左端に戻って最右の b を 0 に書き戻し、0 をこえて右側に移動し、残った 1 を全て b にします。 後者のときは右側に移動し、残った 1 を全て b に、更にその右に残った 0 を全て 1 に変えます。(このとき 0 が残っていない可能性もあり、その時の最終結果は全て b です。)

例:文字列の長さの和(または足し算)を計算するDTM

二つの文字列の長さだけが 0m10n とテープに書かれていると仮定します。 引き算に比較すると足し算は楽です。左端から 0m を 1 まで読み飛ばし、1 の位置に 0 を書き込みます。その次に、 0m を b まで読み飛ばし、b を見つけたら左隣に 1 マス戻って b を書き込んで終了します。

[edit] 多重トラックチューリング機械

DTMにおいて各状態が記号を有限個記憶しておける、と仮定してもDTMの定義から外れません。 状態 q ∈ Q にたとえば記号 a ∈ Σ を記録できるとするなら、 (q, a) という二つ組みを新しい状態集合とみなせばよいだけです。

またテープに複数の(有限の)トラックがあり、ヘッドが複数の記号を書けるとしても定義から外れません。もともとテープを左右に1マスずつ動かしていたところを、nマスのブロック毎に移動させるだけです。従って、多重トラックDTM、記憶領域つきDTMの計算能力は、もとのDTMの計算能力と差はありません。

[edit] 多テープチューリング機械

複数のテープを持ち、制御部(ヘッド)も各テープ毎に持っているチューリング機械を考えましょう。 状態遷移関数における制御部の移動先は、 +1, -1 に加えて 0 (動かない)という項を追加します。これは各制御部の位置を自由に設定するのに必要です。

この多テープTMが、もとのDTMと計算能力に差がないことを示しましょう。 テープが n 本あるTMなら、2n トラックをもち、i 個の記号を記憶できるDTMで模倣します。テープ i に対応する2トラックには、テープ i のヘッド位置マーカーとテープ i の中身全体が記録されています。 複数ヘッドを持つ多テープTMの1ステップは、2n トラックDTMのヘッドがテープ全体を一往復することで模倣できます。 まず、往路において各テープ i から読んでいる記号をヘッドの記憶部分に記録します。合計 n 個の記号を記憶し、多テープTMの状態を把握します。 復路において、各位置マーカーが読んでいる部分のテープ記号を更新し、ヘッド位置マーカーを移動させます。

結果として、多テープTMの計算能力は、もとのDTMの計算能力と差はありません。

[edit] 非決定性チューリング機械

非決定性チューリングマシン (NDTM: Non-deterministic Turing Machine) の場合、各状態と各テープ記号について動作の選択肢が有限個存在します。 これら選択肢の最大値を r とし、これら選択肢を 1 から r までの数字で表現します。

三重トラックチューリング機械を用意し、第 1 トラックに入力列が書かれているとします。 第 2 トラックは、1からrで構成される数字の列を記録するスタック記憶域として利用します。 第 3 トラックは、第 1 トラックから入力を丸々写し取って非決定性TMの動きをシミュレートするヒープ領域として利用します。 そして入力列から生成される選択肢全てを順番に試していきます。もしも選択肢のいずれかの結果、受理状態に至ったら受理とし、それ以外は入力を受理しないとします。

結果として、非決定性TMの計算能力は、もとのDTMの計算能力と差はありません。

[edit] 万能チューリング機械

記憶域つき多テープ多重トラックTMが現在の計算機のモデルになることは、容易に想像できると思います。ここでは、様々なバリエーションの計算能力が、もとの決定性TMの計算能力と変わらないことを一般化して、いかなるTMでもシミュレートできる万能チューリング機械 (UTM: Universal Turing Machine) を考えましょう。

チューリング機械の本質は、テープ記号、状態集合、状態遷移関数、入力文字列でした。 以上の情報は、状態や入力文字の符号化を定めてやれば01の列として表現できます。 従って、TMの構成を01列の「プログラム」とみなして動作をシミュレートすればOKです。

模倣するには3テープのTMを利用します。テープ1には模倣したいTMの構造を01の列として記述しておき、テープ2に、模倣するTMの入力文字列をセットします。 テープ3は処理用で、ヘッドの現在状態とテープ2のヘッドが読んでいる入力文字列を毎回コピーしてきます。テープ3に書かれた情報をテープ1の中にある状態遷移関数と照らし合わせて次状態を探し、それをテープ2と3に上書きします。

結果として、UTMの計算能力でさえ、もとのDTMの計算能力と差がないことがわかります。

次→ クラスNP

Personal tools
Namespaces

Variants
Actions
Navigation
metabolites
Toolbox