Test GR4: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Rogoda (dyskusja | edycje)
Nie podano opisu zmian
Rogoda (dyskusja | edycje)
Nie podano opisu zmian
 
(Nie pokazano 78 pośrednich wersji utworzonych przez tego samego użytkownika)
Linia 1: Linia 1:
Sformułujemy definicje podstawowych klas
5555555555555555555555555555555555555555 Logika
złożoności w języku maszyn Turinga oraz metodę ich porównywania.
Przeanalizujemy związki między rodziną języków określonych przez maszyny Turinga a
rodziną języków typu '''(0)''' z hierarchii Chomsky'ego.  Podamy dalsze własności
języków kontekstowych i typu '''(0)'''.
Wprowadzimy pojęcie języka rekurencyjnie
przeliczalnego oraz przedstawimy tezę Churcha. Następnie omówimy
teoretyczne podstawy teorii rozstrzygalności oraz przeanalizujemy
kilka problemów nierozstrzygalnych w teorii języków.


__FORCETOC__


==Klasy złożoności obliczeniowej==


Jednym z podstawowych celów wprowadzania maszyn Turinga jest dążenie
do formalnej definicji złożoności obliczeniowej. Na podstawie
wcześniejszych uwag możemy '''utożsamiać akceptację słowa'''
przez maszynę Turinga z jej '''zatrzymaniem się'''. Intuicyjnie,
można takie zachowanie maszyny Turinga utożsamić z wykonaniem
programu, który zwraca odpowiedź "Tak" na postawione przez nas
pytanie.


{{definicja|1.1||
10101010101010101010101010101010101010101010101010 Logika
Ustalmy funkcje <math>\displaystyle t,s:\mathbb{N}\rightarrow \mathbb{N}</math>. Mówimy, że
maszyna Turinga <math>\displaystyle \mathcal{MT}</math> (deterministyczna lub
niedeterministyczna) '''akceptuje słowo <math>\displaystyle w\in \Sigma_I^*</math> w
czasie <math>\displaystyle t(|w|)</math>''', jeśli istnieje ciąg <math>\displaystyle k\leqslant t(|w|)</math> konfiguracji
<math>\displaystyle d_1,d_2,\dots, d_k</math> takich, że <math>\displaystyle d_1=\sharp s_0 w \sharp</math>, <math>\displaystyle d_k=
\sharp w_{1}s_{F}w_{2}\sharp</math> dla pewnych <math>\displaystyle w_{1},w_{2}\in \Sigma
_{T}^{*},s_{F}\in S_{F}</math> oraz <math>\displaystyle d_i \mapsto d_{i+1}</math> dla
<math>\displaystyle i=1,\dots,k-1</math>.
 
Jeśli istnieje ciąg konfiguracji <math>\displaystyle d_1 \mapsto d_2 \mapsto \dots
\mapsto d_m</math>, gdzie <math>\displaystyle d_1=\sharp s_0 w \sharp</math>, <math>\displaystyle d_m</math> jest
konfiguracją akceptującą (tzn. <math>\displaystyle d_m= \sharp w_{1}s_{F}w_{2}\sharp</math>
dla pewnych <math>\displaystyle w_{1},w_{2}\in \Sigma _{T}^{*},s_{F}\in S_{F}</math>) oraz
dodatkowo <math>\displaystyle |d_i|\leqslant s(|w|)+2</math>, to mówimy, że maszyna <math>\displaystyle \mathcal{MT}</math>
'''akceptuje słowo <math>\displaystyle w\in \Sigma_I^*</math> w pamięci <math>\displaystyle s(|w|)</math>'''.
 
Mówimy, że '''język <math>\displaystyle L</math> jest akceptowany w czasie <math>\displaystyle t(n)</math>
(pamięci <math>\displaystyle s(n)</math>)''', jeśli istnieje maszyna Turinga <math>\displaystyle \mathcal{MT}</math>, dla
której <math>\displaystyle L(\mathcal{MT})=L</math> oraz każde słowo <math>\displaystyle w\in L</math> jest
akceptowane w czasie <math>\displaystyle t(|w|)</math> (pamięci <math>\displaystyle s(|w|)</math> odpowiednio).
}}
 
