Teoria Obliczeń i Złożoności Obliczeniowej

Transkrypt

Teoria Obliczeń i Złożoności Obliczeniowej
Teoria Obliczeń i Złożoności Obliczeniowej
Laboratorium: Maszyna Turinga.
Zapoznanie się z modelem obliczeń w postaci jednotaśmowej Maszyny Turinga.
Maszyna Turinga to stworzony przez Alana Turinga abstrakcyjny model komputera służący do wykonywania
algorytmów. Maszyna Turinga składa się z nieskończenie długiej taśmy podzielonej na pola. Taśma może
być nieskończona jednostronnie lub obustronnie. Każde pole może znajdować się w jednym z N stanów.
Maszyna zawsze jest ustawiona nad jednym z pól i znajduje się w jednym z M stanów. Zależnie od
kombinacji stanu maszyny i pola maszyna zapisuje nową wartość w polu, zmienia stan i przesuwa się o jedno
pole w prawo, w lewo lub pozostaje na miejscu. Liczby N i M mogą być dowolne, byle skończone. Wyróżnia
się też stan (M+1)-szy, który oznacza zakończenie pracy maszyny.
Maszyny Turinga są interesujące z kilku względów: udowodniono, że zwykłe komputery są równoważne
maszynie Turinga, jest wygodnym narzędziem przy precyzowaniu pojęć i problemów procesu poznawania
i sztucznej inteligencji.
Jeżeli dla każdej konfiguracji Maszyny Turinga dopuszczalne jest wykonanie co najwyżej 1 instrukcji, o taką
maszynę nazywamy deterministyczną (DTM).
Złożoność czasowa T(n) DTM równa jest sumie ruchów głowicy maszyny wykonywanych podczas
przetwarzania słowa wejściowego o długości n (bierzemy pod uwagę zawsze najgorszy przypadek).
Złożoność pamięciową S(n) DTM obliczamy jako odległość od lewego końca taśmy jaką może osiągnąć
głowica maszyny w trakcie przetwarzania słowa wejściowego o długości n (w najgorszym przypadku).
Analiza algorytmu dla DTM
Przeanalizujemy program dodający do siebie dwie liczby w zapisie binarnym. Do analizy programu
posłużymy się symulatorem Maszyny Turinga. Symulator dane na temat wszystkich możliwych stanów
automatu przechowuje w pliku tekstowym. Oto jak wygląda zapis algorytmu dodawania w formacie
akceptowanym przez program:
0|0
1|1
2|3
3|3
4|4
5|5
6|
0
Z
0
b
0
0
0
1|0
1|1
-1|4
-1|3
-1|4
-1|5
|
1
J
1
b
1
1
1
1|1
1|1
-1|5
-1|3
-1|4
-1|
|
x
x
x
b
x
x
1|
1|1
-1|
-1|1
-1|6
|5
|6
J
J
1
0
1
Z
|
1|1
|
1|1
-1|1
-1|5
-1|1
Z
Z
0
1
0
J
|
1|2
|
1|1
1|1
-1|7
1|1
b
|
b -1|
|
0 1|
1 1|
b 1|
J 1|
Tabelka zawiera w pierwszej kolumnie numery aktualnych stanów maszyny, w pierwszym wierszu jest
zapisany aktualny symbol na taśmie. Na przecięciu się kolumn i wierszy znajdują się kolejno: numer
kolejnego stanu maszyny, symbol na który zostanie wymieniony symbol bieżący oraz kierunek ruchu głowicy
maszyny (1 – prawo, -1 – lewo).
Ten sam algorytm można przedstawić w postaci grafu przejść między stanami Maszyny Turinga:
Algorytm przyjmuje jako dane wejściowe dwie liczby binarne oddzielone przez 'x', np. 101x011.
Przeprowadzimy test dla dodawania 2 liczb: 5+3. Oczekujemy wyniku 8, czyli binarnie 1000. Kolejne przejścia
Maszyny Turinga doprowadziły właśnie do takiego wyniku:
_[1]_01x011 Stan: 0
J_[0]_1x011 Stan: 0
JZ_[1]_x011 Stan: 0
JZJ_[x]_011 Stan: 0
JZJx_[0]_11 Stan: 1
.
.
.
_[b]_1000bb Stan: 5
b_[1]_000bb Stan: 7
Wynik na taśmie: b1000bbbbb
Łatwo wyznaczyć złożoność pamięciową tego programu. Jeżeli założymy, że dodajemy 2 liczby n-bitowe to
S(n)=2n+1+1 (1 znak przeznaczony jest na separator 'x', a drugi na zaznaczenie końca, czyli symbol 'b').
Program wykorzystuje więc za każdym razem 2n+2 pól na taśmie. Oznacza to, że złożoność pamięciowa
zależy liniowo od wielkości wprowadzonej liczby binarnej.
Spróbujmy wyznaczyć złożoność czasową. Program najpierw czyta 2 liczby n-bitowe. Następnie
przeprowadzane jest dodawanie – bit po bicie odbywa się kopiowanie bitów liczby 2 do pierwszej, a następnie
wykonywane jest dodawanie na bitach. Oznacza to n-krotne przesunięcie głowicy o średnio n pól tam i z
powrotem. N-krotne kopiowanie wszystkich bitów liczby długości n sprawia, że algorytm charakteryzuje się
kwadratową złożonością czasową.

Podobne dokumenty