{{uwaga|1.1||
W niektórych podejściach wykorzystuje się, do definicji złożoności
pamięciowej, tak zwanych maszyn Turinga off-line. Pomysł polega na
tym, aby nie uwzględniać komórek taśmy, z których maszyna czytała
informacje, a jedynie te, do których następował zapis. Dzięki temu
zabiegowi można w sposób "rozsądny" mówić o akceptacji słowa w
pamięci <math>\displaystyle \log n</math> itp. W ujęciu prezentowanym w tym wykładzie
zajmujemy się akceptacją w pamięci <math>\displaystyle n^k</math>, dla <math>\displaystyle k\geqslant 1</math>, zatem nie ma
potrzeby dodatkowego definiowania maszyn Turinga off-line.
}}
 
{{definicja|1.2||
Oznaczmy przez <math>\displaystyle Dtime(t(n))</math> oraz <math>\displaystyle Dspace(s(n))</math> rodzinę języków
akceptowanych w czasie <math>\displaystyle t(n)</math> i odpowiednio pamięci <math>\displaystyle s(n)</math> przez
deterministyczną maszynę Turinga. Dla maszyn niedeterministycznych
wprowadzamy w identyczny sposób klasy <math>\displaystyle Ntime(t(n))</math> oraz
<math>\displaystyle Nspace(s(n))</math>.
 
Określamy następujące klasy złożoności (klasy języków):
 
<center><math>\displaystyle \aligned  \textbd{P} \displaystyle  =\bigcup_{k=0}^\infty Dtime(n^k), &\qquad\qquad&
\textbd{NP} \displaystyle  =\bigcup_{k=0}^\infty Ntime(n^k),
\\
\textbd{PSPACE} \displaystyle  =\bigcup_{k=0}^\infty Dspace(n^k), &&
\textbd{NSPACE} \displaystyle  =\bigcup_{k=0}^\infty Nspace(n^k).
\endaligned</math></center>
 
}}
 
Wprost z definicji otrzymujemy zależności '''P''' <math>\displaystyle  \subset </math> '''NP''' oraz '''PSPACE''' <math>\displaystyle  \subset </math> '''NPSPACE''' . W dalszej części wykładu udowodnimy kilka mniej oczywistych zależności.
 
{{przyklad|1.1||
Rozważmy język:
<center><math>\displaystyle
L=\left\{1^i 2^j 3^k\: k=i\cdot j,\: i,j\geqslant 1\right\}.
</math></center>
 
Język <math>\displaystyle L\in  </math> '''P''' . Deterministyczna maszyna Turinga
<math>\displaystyle MT_3</math> akceptująca taki język może wyglądać następująco (zaczynamy
od konfiguracji <math>\displaystyle \sharp s_0 w \sharp</math>):
# Jeśli symbol pod głowicą, to <math>\displaystyle 1</math> zamień go na <math>\displaystyle\sharp</math>. Inaczej odrzuć.
# Przejdź od lewego ogranicznika do prawego, sprawdzając, czy po <math>\displaystyle 1</math> występuje <math>\displaystyle 1</math> lub <math>\displaystyle 2</math>, po <math>\displaystyle 2</math> tylko <math>\displaystyle 2</math> lub <math>\displaystyle 3</math>, a po <math>\displaystyle 3</math> kolejny symbol <math>\displaystyle 3</math> lub ogranicznik. Jeśli ta zależność nie jest spełniona, odrzuć. Gdy osiągniesz ogranicznik wykonaj następny krok.
# Gdy przed ogranicznikiem nie znajduje się symbol <math>\displaystyle 3</math>, odrzuć. W przeciwnym razie zamień symbol <math>\displaystyle 3</math> na <math>\displaystyle \sharp</math>, a następnie poruszaj się w lewo, aż dotrzesz do symbolu innego niż <math>\displaystyle 3</math> i <math>\displaystyle \diamondsuit</math>.
# Jeśli symbol do którego dotarłeś to <math>\displaystyle 2</math>, zamień go na <math>\displaystyle \diamondsuit</math>. Sprawdź symbol po lewej. Jeśli to <math>\displaystyle 2</math>, poruszaj się w prawo aż do ogranicznika. Następnie przejdź do kroku 3.
# Jeśli dotarłeś do symbolu <math>\displaystyle 1</math>, poruszaj się w lewo aż do ogranicznika. Zamień symbol <math>\displaystyle 1</math> przy ograniczniku na <math>\displaystyle \sharp</math>, a następnie idź w prawo, zamieniając wszystkie symbole <math>\displaystyle \diamondsuit</math> na <math>\displaystyle 2</math>. Gdy dojdziesz do ogranicznika, przejdź do kroku <math>\displaystyle 3</math>.
# Jeśli dotarłeś do ogranicznika, oznacza to, że skasowano już wszystkie symbole <math>\displaystyle 1</math>. Przejdź w prawo aż do ogranicznika. Jeśli natrafisz na symbol <math>\displaystyle 3</math>, odrzuć. W przeciwnym przypadku, akceptuj.
 
Nietrudno zaobserwować, że maszyna <math>\displaystyle MT_3</math> przechodzi przez taśmę w prawo i w lewo tyle
razy, ile symboli <math>\displaystyle 3</math> zawiera taśma oraz wykonuje jeden dodatkowy
przebieg na starcie. Zatem słowa z <math>\displaystyle L</math> są akceptowane w
czasie ograniczonym wielomianowo.
}}
 
{{kotwica|prz.1.2|}}{{przyklad|1.2||
 
Rozważmy teraz język
<center><math>\displaystyle
L=\left\{3^k\: : \: k=i\cdot j  </math>  dla pewnych  <math>\displaystyle  i,j> 1\rbrace.
</math></center>
 
Najprostszą metodą uzasadnienia, że <math>\displaystyle L\in  </math> '''NP'''  jest
konstrukcja tak zwanej wyroczni. Polega ona na następującej
dwuetapowej  procedurze:
# Skonstruuj niedeterministyczną maszynę Turinga (wyrocznia) generującą pewne słowo (certyfikat).
# Zweryfikuj w sposób deterministyczny spełnienie założeń przez certyfikat.
 
W naszym przykładzie Etap 1 wygląda następująco:
# Użyj dwóch taśm. Na pierwszej z nich znajduje się <math>\displaystyle 3^k</math>.
# Idź po pierwszej taśmie, wykorzystując niedeterministyczną funkcję przejść. Napotykając <math>\displaystyle 3</math>, możesz wypisać <math>\displaystyle 1</math> na taśmie drugiej i przejść o jedną komórkę w prawo na taśmie pierwszej lub przejść do następnego kroku. Jeśli dotarłeś do prawego ogranicznika taśmy pierwszej, przejdź do kroku 3.
# Powróć do początku pierwszej taśmy. Wykonaj sekwencję jak w kroku <math>\displaystyle 2</math>, z tą różnicą, że teraz na drugiej taśmie wypisuj symbole <math>\displaystyle 2</math>.
# Jako ostatnią część tego etapu przekopiuj symbole <math>\displaystyle 3</math> z pierwszej taśmy na drugą (po symbolach <math>\displaystyle 1</math> i <math>\displaystyle 2</math>).
 
W konstrukcji wykorzystaliśmy dwie taśmy, ale oczywiście w
nawiązaniu do wcześniejszych uwag, całą konstrukcję można wykonać na
jednej taśmie (z odpowiednio rozszerzonym alfabetem i bardziej
skomplikowaną funkcją przejść).
 
Etap 2 polega na weryfikacji, czy na taśmie drugiej znajduje się
słowo postaci <math>\displaystyle 1^i 2^j 3^k</math>, gdzie <math>\displaystyle i,j>1</math> oraz <math>\displaystyle k=i\cdot j</math>. Jeśli tak, to słowo wejściowe <math>\displaystyle 3^k</math> pochodziło z języka <math>\displaystyle L</math> i akceptujemy. Można do tego wykorzystać deterministyczną maszynę Turinga, niemal identyczną z opisaną w przykładzie poprzednim.
 
Jeśli słowo wejściowe pochodzi z języka <math>\displaystyle L</math>, to jedno z obliczeń maszyny niedeterministycznej z  Etapu 1. prowadzi do konstrukcji odpowiedniego słowa na drugiej taśmie. Nie wiemy, jaka dokładnie ścieżka obliczeń ma być wykorzystana, ale dla akceptacji języka <math>\displaystyle L</math> nie ma to znaczenia.
 
Zastanów się, czy da się wykazać, że także <math>\displaystyle L\in  </math> '''P'''
(Ćwiczenie '''1.3''', do tego wykładu).
}}
 
{{definicja|1.3||
Funkcja <math>\displaystyle s(n)</math> jest '''konstruowalna pamięciowo''', jeśli istnieje maszyna Turinga <math>\displaystyle \mathcal{MT}=(\Sigma _{T},S,f,s_{0},S_{F})</math>, dla
której <math>\displaystyle d_1 \mapsto^* d_2</math>, gdzie <math>\displaystyle d_1=\sharp s_0 1^n \sharp</math>,
<math>\displaystyle d_2=\sharp s_1 1^{s(n)} w \sharp</math> dla <math>\displaystyle s_1\in S_F</math>, <math>\displaystyle w\in
(\Sigma_T\setminus \left\{1\right\})^*</math> oraz dodatkowo <math>\displaystyle d_2</math> jest
konfiguracją końcową.
}}
 
Inaczej mówiąc, funkcję <math>\displaystyle s(n)</math> nazywamy konstruowalną pamięciowo, jeśli istnieje maszyna Turinga <math>\displaystyle \mathcal{MT}</math>, otrzymując na wejściu
słowo <math>\displaystyle w</math> długości <math>\displaystyle |w|=n</math>, zaznacza na taśmie roboczej <math>\displaystyle s(n)</math> klatek i zatrzymuje się (akceptując słowo <math>\displaystyle w</math>).
 
{{przyklad|1.3||
Funkcja <math>\displaystyle s(n)=2n</math> jest konstruowalna pamięciowo. Maszyna <math>\displaystyle MT_4</math>,
która konstruuje <math>\displaystyle s(n)</math> działa według schematu:
# Przejdź do prawego markera. Jeśli napotkano symbol inny niż <math>\displaystyle 1</math>, to odrzuć.
# Idź w lewo aż do pierwszego symbolu <math>\displaystyle 1</math> lub markera <math>\displaystyle \sharp</math>
# Jeśli napotkałeś symbol <math>\displaystyle 1</math>, zamień go na <math>\displaystyle \clubsuit</math> i przejdź do prawego markera. Dopisz do słowa symbol <math>\displaystyle \clubsuit</math> (zwiększając tym samym długość słowa na taśmie o <math>\displaystyle 1</math>). Następnie powtórz cykl od <math>\displaystyle 2</math>.
# Jeśli napotkałeś marker, idź w prawo, zamieniając wszystkie wystąpienia <math>\displaystyle \clubsuit</math> na <math>\displaystyle 1</math>. Następnie wracaj do lewego markera i zatrzymaj się, akceptując.
 
}}
 
{{kotwica|tw.1.1|}}{{twierdzenie|1.1 liniowa kompresja pamięci||
 
Niech będzie dany język <math>\displaystyle L</math> oraz maszyna Turinga
<math>\displaystyle \mathcal{TM}</math> akceptująca <math>\displaystyle L</math> w pamięci <math>\displaystyle s(n)</math>. Dla dowolnego
<math>\displaystyle \varepsilon>0</math> istnieje maszyna Turinga <math>\displaystyle \mathcal{TM}'</math> akceptująca <math>\displaystyle L</math> w
pamięci <math>\displaystyle \max\left\{n,\varepsilon s(n)\right\}</math>.
}}
 
{{dowod|||
(''Szkic'')
Ustalamy liczbę naturalną <math>\displaystyle k</math>, dla której <math>\displaystyle \varepsilon k\geqslant 2</math>. Maszynę
<math>\displaystyle \mathcal{TM}'</math> definiujemy następująco:
# Przekoduj słowo wejściowe, łącząc po <math>\displaystyle r</math> kolejnych symboli w jeden blok stanowiący nowy symbol na taśmie.
# Symuluj maszynę <math>\displaystyle \mathcal{MT}</math> na skompresowanej taśmie. Położenie głowicy wewnątrz bloku zakoduj w stanach maszyny <math>\displaystyle \mathcal{MT}'</math>.
 
Zauważmy, że w kroku <math>\displaystyle 1</math>. maszyna <math>\displaystyle \mathcal{MT}'</math> wykorzystuje <math>\displaystyle n</math>
komórek pamięci do odczytania słowa wejściowego. Kompresja taśmy
zapewnia, że podczas symulowania maszyny <math>\displaystyle \mathcal{MT}</math> nie
wykorzystamy więcej niż <math>\displaystyle \lceil \frac{s(n)}{k}\rceil \leqslant \varepsilon s(n)</math>
komórek. Jednocześnie można założyć, że <math>\displaystyle \mathcal{MT}'</math> akceptuje
słowa wejściowe z języka <math>\displaystyle L</math> o długości mniejszej niż <math>\displaystyle k</math> bez
symulowania <math>\displaystyle \mathcal{MT}</math>.
}}
 
{{twierdzenie|1.2 Savitch||
 
Dla dowolnej funkcji <math>\displaystyle s(n)</math> konstruowalnej pamięciowo spełniającej
warunek <math>\displaystyle s(n)\geqslant \log_2 n</math> prawdziwa jest inkluzja
<math>\displaystyle Nspace(s(n))\subset DSpace(s^2(n))</math>.
}}
 
{{dowod|||
Niech <math>\displaystyle \mathcal{NMT}</math> będzie niedeterministyczną maszyną Turinga
akceptującą język <math>\displaystyle L=L(\mathcal{NMT})</math> w pamięci <math>\displaystyle s(n)</math>. Niech
<math>\displaystyle k(n)</math> oznacza liczbę konfiguracji potrzebną do zaakceptowania słowa
o długości <math>\displaystyle n</math>. Istnieje liczba <math>\displaystyle c>1</math>, dla której <math>\displaystyle k(n)\leqslant c^{s(n)}</math>, co z kolei oznacza, że każde słowo o długości <math>\displaystyle n</math> jest akceptowane w <math>\displaystyle c^{s(n)}</math> krokach czasowych.
}}
Rozważmy algorytm:
 
{{algorytm|||
  1  Wejście: słowo <math>\displaystyle w</math> długości <math>\displaystyle |w|=n</math>
  2  oblicz <math>\displaystyle s(n)</math>
  3  '''for''' każda konfiguracja akceptująca <math>\displaystyle d_A</math> dla której <math>\displaystyle |d_A|\leqslant s(n)</math>
  4    '''do if''' Test(<math>\displaystyle \sharp s_0 w \sharp</math>, <math>\displaystyle d_A</math>, <math>\displaystyle s(n) \log_2 c</math>) '''then''' akceptuj
}}
 
gdzie procedura Test ma następującą postać:
 
{{algorytm|'''Procedure''' Test(<math>\displaystyle d</math>,<math>\displaystyle d'</math>,<math>\displaystyle i</math>)||
  1  '''if''' <math>\displaystyle i=0</math> '''and''' [ (<math>\displaystyle d=d'</math>) '''or''' (<math>\displaystyle d\mapsto d'</math>)] '''then return true'''
  2    '''else for''' każda konfiguracja <math>\displaystyle d''</math> dla której <math>\displaystyle |d''|\leqslant s(n)</math>
  3      '''do if''' Test(<math>\displaystyle d</math>,<math>\displaystyle d''</math>,<math>\displaystyle i-1</math>) '''and''' Test <math>\displaystyle d''</math>,<math>\displaystyle d'</math>,<math>\displaystyle i-1</math>)
  4        '''then return true''';
  5  '''return false'''
}}
 
Przedstawiony algorytm można zrealizować za pomocą wielotaśmowej
maszyny Turinga. Założenie dotyczące konstruowalności pamięciowej
jest istotnie wykorzystywane w tej konstrukcji przy implementacji
linii 3 algorytmu i linii 2 procedury Test. Musimy zaznaczyć <math>\displaystyle s(n)</math>
komórek taśmy, aby móc konstruować konfiguracje o długości
ograniczonej przez <math>\displaystyle s(n)</math> i móc następnie wykonywać na nich
symulację maszyny <math>\displaystyle \mathcal{NMT}</math>.
 
Zauważmy, że ilość konfiguracji jest ograniczona przez <math>\displaystyle s(n)</math>, a
głębokość rekursji przez <math>\displaystyle \log c^{s(n)}</math>. Oznacza to, że jesteśmy w
stanie skonstruować maszynę Turinga, która wymaga <math>\displaystyle c' s^2(n)</math> pamięci, gdzie <math>\displaystyle c'</math> jest pewną stałą. Na mocy Twierdzenia [[#tw.1.1|1.1]] jesteśmy w stanie określić maszynę <math>\displaystyle \mathcal{MT}</math> działającą w pamięci <math>\displaystyle s^2(n)</math>.
 
{{wniosek|1.1||
<center> '''PSPACE''' <math>\displaystyle  = </math> '''NPSPACE''' </center>
 
}}
 
{{lemat|1.1||
Jeśli <math>\displaystyle g(n)\geqslant n</math>, to <math>\displaystyle Dtime(g(n))\subset Dspace(g(n))</math> oraz
<math>\displaystyle Ntime(g(n))\subset Nspace(g(n))</math>.
}}
 
{{dowod|||
Niech będzie dana maszyna deterministyczna <math>\displaystyle \mathcal{MT}</math>
akceptująca dany język <math>\displaystyle L</math> w czasie <math>\displaystyle g(n)</math>. Do akceptacji słowa <math>\displaystyle w</math>
o długości <math>\displaystyle n</math> maszyna wykorzystuje co najwyżej <math>\displaystyle g(n)</math> kroków
czasowych, czyli odwiedza co najwyżej <math>\displaystyle g(n)+1</math> komórek taśmy.
 
Na podstawie Twierdzenia [[#tw.1.1|1.1]] istnieje maszyna Turinga
<math>\displaystyle \mathcal{MT}'</math> wykorzystująca
<center><math>\displaystyle
\max \left\{n, \frac{1}{2}(g(n)+1)\right\}\leqslant g(n)
</math></center>
 
komórek pamięci. Dla niedeterministycznych maszyn Turinga argumentacja
jest identyczna.
}}
 
{{wniosek|1.2||
<center> '''P''' <math>\displaystyle  \subset  </math> '''NP''' <math>\displaystyle  \subset
</math> '''PSPACE''' <math>\displaystyle  = </math> '''NPSPACE''' </center>
 
}}
 
{{uwaga|1.2||
Nie jest znany przykład wykazujący silną inkluzję '''P''' <math>\displaystyle  \varsubsetneq  </math> '''NP''' ani dowód wykluczający istnienie takiego przykładu. Powszechnie uznawana
hipoteza głosi:
<center> '''P''' <math>\displaystyle  \neq  </math> '''NP'''. </center>
 
Rozstrzygnięcie jej prawdziwości lub fałszywości stanowi jeden z
najważniejszych, a zarazem najtrudniejszych problemów współczesnej
informatyki. Jak widzieliśmy w Przykładzie [[#prz.1.2|1.2]], nawet w
przypadku konkretnego języka <math>\displaystyle L\in  </math> '''NP''',  problem
uzasadnienia, że także <math>\displaystyle L\in  </math> '''P''',  jest nietrywialny,
gdyż wymaga zazwyczaj konstrukcji całkiem nowej maszyny Turinga niż
ta do weryfikacji <math>\displaystyle L\in  </math> '''NP'''  .
}}
 
==Redukcja i problemy zupełne==
 
{{definicja|2.1 transformacja wielomianowa||
 
Niech <math>\displaystyle L_1,L_2</math> będą dowolnymi językami nad pewnym alfabetem
<math>\displaystyle \Sigma_I</math>. Mówimy, że <math>\displaystyle L_1</math> redukuje się do <math>\displaystyle L_2</math> w czasie
wielomianowym, co oznaczamy <math>\displaystyle L_1 \propto L_2</math>, gdy istnieje
deterministyczna maszyna Turinga <math>\displaystyle \mathcal{MT}=(\Sigma
_{T},S,f,s_{0},S_{F})</math> taka, że dla dowolnego <math>\displaystyle w\in \Sigma_I^*</math>
istnieje <math>\displaystyle w'\in \Sigma_I^*</math> i stan <math>\displaystyle s_1\in S_F</math> o własności
<center><math>\displaystyle
\sharp s_0 w \sharp \mapsto^* \sharp s_1 w' \sharp
</math></center>
 
oraz
<center><math>\displaystyle
w\in L_1 \quad \Longleftrightarrow \quad w' \in L_2.
</math></center>
 
}}
 
{{lemat|2.1||
Załóżmy, że <math>\displaystyle L_1 \propto L_2</math>. Wtedy zachodzą implikacje:
# <math>\displaystyle L_2 \in  </math> '''P''' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<math>\displaystyle \quad \Longrightarrow \quad L_1 \in  </math> '''P''',
# <math>\displaystyle L_2 \in  </math> '''NP''' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<math>\displaystyle \quad \Longrightarrow \quad L_1 \in  </math> '''NP''',
# <math>\displaystyle L_2 \in  </math> '''PSPACE''' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<math>\displaystyle \quad \Longrightarrow \quad L_1 \in  </math> '''PSPACE'''.
 
}}
 
{{dowod|||
Dane słowo <math>\displaystyle w</math> transformujemy do <math>\displaystyle w'</math> w czasie wielomianowym, co gwarantuje założenie <math>\displaystyle L_1 \propto L_2</math>. Dzięki założeniu <math>\displaystyle L_2 \in </math> '''P'''  możemy rozstrzygnąć, czy <math>\displaystyle w'\in L_2</math> (tzn. jeśli akceptujemy <math>\displaystyle w'</math>, to robimy to w czasie wielomianowym). Tym sposobem (korzystając z definicji transformacji wielomianowej) akceptujemy <math>\displaystyle w</math> w czasie wielomianowym, o ile tylko <math>\displaystyle w\in L_1</math>. Dowód dla pozostałych implikacji jest identyczny.
}}
 
{{definicja|2.2||
Niech <math>\displaystyle \mathcal{C}</math> oznacza pewną klasę języków. Język <math>\displaystyle L</math> nazywamy '''<math>\displaystyle \mathcal{C}</math>-trudnym''', jeśli spełniony jest warunek:
<center><math>\displaystyle
\forall\; L' \in \mathcal{C} \quad L'\propto L.
</math></center>
 
Jeżeli dodatkowo spełniony jest warunek <math>\displaystyle L\in \mathcal{C}</math>, to język <math>\displaystyle L</math> nazywamy '''<math>\displaystyle \mathcal{C}</math>-zupełnym'''.
}}
 
Intuicyjnie, fakt, że język jest <math>\displaystyle \mathcal{C}</math>-zupełny, oznacza, że jest on najbardziej skomplikowany (pod względem obliczeniowym) wśród języków z klasy <math>\displaystyle \mathcal{C}</math>, natomiast język <math>\displaystyle \mathcal{C}</math>-trudny jest bardziej skomplikowany niż każdy z klasy
<math>\displaystyle \mathcal{C}</math>, choć sam nie musi do niej należeć.
 
{{uwaga|2.1||
Rozważając klasę  '''P''' ,  '''NP'''  i '''PSPACE''',  możemy mówić o językach (problemach) '''P''' -zupełnych,  '''NP''' -zupełnych, czy też  '''PSPACE''' -zupełnych. To samo odnosi się do
języków trudnych (tzn. klasa języków  '''P''' -trudnych, itd.).
}}
 
{{przyklad|2.1||
Rozważmy języki:
<center><math>\displaystyle
L_1=\left\{1^i 2^j 3^k\: k=i\cdot j,\: i,j\geqslant 1\right\}\quad,\quad
L_2=\left\{1^i 2^j 4^{2k}\: k=i\cdot j,\: i,j\geqslant 1\right\}.
</math></center>
 
Języki: <math>\displaystyle L_1</math> oraz <math>\displaystyle L_2</math> wyglądają na bardzo podobne, zatem wydaje się, że <math>\displaystyle L_1 \propto L_2</math> oraz <math>\displaystyle L_2 \propto L_1</math>. Uzasadnienie tego faktu jest prawie natychmiastowe.
}}
Konstruujemy deterministyczną maszynę Turinga która działa w
następujący sposób:
# {{kotwica|prz.1|}} Jeśli słowo wejściowe jest puste, to stop.
# Przejdź do prawego ogranicznika. Jeśli przy ograniczniku nie występuje symbol <math>\displaystyle 4</math>, to wykonaj krok [[#prz.1|1]].
# Jeśli w słowie wejściowym występuje symbol <math>\displaystyle 4</math>, to sprawdź, czy słowo przetwarzane jest postaci <math>\displaystyle \sharp w 4^s \sharp</math>, gdzie <math>\displaystyle s\geqslant 1</math> oraz <math>\displaystyle w\in (\Sigma_I\setminus \left\{4\right\})^*</math> oraz czy dodatkowo <math>\displaystyle s</math> jest liczbą parzystą. Jeśli nie, to wykonaj krok [[#prz.1|1]].
# Zamień słowo <math>\displaystyle 4^s</math> na słowo <math>\displaystyle 3^{\frac{s}{2}}\sharp^{\frac{s}{2}}</math> i wykonaj krok [[#prz.1|1]].
# Przejdź nad pierwszy symbol po lewym ograniczniku i zatrzymaj się.
 
W ten sposób zawsze przeprowadzamy konfigurację <math>\displaystyle \sharp s_0 w \sharp
</math> na konfigurację <math>\displaystyle \sharp s_1 w' \sharp</math>, przy czym <math>\displaystyle w'=1^i 2^j 3^k</math>
tylko, gdy <math>\displaystyle w=1^i 2^j 4^{2k}</math>. Zatem <math>\displaystyle w\in L_2</math> wtedy i tylko wtedy, gdy <math>\displaystyle w'\in L_1</math>. Wykazaliśmy, że <math>\displaystyle L_2 \propto L_1</math>.
 
Warunek <math>\displaystyle L_1 \propto L_2</math> otrzymujemy w sposób identyczny. Trzeba
tylko wypisać odpowiednią ilość symboli <math>\displaystyle 4</math> (a wiemy już, jak
konstruować liczbę <math>\displaystyle 2n</math>, mając dane <math>\displaystyle n</math>).

Aktualna wersja na dzień 20:09, 29 wrz 2006

5555555555555555555555555555555555555555 Logika



10101010101010101010101010101010101010101010101010 Logika