THEORETISCHE INFORMATIK Vorlesungsskript Jiřı́ Adámek Institut für Theoretische Informatik Technische Universität Braunschweig April 2006 Inhaltsverzeichnis 1 Endliche Automaten 1 1.1 Mathematische Grundbegriffe . . . . . . . . . . . . . . . . . . . . . . 2 1.2 Definition der endlichen Automaten . . . . . . . . . . . . . . . . . . 6 1.3 Nichtdeterministische Automaten . . . . . . . . . . . . . . . . . . . . 10 1.4 Reguläre Sprachen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.5 Minimierung von Automaten . . . . . . . . . . . . . . . . . . . . . . 21 1.6 Nerode-Äquivalenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 1.7 Beweise der Regularität . . . . . . . . . . . . . . . . . . . . . . . . . 27 1.8 Moore- und Mealy-Automaten . . . . . . . . . . . . . . . . . . . . . 30 2 Kontextfreie Sprachen und Kellerautomaten 33 2.1 Die Idee einer formalen Grammatik . . . . . . . . . . . . . . . . . . . 33 2.2 Kontextfreie Grammatik . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.3 Ableitungsbäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.4 Kontextfreie und reguläre Sprachen . . . . . . . . . . . . . . . . . . . 43 2.5 Eigenschaften kontextfreier Sprachen . . . . . . . . . . . . . . . . . . 48 2.6 Nullierbare Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 2.7 Chomsky-Normalform . . . . . . . . . . . . . . . . . . . . . . . . . . 56 2.8 Algorithmen für formale Sprachen . . . . . . . . . . . . . . . . . . . 61 2.9 Kellerautomaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 2.10 Kellerautomaten und kontextfreie Sprachen . . . . . . . . . . . . . . 68 3 Turingmaschinen 73 3.1 Definition einer Turingmaschine . . . . . . . . . . . . . . . . . . . . . 73 3.2 Modifikationen von Turingmaschinen . . . . . . . . . . . . . . . . . . 79 3.2.1 TM mit mehreren finalen Zuständen . . . . . . . . . . . . . . 79 3.2.2 TM mit zusätzlichem Gedächtnis . . . . . . . . . . . . . . . . 79 3.2.3 TM mit erweitertem Bandalphabet . . . . . . . . . . . . . . . 80 3.2.4 TM mit mehrspurigem Band . . . . . . . . . . . . . . . . . . 80 3.2.5 TM mit mehreren Bändern . . . . . . . . . . . . . . . . . . . 82 3.3 Entscheidbare Probleme und rekursive Sprachen . . . . . . . . . . . 85 i ii INHALTSVERZEICHNIS 3.4 Nichtdeterministische Turingmaschinen . . . . . . . . . . . . . . . . . 90 3.5 Berechenbare Funktionen . . . . . . . . . . . . . . . . . . . . . . . . 93 4 Churchsche These 97 4.1 RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 4.2 RAM-Berechenbarkeit . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4.3 Grammatiken und Turingmaschinen . . . . . . . . . . . . . . . . . . 103 4.4 Chomsky-Hierarchie . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 4.5 Rekursive Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . 110 5 Unentscheidbare Probleme 117 5.1 Universelle Turingmaschine . . . . . . . . . . . . . . . . . . . . . . . 117 5.2 Das Halteproblem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 5.3 Weitere unentscheidbare Probleme . . . . . . . . . . . . . . . . . . . 124 5.3.1 Das Akzeptanzproblem . . . . . . . . . . . . . . . . . . . . . 124 5.3.2 Akzeptanz des leeren Wortes . . . . . . . . . . . . . . . . . . 125 5.3.3 Ist eine TM ein Algorithmus? . . . . . . . . . . . . . . . . . . 126 5.3.4 Satz von Rice . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 5.3.5 Minimierung von Turingmaschinen . . . . . . . . . . . . . . . 129 6 Komplexität von Algorithmen 131 6.1 Beispiele effizienter Algorithmen . . . . . . . . . . . . . . . . . . . . 132 6.2 Komplexitätsklasse P . . . . . . . . . . . . . . . . . . . . . . . . . . 138 6.3 Berechnungsprobleme und Reduzierbarkeit . . . . . . . . . . . . . . . 142 6.4 Robustheit der Klasse P . . . . . . . . . . . . . . . . . . . . . . . . . 147 6.4.1 TM mit zusätzlichem Gedächtnis . . . . . . . . . . . . . . . . 148 6.4.2 TM mit mehrspurigem Band . . . . . . . . . . . . . . . . . . 148 6.4.3 Mehr-Band TM . . . . . . . . . . . . . . . . . . . . . . . . . . 148 6.4.4 RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 6.5 Geometrische Algorithmen und reelle RAM . . . . . . . . . . . . . . 150 6.6 Komplexitätsklasse N P . . . . . . . . . . . . . . . . . . . . . . . . . 161 6.7 N P-Vollständigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 6.8 Weitere N P-vollständige Probleme . . . . . . . . . . . . . . . . . . . 168 6.9 Komplexitätsklasse coN P . . . . . . . . . . . . . . . . . . . . . . . . 172 6.10 Komplexität von Optimierungsproblemen . . . . . . . . . . . . . . . 174 6.11 Approximation von Optimierungsproblemen . . . . . . . . . . . . . . 180 6.12 Raumkomplexität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 7 Parallele Algorithmen 7.1 Algorithmen für eine PRAM 191 . . . . . . . . . . . . . . . . . . . . . . 191 7.2 Simulationen von PRAM Modellen . . . . . . . . . . . . . . . . . . . 198 INHALTSVERZEICHNIS iii 7.3 Komplexitätsklasse N C . . . . . . . . . . . . . . . . . . . . . . . . . 199 7.4 Boolesche Schaltkreise und PRAMs . . . . . . . . . . . . . . . . . . . 202 7.5 Netzwerk-Modelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 7.5.1 Ring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 7.5.2 Zweidimensionales Gitter . . . . . . . . . . . . . . . . . . . . 213 7.5.3 Hypercube . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 iv INHALTSVERZEICHNIS Kapitel 3 Turingmaschinen Weder endliche Automaten noch Kellerautomaten sind genügend starke Berechnungsmodelle, denn sie sind nicht fähig, selbst so einfache Sprachen wie z. B. {an bn cn ; n ≥ 1} zu akzeptieren. Wir führen jetzt ein Modell einer Maschine ein, die eine sehr starke Leistung hat, obwohl die Definition nicht komplizierter als die der Kellerautomaten ist: die Turingmaschinen. Diese Maschinen wurden von Alan Turing in den dreißiger Jahren als Formalisierung des intuitiven Begriffs des Algorithmus eingeführt. Turing versuchte zu zeigen, dass jeder Rechenprozess, den ein Mensch aufgrund einer (endlichen, eindeutigen) Anweisung durchführen kann, auch automatisch von einer Maschine durchgeführt werden kann. Was einem menschlichen Rechner zur Verfügung steht, ist eine endliche Liste von Instruktionen, die zusammen mit den Daten in seinem Gedächtnis eine endliche Menge von (inneren) Zuständen formt. Außerdem hat er einen unbeschränkten Raum, in dem er lesen, schreiben und überschreiben darf. Das kann (zweidimensional) durch einen beliebig erweiterbaren Papierstoß realisiert werden, oder äquivalent, falls alle Zeilen als Erweiterungen der ersten angesehen werden, als ein (eindimensionales) unendliches Band. Das formale Modell ist dann dem eines Kellerautomaten ähnlich: anstelle des Kellers gibt es hier ein Band, auf dem sich ein read-and-write-Kopf unbeschränkt bewegt. Die Leistungsfähigkeit von Turingmaschinen ist trotzdem unvergleichlich größer als die der Kellerautomaten. Es zeigt sich, dass die Klasse aller Probleme, die mit Turingmaschinen gelöst werden können, dieselbe ist wie die Klasse aller Probleme, die moderne Rechner mit modernen Programmiersprachen lösen können. Die Churchsche These, die wir später genauer erläutern, behauptet, dass die Turingmaschine sogar ein ganz allgemeines Modell des Begriffs des Algorithmus ist. Also kann ein Problem genau dann mit einem Algorithmus gelöst werden, wenn eine Turingmaschine es lösen kann. Diese These kann nicht bewiesen werden (der Begriff des Algorithmus ist eben doch nur intuitiv), aber sie wurde mehrmals überzeugend dadurch untermauert, dass andere – oft grundsätzlich verschiedene – Berechnungsmodelle dieselbe Klasse lösbarer Probleme ergeben. 3.1 Definition einer Turingmaschine Eine Turingmaschine besteht – analog zum Kellerautomaten – aus inneren Zuständen, externem Speicher und einer Betriebseinheit, die aufgrund des momentanen Zustandes und des gerade gelesenen Symbols entscheidet, welcher der nächste Zustand ist und wie der Speicher geändert wird. Im Vergleich zu Kellerautomaten 73 74 KAPITEL 3. TURINGMASCHINEN hat hier der Speicher den Typ eines (unbeschränkten) Bandes, auf dem sich ein Lese-/Schreibkopf frei bewegt: ... a b b a ... ⇑ Band ww Kopf ww w w ww ww w {w w Betriebseinheit • q0 q3 • • • q1 • q2 (Obwohl das Band unbeschränkt ist, ist zu jedem Zeitpunkt nur ein endlicher Teil beschrieben; der Rest ist leer.) Noch ein Unterschied im Vergleich zu den Kellerautomaten: wir arbeiten zuerst nur mit deterministischen Turingmaschinen, denn sie sind (wie im Fall der endlichen Automaten) genauso leistungsfähig wie die nichtdeterministischen. Das beweisen wir später. Die Übergangsfunktion δ einer Turingmaschine entscheidet aufgrund des momentanen Zustandes q und des gerade gelesenen Bandsymbols s, ob 1. sich der Zustand zu q 0 ändert und sich der Kopf nach links (L) oder rechts (R) bewegt oder 2. sich der Zustand zu q 0 ändert und der Kopf das momentane Bandsymbol mit einem neuen Symbol s0 überschreibt. Das beschreiben wir als Funktion δ(q, s) = (q 0 , s0 ), wobei s0 = L, R oder s0 ∈ Σ ist. (Σ ist das gegebene Eingabealphabet). Wir müssen aber auch Bandfelder, die nicht beschriftet sind, behandeln. Dazu führen wir ein Spezialsymbol # (Blank) ein, das unbeschriftete Felder bezeichnet. In der Formel δ(q, s) = (q 0 , s0 ) sind q und q 0 also Zustände, s ein Symbol aus Σ ∪ {#} und s0 ein Symbol aus Σ ∪ {#,L,R}. Obwohl die Turingmaschine, wie wir sie jetzt definieren, deterministisch ist, gibt es neben 1. und 2. noch eine weitere Möglichkeit für ihr Verhalten, nämlich dass 3. die Maschine im Zustand q auf dem Bandsymbol s hält und die Berechnung endet. Formal wird dies dadurch beschrieben, dass δ(q, s) nicht definiert ist. Hier ist δ also eine partielle Funktion. Es gibt einen wichtigen Grund für diesen dritten Fall: der Kopf der Turingmaschine ist kein read-only-Kopf (wie im Fall der endlichen Automaten und Kellerautomaten). Der Impuls, eine Berechnung zu beenden, erfolgt hier also nicht durch das Ende der Eingabe. Im Vergleich mit den DEA oder Kellerautomaten ergibt sich eine kleine Vereinfachung: es genügt ein finaler Zustand, wir brauchen keine Menge F ⊆ Q (vergleiche 3.2 unten). Definition. Eine Turingmaschine (TM) ist ein Fünftupel M = (Q, Σ, δ, q0 , qF ) wobei 3.1. DEFINITION EINER TURINGMASCHINE Q Σ δ q0 ∈ Q qF ∈ Q 75 eine endliche Menge (aller Zustände), eine endliche Menge (das Eingabealphabet), die die Symbole L, R und # nicht enthält, eine partielle Funktion (die Übergangsfunktion) mit Definitionsbereich Q × (Σ ∪ {#}) und Wertebereich Q × (Σ ∪ {#,L,R}), der Initialzustand und der Finalzustand ist. Notation. Wir schreiben statt δ(q, s) = (q 0 , s0 ) oft nur (q, s) → (q 0 , s0 ) und sprechen von Übergangsregeln. Wir bezeichnen durch Σ die Menge Σ = Σ ∪ {#}. Beispiel 1. Teilbarkeit durch 5. Der Algorithmus, der für eine Zahl entscheidet, ob sie durch 5 teilbar ist, ist einfach: akzeptiert werden Zahlen mit der letzten Ziffer 0 oder 5. Wir lesen also die Eingabe s1 . . . sn bis wir das letzte beschriebene Feld sn erreichen (also: bis # erscheint und dann einen Schritt zurück). Falls sn = 0 oder 5, gehen wir in den Finalzustand qF über: (q0 , i) → (q0 , R) für i = 0, 1, . . . , 9 (wir lesen weiter) (q0 , #) → (q1 , L) einen Schritt zurück und in den neuen Zustand q1 (q1 , 0) → (qF , 0) falls sn = 0 oder 5, ist der letzte Zustand qF (q1 , 5) → (qF , 5) Genauer: die folgende TM M = ({q0 , q1 , qF }, {0, 1, . . . , 9}, δ, q0 , qF ), deren Übergangsregeln oben aufgelistet sind, akzeptiert die Sprache aller Wörter über Σ = {0, 1, . . . , 9}, die mit 0 oder 5 enden. Beispiel einer Berechnung: für die Eingabe 132 wird die TM die folgenden Schritte machen: ... # # 1 3 2 # # # # ... Initialkonfiguration ⇑ q0 ... # # 1 3 2 # # # # ... ⇑ q0 ... # # 1 3 2 # # # # ... ⇑ q0 ... # # 1 3 2 # # # # ... ⇑ q0 ... # # 1 3 2 # # # # ... Haltekonfiguration ⇑ q1 Da kein Übergang (q1 , 2) → definiert ist, hält hier die Turingmaschine. Die Eingabe 132 wird nicht akzeptiert, da q1 nicht der Finalzustand ist. 76 KAPITEL 3. TURINGMASCHINEN Die Berechnung von Eingaben formalisieren wir jetzt. Konfigurationen: Eine Konfiguration einer Turingmaschine ist die vollständige Information über die TM zu einem Zeitpunkt der Berechnung; sie wird durch (1) den momentanen Zustand q, (2) den Inhalt des Bandes und (3) die Position des Kopfes bestimmt. Also ist (1) ein Element der Menge Q. Wir können (2) und (3) zusammenfassen, indem wir sagen, welches Wort u links vom Kopf steht, welches Wort v rechts steht und welches Symbol a aus Σ = Σ ∪ {#} der Kopf liest. Dabei ist u entweder leer, oder hat das erste Symbol aus Σ und die weiteren aus Σ: ∗ u ∈ Σ × Σ ∪ {ε}. ∗ Analog v ∈ Σ × Σ ∪ {ε}. Eine Konfiguration ist also ein Quadrupel ∗ ∗ (q, u, a, v), wobei q ∈ Q, u ∈ Σ × Σ ∪ {ε}, a ∈ Σ und v ∈ Σ × Σ ∪ {ε}. Die Menge ∗ ∗ K = Q × (Σ × Σ ∪ {ε}) × Σ × (Σ × Σ ∪ {ε}) heißt Konfigurationsmenge. Die üblichere (und übersichtlichere) Schreibweise ist, u, a, v zu konkatenieren und a zu unterstreichen: (q, uav). In Beispiel 1 in Abschnitt 3.1 hat die Berechnung also die Konfigurationen (q0 , 132) (q0 , 132) (q0 , 132) (q0 , 132#) und (q1 , 132) Berechnung: Die Eingabe s1 s2 . . . sn ∈ Σ ∗ wird immer so auf das Band geschrieben, dass die Buchstaben ohne Leerzeichen hintereinander stehen. Der Kopf wird auf den ersten Buchstaben gestellt und der Zustand ist initial. Mit anderen Worten heißt das: wir erwarten am Anfang, dass die Konfiguration die folgende Form hat: (∗) (q0 , s1 s2 . . . sn ), wobei s1 . . . sn ∈ Σ∗ . Der Fall der leeren Eingabe ε ∈ Σ∗ (also n = 0) entspricht der Konfiguration (q0 , #). Konfigurationen der Form (∗) heißen Initialkonfigurationen. Falls die Turingmaschine eine Konfiguration (q, s1 s2 . . . si−1 si si+1 . . . sn ) erreicht hat, gibt es zwei Möglichkeiten: entweder ist δ(q, si ) nicht definiert, dann heißt die Konfiguration Haltekonfiguration, oder es gilt δ(q, si ) = (q 0 , s0 ) mit s0 ∈ {L,R} ∪ Σ, dann definieren wir die Folgekonfiguration wie folgt: 1. falls s0 =L, dann ist die Folgekonfiguration (q 0 , s1 s2 . . . si−1 si si+1 . . . sn ) 2. falls s0 =R, dann ist die Folgekonfiguration (q 0 , s1 s2 . . . si−1 si si+1 . . . sn ) 3. falls s0 ∈ Σ, dann ist die Folgekonfiguration (q 0 , s1 s2 . . . si−1 s0 si+1 . . . sn ). Diese Definition ist in Tabelle 3.1 zusammengefasst. 3.1. DEFINITION EINER TURINGMASCHINE Konfiguration (q, s1 s2 . . . si−1 si si+1 . . . sn ) (q, s1 s2 . . . si−1 si si+1 . . . sn ) (q, s1 s2 . . . si−1 si si+1 . . . sn ) (q, s1 s2 . . . si−1 si si+1 . . . sn ) δ(q, si ) (q 0 , L) (q 0 , R) (q 0 , s0 ) nicht definiert 77 Folgekonfiguration (q , s1 s2 . . . si−1 si si+1 . . . sn ) (q 0 , s1 s2 . . . si−1 si si+1 . . . sn ) (q 0 , s1 s2 . . . si−1 s0 si+1 . . . sn ) keine (Haltekonfiguration) 0 Tabelle 3.1: Definition der Folgekonfiguration der TM Bemerkung 1. Wie ist der Fall 1 zu verstehen, falls i = 1 gilt? Die Folgekonfiguration zu (q0 , s1 . . . sn ) ist natürlich (q 0 , #s1 . . . sn ). Analog folgt im Fall 2 aus i = n, dass die Folgekonfiguration (q 0 , s1 . . . sn #) ist. Notation. Die Relation Folgekonfiguration“ auf der Menge K aller Konfiguratio” nen bezeichnen wir mit dem Symbol `. Also ergibt der 1. Fall (q, s1 s2 . . . si−1 si si+1 . . . sn ) ` (q 0 , s1 s2 . . . si−1 si si+1 . . . sn ) usw. Die reflexive und transitive Hülle dieser Relation wird mit `∗ bezeichnet; d.h., K `∗ K 0 bedeutet, dass K und K 0 zwei Konfigurationen sind, die entweder gleich sind oder dass es Konfigurationen K = K 0 , K1 , . . . , K n = K 0 mit Ki−1 ` Ki für i = 1, . . . , n gibt. Wir sagen, dass die Konfiguration K 0 von K berechenbar ist. In Beispiel 1 in Abschnitt 3.1 gilt (q0 , 132) ` (q0 , 132) ` . . . ` (q1 , 132) und, die letzte Konfiguration hat keine Folgekonfiguration, da sie eine Haltekonfiguration ist. Definition. Für jede Turingmaschine ist die Berechnung einer Eingabe s1 s2 . . . sn ∈ Σ∗ eine endliche oder unendliche Liste von Konfigurationen: K0 ` K1 ` K2 ` . . . wobei 1. K0 die Initialkonfiguration mit K0 = (q0 , s1 s2 . . . sn ) ist, und 2. falls die Liste endlich ist, ist die letzte Konfiguration eine Haltekonfiguration. Wir sagen, dass die Turingmaschine die Eingabe genau dann akzeptiert, wenn ihre Berechnung endlich ist und der Zustand der letzten Konfiguration final ist. Bemerkung 2. Die Berechnung einer Eingabe w hat also drei mögliche Ergebnisse: 1. die TM hält und akzeptiert w, 2. die TM hält und akzeptiert w nicht, 3. die TM hält nicht (und akzeptiert w deshalb nicht). Am Anfang ist die Eingabe kompakt“, also ohne Unterbrechung (durch #) auf dem ” Band geschrieben. Im Verlauf der Berechnung kann # an jeder Stelle erscheinen. Beispiel 2. In Beispiel 1 in Abschnitt 3.1 haben wir die Berechnung der Eingabe 132 beschrieben. Die letzte Konfiguration ist (q1 , 132). Da q1 nicht final ist, wird 132 nicht akzeptiert. Auch das leere Wort wird nicht akzeptiert: hier haben wir eine 1-Schritt-Berechnung, denn (q0 , #) ist eine Haltekonfiguration, und q0 ist nicht final. 78 KAPITEL 3. TURINGMASCHINEN Diese Turingmaschine hält auf jede Eingabe (eine wichtige Eigenschaft, wie wir später erfahren werden) und akzeptiert genau die Eingaben, deren letztes Symbol 0 oder 5 ist. Definition. Für jede Turingmaschine M = (Q, Σ, δ, q0 , F ) bezeichnen wir mit L(M ) die Sprache aller Wörter über Σ, die M akzeptiert. Beispiel 3. Eine Turingmaschine, die die Sprache aller Wörter [an bn cn ] für n ≥ 1 über Σ = {a, b, c, [, ]} akzeptiert. (Diese Sprache ist nicht kontextfrei – beweisen sie es!) Wir simulieren den folgenden primitiven Algorithmus: (i) lösche ein a und gehe nach rechts, solange ein a gelesen wird, (ii) lösche ein b und gehe nach rechts, solange ein b gelesen wird, (iii) lösche ein c und gehe nach links; am Ende: (iv) akzeptiere genau dann, wenn alle Felder zwischen [ und ] leer sind. Schritt (i) wird wie folgt implementiert: 1. (q0 , [ ) → (q1 ,R) 2. (q1 , a) → (q2 , #) 3. (q2 , #) → (q2 ,R) 4. (q2 , a) → (q2 ,R) Schritt (ii) analog: 5. (q2 , b) → (q3 , #) 6. (q3 , #) → (q3 ,R) 7. (q3 , b) → (q3 ,R) und Schritt (iii) wie folgt: 8. (q3 , c) → (q4 , #) 9. (q4 , x) → (q4 ,L) für x = #, a, b 10. (q4 , [ ) → (q1 ,R) 11. (q1 , #) → (q1 ,R) Schritt (iv) entspricht der Situation, in der im Zustand q1 am Ende das Symbol ] gelesen wird: 12. (q1 , ] ) → (qF , ] ) Das heißt, dass die folgende TM: M = ({q0 , q1 , q2 , q3 , q4 , qF }, {a, b, c, [, ]}, δ, q0, qF ), mit δ durch 1. bis 12. gegeben, die Sprache {[an bn cn ] ; n ≥ 1} akzeptiert. Beispiel einer Berechnung: das Wort [aac] wird wie folgt berechnet: (q0 , [aac] ) ` (q0 , [aac] ) ` (q1 , [#ac] ) ` (q1 , [#ac] ) ` (q1 , [#ac] ) und die TM hält, denn es ist kein Übergang (q1 , c) →? definiert. Das Wort [aac] wird also nicht akzeptiert. 3.2. MODIFIKATIONEN VON TURINGMASCHINEN 3.2 79 Modifikationen von Turingmaschinen Wir behaupteten in der Einleitung zu diesem Kapitel, dass Turingmaschinen zu einer starken Leistung fähig sind. Das ist auf den ersten Blick nicht leicht zu erkennen. Aber wir führen jetzt kompliziertere Maschinen ein, mit deren Hilfe schon recht komplizierte Sprachen akzeptiert werden können. Anschließend zeigen wir, dass sich alle diese neuen Maschinen auf den einfachen Fall reduzieren lassen. (Das ist keine Überraschung: erinnern wir uns an die Churchsche These, die behauptet, dass sich alle Berechnungsmodelle auf TM reduzieren lassen!) 3.2.1 TM mit mehreren finalen Zuständen Wir können das Konzept der Turingmaschinen zu einer Maschine M = (Q, Σ, δ, q0 , F ) verallgemeinern, die der obigen entspricht, nur ist F ⊆ Q eine Menge finaler Zustände. Jede solche Maschine kann durch die folgende TM M 0 = (Q ∪ {qF }, Σ, δ 0 , q0 , qF ) simuliert werden: qF ist ein neuer Zustand, und δ 0 besteht aus allen Übergangsregeln, die in δ enthalten sind, und zusätzlich werden in δ 0 noch die folgenden Regeln (q, s) → (qF , s) aufgenommen, wobei q ∈ F ein Zustand ist, für den δ(q, s) undefiniert ist. (Also führen Haltekonfigurationen (q, s) von M , bei denen q final ist, zu Haltekonfigurationen (qF , s) von M 0 .) 3.2.2 TM mit zusätzlichem Gedächtnis Wir können die Definition einer TM so modifizieren, dass die Maschine in jedem Schritt zusätzlich einen Zugriff auf ein Gedächtnis hat, wobei Symbole eines endlichen Alphabets A = {a1 , . . . , am } gespeichert werden. Die Übergangsfunktion δ entscheidet jetzt aufgrund (1) des Zustandes, (2) des gelesenen Symbols aus Σ∪{#} und (3) des gespeicherten Symbols aus A. Für Initialkonfigurationen nehmen wir an, dass ein ausgewähltes Symbol a0 ∈ A gemerkt wird. Beispiel 1. Die Sprache aller Wörter, deren erstes Symbol nie wieder vorkommt, also L = {s1 . . . sn ∈ Σ∗ ; s1 6= si für i = 2, . . . , n}, kann durch eine TM mit zusätzlichem Gedächtnis wir folgt akzeptiert werden: die TM liest das erste Symbol und speichert es im Gedächtnis (also A = Σ, d.h., das zusätzliche Gedächtnis kann ein Symbol aus Σ speichern). Dann vergleicht die TM die anschließend gelesenen Symbole mit dem gespeicherten und hält und akzeptiert nicht, falls sie eine Übereinstimmung feststellt. Sobald die TM das Blanksymbol liest, hält sie und akzeptiert. Diese TM braucht nur zwei Zustände: q0 , initial und final, in dem s1 gespeichert wird, und q1 , in dem nach rechts gegangen und mit dem Speicher verglichen wird. Bemerkung 1. Eine TM mit zusätzlichem Gedächtnis ist eigentlich eine TM in dem vorher definierten Sinne, deren Zustandsmenge das kartesische Produkt Q×A ist (d. h. die Menge aller Paare (q, a), wobei q ein Zustand und a ∈ A ist). Die Übergänge der Maschine sind also von (q, a) ∈ Q × A und s ∈ S abhängig. Der Initialzustand ist (q0 , a0 ), und alle Zustände (qF , a), a ∈ A, sind final. Zum Beispiel gilt für die Maschine aus Beispiel 1 in Abschnitt 3.1, dass A = Σ (mit s0 ∈ Σ beliebig gewählt) und die Zustandsmenge Q = {q0 , q1 } × Σ = {(qi , s); i = 0, 1 und s ∈ Σ} 80 KAPITEL 3. TURINGMASCHINEN ist. Wir können sie wie folgt als normale“ TM beschreiben, wobei der Initialzustand ” (q0 , s0 ) auch final ist: M = (Q, Σ, δ, (q0 , s0 ), (q0 , s0 )) mit den folgenden Übergangsregeln: ((q0 , s0 ), s) → ((q1 , s), R) für alle s ∈ Σ ((q1 , s), s0 ) → ((q1 , s), R) für alle s0 ∈ Σ, s0 6= s ((q1 , s), #) → ((q0 , s0 ), #). Zum Beispiel wird die Eingabe stt(t 6= s) wie folgt berechnet: ((q0 , s0 ), stt) ` ((q1 , s), stt) ` ((q1 , s), stt) ` ((q1 , s), stt#) ` ((q0 , s0 ), stt#). Hier hält die TM und akzeptiert. 3.2.3 TM mit erweitertem Bandalphabet Manchmal ist es geschickt, zusätzliche (Hilfs-)Symbole auf das Band schreiben zu dürfen, die nicht zum Eingabealphabet gehören. Das bedeutet, dass außer dem Eingabealphabet Σ noch ein Bandalphabet Γ mit Σ ⊆ Γ gegeben wird und die Übergangsfunktion δ mit allen Symbolen aus Γ arbeitet, d.h., δ ist eine partielle Funktion mit Definitionsbereich Q×(Γ∪{#}) und Wertebereich Q×(Γ∪{#, L, R}). Eine TM mit erweitertem Bandalphabet ist also ein 6-Tupel M = (Q, Σ, Γ, δ, q0 , qF ) wobei Σ ⊆ Γ das Eingabealphabet und δ : Q × (Γ ∪ {#}) → Q × (Γ ∪ {#, L, R}) eine partielle Funktion ist. Die Sprache, die M akzeptiert, ist die Sprache L(M ) ⊆ Σ∗ aller Wörter über dem (kleineren) Eingabealphabet Σ, für die M im Finalzustand hält. Beispiel 2. Eine 1-Band TM, die die Sprache {an bn cn ; n ≥ 1} akzeptiert. Hier haben wir Σ = {a, b, c}, und wir benutzen Γ = {a, b, c, [, ]}. Die TM wird erst die Eingabe mit [ und ] umklammern: (q0 , a) → (q0 , L) (q0 , #) → (q0 , [ ) (q0 , [ ) → (q1 , R) (q1 , x) → (q1 , R) füR x = a, b, c (q1 , #) → (q1 , ] ). Jetzt kann sie die TM von Beispiel 3 in Abschnitt 3.1 simulieren. Bemerkung 2. Für jede TM mit erweitertem Bandalphabet M gibt es eine ( nor” male“) TM, die M simuliert. Das Eingabealphabet der neuen TM ist das Bandalphabet Γ von M . Wir überprüfen zuerst (unter Verwendung eines zusätzlichen Gedächtnisses, das Σ beinhaltet), ob jedes Symbol der Eingabe in Σ liegt. Falls nein, hält die TM und akzeptiert nicht. Falls ja, wird weiter wie bei M berechnet. 3.2.4 TM mit mehrspurigem Band Wir arbeiten hier mit einer Modifikation von TM, die darin besteht, dass das Band in k Spuren unterteilt wird, die alle gleichzeitig gelesen werden. Stellen wir uns erst vor, dass k = 2 ist. Wir schreiben Symbole aus dem Eingabealphabet Σ = Σ1 auf Spur 1 und Symbole eines Hilfsalphabetes Σ2 auf Spur 2: ... # 0 1 0 0 1 # # # ... ... # # a # b # # a # ... ⇑ 3.2. MODIFIKATIONEN VON TURINGMASCHINEN 81 Die Maschine entscheidet in jedem Schritt abhängig vom Zustand und dem Inhalt beider Spuren (1) was der nächste Zustand wird und (2) ob sich der Kopf bewegt oder beide Spuren gleichzeitig überschrieben werden. Eine 2-Spur-TM ist eigentlich eine TM im vorher definierten Sinne, deren Bandalphabet aus Paaren (s1 , s2 ), mit s1 ∈ Σ1 und s2 ∈ Σ2 , geformt wird. Die einzige Ausnahme ist das Paar (#, #), das jetzt als Blank-Symbol dient. Also ist eine 2Spur-TM einfach eine TM mit dem Eingabealphabet Σ = Σ1 × Σ2 − {(#, #)}. Analoges gilt für k-spurige Maschinen, die auf der i-ten Spur Symbole aus Σi tragen (i = 1, . . . , k): das sind also die normalen“ TM mit Eingabealphabet ” Σ = Σ1 × Σ2 × · · · × Σk − {(#, #, . . . , #)} und mit dem Blanksymbol (#, #, . . . , #). Beispiel 3. Primzahltest Wir zeigen, wie man eine 3-spurige TM konstruiert, die die Sprache L aller Primzahlen (in binärer Darstellung) akzeptiert. Hiermit kann man auch gut die Idee von Turing illustrieren, dass jeder Algorithmus mit einer TM automatisiert werden kann. Wir verwenden hier den primitiven Algorithmus, der jede Zahl n durch alle Testzahlen 2, 3, 4, . . . , n − 1 teilt und n akzeptiert, falls alle Divisionen einen positiven Rest ergeben. EINGABESPUR TESTZAHLSPUR HILFSSPUR ... ... ... 1 0 1 1 1 1 0 1 1 0 1 1 1 ⇑ q0 ... ... ... Die Spuren der TM sind (1) Eingabespur, die während der Berechnung unverändert bleibt, (2) Testzahlspur, die am Anfang mit 1 beschriftet wird und in jedem Berechnungsdurchgang um eins vergrößert wird (sodass in dem ersten Berechnungsdurchgang durch 2 dividiert wird, im zweiten mit 3, usw.) und (3) eine Hilfsspur. Wir schreiben am Anfang also die gegebene Zahl n = 1, 2, 3, . . . auf Spur 1, die Zahl 1 auf Spur 2 und nichts auf Spur 3. Der Initialzustand q0 überprüft (durch Vergleich mit Spur 2), ob auf Spur 1 eine Zahl n ≥ 2 steht. Im Fall von n = 0 oder n = 1, wird der Zustand q0 zu q− , einem nicht-finalen Haltezustand verändert. (Also werden 0 und 1 nicht akzeptiert.) Falls n ≥ 2 ist, werden Berechnungsdurchgänge rekursiv durchgeführt, die man wie folgt beschreiben kann: Anfang eines Berechnungsdurchganges: Spur 1 wird auf Spur 3 kopiert. Die Zahl auf Spur 2 wird um 1 vergrößert. Die Spuren 1 und 2 werden verglichen und falls die Zahlen gleich sind, wird der Zustand zu q+ , einem finalen Haltezustand geändert (die Eingabe wird also akzeptiert, denn keine Zahl kleiner n, die n teilt, wurde gefunden). Rumpf eines Berechnungsdurchganges: Die Zahl von Spur 3 wird durch die auf Spur 2 dividiert (z.B. durch wiederholte Subtraktion). Ende eines Berechnungsdurchganges: Jetzt steht auf Spur 3 der Rest der Eingabe modulo der Testzahl. Falls der Rest 0 ist, wird der Zustand zu q− verändert. Falls der Rest positiv ist, wird der Kopf nach links zum ersten Symbol 1 von Spur 1 geschoben und ein neuer Berechnungsdurchgang beginnt. Es ist leicht einzusehen, dass sich diese informale Beschreibung der Turingmaschine relativ einfach durch eine formal definierte TM realisieren lässt. 82 3.2.5 KAPITEL 3. TURINGMASCHINEN TM mit mehreren Bändern Die nächste Modifikation von TM ist eine Maschine, die mehrere Bänder hat und bei der auf jedem Band ein Lese-/Schreibkopf steht. Die k Köpfe bewegen sich unabhängig voneinander und schreiben auch unabhängig voneinander auf ihren individuellen Bändern. Die Kontrolle ist aber zentral (durch den gegebenen Zustand): Band 1 ... ... ⇑X Kopf 1 Band 2 ... • q0 q4 • ... eeee•2 q1 •ee • q3 • q2 ⇑Z Kopf 2 SCHEMA EINER 2-BAND TM Das bedeutet, dass der Übergangsfunktion δ hier der Zustand q und die k gelesenen Symbole k (s1 , s2 , . . . , sk ) ∈ Σ zur Verfügung stehen. (Wir bezeichnen mit Ak = A × A × · · · × A die Menge aller k-Tupel von Elementen aus A). Hier ist Σ die Menge aller Bandsymbole von allen k Bändern. Als Ergebnis haben wir einen neuen Zustand q 0 und ein k-Tupel von Symbolen aus {L,R} ∪ Σ ∪ {#}. Das heißt, dass δ eine partielle Funktion mit Urbildbereich Q × (Σ ∪ {#})k und Wertebereich Q × (Σ ∪ {#,L,R})k ist. Definition. Eine k-Band-Turingmaschine ist ein Fünftupel M = (Q, Σ, δ, q0 , qF ), die wie eine TM definiert wird, nur ist δ jetzt eine partielle Funktion mit Urbildbereich Q × (Σ)k und Wertebereich Q × (Σ ∪ {L,R})k . Die Berechnung durch eine k-Band TM ist analog zum Fall einer 1-Band TM definiert. Eine Konfiguration hat die Form (q, u1 a1 v1 , u2 a2 v2 , . . . , uk ak vk ), wobei q der Zustand und ui ai vi der Inhalt des i-ten Bandes bezeichnet. Falls δ(q, a1 . . . ak ) definiert ist, wird die Folgekonfiguration individuell auf jedem Band berechnet. Falls δ(q, a1 . . . ak ) undefiniert ist, heißt die Konfiguration Haltekonfiguration. Band 1 dient als Eingabeband, das heißt, die Initialkonfiguration für eine Eingabe s1 . . . sn ist (q0 , s1 . . . sn , #, #, . . . , #) | {z } (k−1)−mal Die Eingabe wird akzeptiert, falls die Maschine eine Haltekonfiguration mit dem finalen Zustand erreicht. Beispiel 4. Eine 2-Band TM, die die Sprache {an bn cn ; n ≥ 1} akzeptiert. Die TM hat ein Eingabeband (Band 1) und ein Hilfsband (Band 2). Band 1 bleibt unverändert, Band 2 ist am Anfang leer. 3.2. MODIFIKATIONEN VON TURINGMASCHINEN Band 1 83 a a ... a b b ... b c c ... c # # ⇑ Band 2 # # # ... ⇑ Initialkonfiguration Erste Etappe der Berechnung: Solange der Kopf 1 a liest, schreibt Kopf 2 a, und beide Köpfe bewegen sich ein Feld nach rechts. Nur am Anfang schreibt Kopf 2 ein x anstelle von a. Band 1 a a ... a b b ... b c c ... c # # ⇑ Band 2 x a ... a # # # ... ⇑ Zweite Etappe: Hier bewegen sich Kopf 1 und Kopf 2 gleichzeitig in entgegengesetzte Richtungen: Kopf 1 nach rechts und Kopf 2 nach links, bis Kopf 1 c und Kopf 2 x liest. Falls Kopf 1 während dieser Bewegung immer b und Kopf 2 immer a liest, gehen wir zur dritten Etappe über; falls nicht, hält die TM in einem nicht-finalen Zustand (Eingabe nicht akzeptiert). Band 1 . . . ## a a . . . a b b . . . b c c . . . ⇑ Band 2 ... # x a ... a # # # ... ⇑ Dritte Etappe: Beide Köpfe bewegen sich gleichzeitig nach rechts, bis Kopf 1 # liest. Falls in jedem dieser Schritte außer dem letzten Kopf 1 c und Kopf 2 a liest und falls beide Köpfe im letzten Schritt # lesen, dann hält die TM im finalen Zustand qF (Eingabe akzeptiert). Falls nicht, hält die TM und akzeptiert nicht. Formal können wir die Übergänge wie folgt beschreiben: Erste Etappe: (q0 , a, #) → (q1 , a, x) (q1 , a, x) → (q1 , R, R) (q1 , a, #) → (q1 , a, a) (q1 , a, a) → (q1 , R, R) Zweite Etappe: (q1 , b, #) → (q2 , R, L) (q2 , b, a) → (q2 , R, L) (q2 , c, x) → (q2 , R, R) Dritte Etappe: (q2 , c, a) → (q2 , R, R) (q2 , #, #) → (qF , #, #). Das sind alle Übergänge für die 2-Band TM mit Bandalphabet Σ̂ = {a, b, c, x} und Eingabealphabet Σ = {a, b, c}, die die Sprache aller an bn cn (n ≥ 1) akzeptiert. (Vergleichen Sie das mit Beispiel 3 in Abschnitt 3.1). Beispiele von Berechnungen: Die Eingabe aabbcc wird wie folgt berechnet: 84 KAPITEL 3. TURINGMASCHINEN (q0 , aabbcc, #) ` (q0 , aabbcc, x) ` (q0 , aabbcc, x#) ` (q0 , aabbcc, xx) ` (q0 , aabbcc, xx#) ` (q0 , aabbcc, xx#) ` (q0 , aabbcc, xx#) ` (q0 , aabbcc, xx#) ` (q0 , aabbcc#, xx#) ` (qF , aabbcc#, xx#) und wird akzeptiert. Die Eingabe aabcc wird wie folgt berechnet: (q0 , aabcc, #) ` (q0 , aabcc, x) ` (q0 , aabcc, x#) ` (q0 , aabcc, xx) ` (q0 , aabcc, xx#) ` (q0 , aabcc, xx) ` (q0 , aabcc, xx#) und wird nicht akzeptiert. Bemerkung 3. Simulation einer 2-Band-TM durch eine 1-Band-TM Sei M = (Q, Σ, δ, q0 , F ) eine 2-Band-TM. Wir konstruieren eine 1-Band-TM mit zusätzlichem Gedächtnis, M , die die Maschine M Schritt für Schritt simuliert. Das Band von M ist 4-spurig: Band 1 ... a a b ... # # # ... 0 1 0 ... ⇑ # # a a b a a ⇑ Band 2 0 1 0 ⇑ Maschine M a ⇑ # # a # # # # # # # # # # # # # # # # # # # ... ... ... ... Maschine M Band 1 der Maschine M wird auf die Spur 1 von M kopiert, die Kopfposition des Kopfes von Band 1 steht auf der Spur 2. Analog wird Band 2 auf Spur 3 von M kopiert und die Kopfposition des Bandes auf Spur 4. Das Eingabealphabet von M ist also Σ = (Σ ∪ {#}) × {⇑, #} × (Σ ∪ {#}) × {⇑, #} − {(#, #, #, #)}, wobei (#, #, #, #) das Blank-Symbol ist. Die Zustände von M und M sind dieselben. Die Maschine M muss sich die letzten von Kopf 1 und Kopf 2 gelesenen Symbole merken, also hat sie ein zusätzliches Gedächtnis der Form (s1 , s2 , x), wobei si ∈ Σi ∪ {#} das aktuelle Symbol von Band i (= 1, 2) der Turingmaschine M ist und x ∈ {l, r} aussagt, ob Kopf 2 (also das Symbol ⇑ auf Spur 4)links oder rechts von Kopf 1 (dem Symbol ⇑ auf Spur 2) steht. 1. Anfang der Simulation: Auf Spur 1 steht die Eingabe v1 v2 . . . vn von M , die Spuren 2 - 4 sind leer. Wir schreiben je ein ⇑ auf die Spuren 2 und 4 unter v1 von Spur 1. SPUR SPUR SPUR SPUR 1 2 3 4 ... ... ... ... # # # # v1 v2 . . . vn # ⇑ # ... # # ... ⇑ # ... ... ... ... ... 3.3. ENTSCHEIDBARE PROBLEME UND REKURSIVE SPRACHEN 85 2. Berechnungsschritt: Am Anfang der Simulation einers Schrittes von M steht der Kopf von M unter dem Symbol ⇑ auf Spur 2. Das gerade gelesene Symbol von Spur 1 wird als s1 im zusätzlichen Gedächtnis gespeichert. Danach sucht der Kopf von M das Symbol ⇑ auf Spur 4: entweder stehen die beiden Symbole ⇑ untereinander, sonst suchen wir links bzw. rechts, falls im zusätzlichen Gedächtnis x = l bzw. x = r steht. Sobald ⇑ gefunden ist, wird das gerade gelesene Symbol von Spur 3 als s2 gespeichert. Aufgrund des Zustandes q von M und des Paares (s1 , s2 ) im zusätzlichen Gedächtnis werden jetzt die Kopfpositionssymbole auf den Spuren 3 und 4 so bewegt, wie die Maschine M die Köpfe bewegt, und die Symbole auf den Spuren 1 und 3 werden so überschrieben, wie M die Symbole auf beiden Bändern überschreibt. (Das geschieht in endlich vielen Schritten der Kopfbewegung von M .) Die Eingabe x ∈ {l, r} im Gedächtnis wir aktualisiert und der Kopf wird nach ⇑ auf Spur 2 bewegt. 3. Ende der Simulation: Die Maschine M hält genau dann, wenn eine Haltekonfiguration von M erreicht wird. Und M akzeptiert genau dann, wenn M akzeptiert. Satz 1. Für jede k-Band-TM gibt es eine (1-Band-) TM, die dieselbe Sprache akzeptiert. Beweis. Für k = 2 folgt der Beweis aus der gerade beschriebenen Simulation und dem Fakt, dass eine 4-spurige TM mit zusätzlichem Gedächtnis durch eine TM simuliert werden kann (siehe Kapitel 3.2.2). Für k > 2 ist der Beweis analog und wird dem Leser überlassen. 3.3 Entscheidbare Probleme und rekursive Sprachen Wie oben erwähnt, repräsentiert eine TM eine formale Darstellung des Begriffs eines Algorithmus, indem sie eine beliebige Eingabe berechnet (und entweder akzeptiert oder nicht). Die Frage ist, ob wir nur terminierende Algorithmen betrachten dürfen, oder ob wir auch Algorithmen erlauben, die unendlich lange berechnen. Im Berechnungsmodell der TM entsprechen den terminierenden Algorithmen die TM, die auf jede Eingabe halten. Das bedeutet, dass das Nichtakzeptieren immer dadurch erfolgt, dass die TM in einem nichtfinalen Zustand hält. Die allgemeineren, nicht terminierenden Algorithmen werden von allgemeinen TM repräsentiert. Probleme, die ein terminierender Algorithmus löst, heißen entscheidbar . Die entsprechenden formalen Sprachen werden entweder entscheidbar oder rekursiv genannt. Die allgemeineren Sprachen heißen semientscheidbar oder (aus Gründen, die wir später erklären) rekursiv aufzählbar: Definition. Eine Sprache L heißt rekursiv oder entscheidbar , falls es eine Turingmaschine M gibt, die L akzeptiert und auf jede Eingabe hält. Eine Sprache L heißt rekursiv aufzählbar oder semientscheidbar , falls es eine Turingmaschine M gibt, die L akzeptiert. Beispiel 1. Die folgenden Sprachen sind rekursiv, denn die oben konstruierten TM halten auf jede Eingabe: 1. Die Sprache aller durch 5 teilbaren Zahlen (siehe Beispiel 1 in Abschnitt 3.1). 2. Die Sprache aller Primzahlen (siehe Beispiel 3 in Abschnitt 3.2.4). 86 KAPITEL 3. TURINGMASCHINEN 3. Die Sprache {an bn cn ; n ≥ 1} (siehe Beispiel 4 in Abschnitt 3.2.5 und Satz 1 in Abschnitt 3.2.5). Beispiel 2. Eine Sprache Lcode, die nicht rekursiv aufzählbar ist. Es ist nicht möglich, ein natürliches“ Beispiel einer nicht rekursiv aufzählbaren ” Sprache zu finden, da alle natürlichen“ Beispiele durch irgendeinen Algorithmus ” beschrieben werden. Aber vorausgesetzt, dass wir eine Codierung für alle TM mit dem Bandalphabet {0, 1} haben (eine solche Codierung wird in Kapitel 5.1 ausführlich beschrieben), können wir eine konkrete Sprache, die nicht rekursiv aufzählbar ist, konstruieren. Wir nehmen also an, dass es für jede Turingmaschine M mit Bandalphabet {0, 1} ein Wort c(M ) über {0, 1} gibt, sodass der Code c(M ) die Sprache der Turingmaschine M vollständig beschreibt. Das heißt, dass für alle Turingmaschinen M und M 0 gilt: c(M ) = c(M 0 ) ⇒ L(M ) = L(M 0 ). Mit Lcode bezeichnen wir die Sprache aller Codewörter w = c(M ) solcher Turingmaschinen M , die ihr eigenes Codewort nicht akzeptieren: Lcode = {w; w = c(M ) für eine Turingmaschine M mit w ∈ / L(M )}. Diese Sprache ist nicht rekursiv aufzählbar. Beweis. Die Annahme, dass es eine Turingmaschine M̂ mit L(M̂) = Lcode gibt, führt zu einem Widerspruch. Für das Codewort ŵ = c(M̂ ) dieser Maschine M̂ zeigen wir nämlich, dass (a) aus ŵ ∈ / Lcode folgt ŵ ∈ Lcode und (b) aus ŵ ∈ Lcode folgt ŵ ∈ / Lcode. Dann ist weder ŵ ∈ Lcode noch ŵ ∈ / Lcode wahr. Zu (a): Da ŵ ∈ / L(M̂) und ŵ = c(M̂ ), folgt aus der Definition von Lcode, dass ŵ ∈ Lcode. Zu (b): Da ŵ ∈ Lcode , gibt es M mit ŵ = c(M ) und ŵ ∈ / L(M ). Aus c(M ) = c(M̂ ) folgt aber L(M ) = L(M̂); es gilt also ŵ ∈ / L(M̂) = Lcode. Bemerkung 1. Jede rekursive Sprache ist selbstverständlich rekursiv aufzählbar, und jede kontextfreie Sprache ist rekursiv, wie sofort bewiesen wird. REGULÄR KONTEXTFREI REKURSIV REKURSIV AUFZÄHLBAR ALLE SPRACHEN Beispiel 4 in Abschnitt 3.2.5 zeigt, dass die Sprache L = {an bn cn ; n ≥ 1} rekursiv (aber nicht kontextfrei) ist. Ein Beispiel einer Sprache, die rekursiv aufzählbar aber nicht rekursiv ist, wird in Kapitel 5 vorgeführt. Dort zeigen wir, dass ein solches Beispiel die Sprache Lhalt aller Wörter c(M )w ist, wobei M eine Turingmaschine und w ein Eingabewort ist, 3.3. ENTSCHEIDBARE PROBLEME UND REKURSIVE SPRACHEN 87 auf das die Turingmaschine M hält. (Das bedeutet, dass das Halteproblem“ nicht ” entscheidbar ist.) Beispiel 3. Jede kontextfreie Sprache ist rekursiv. Wir können nämlich den CYKAlgorithmus (Kapitel 2.7) durch eine Turingmaschine, die auf jede Eingabe hält, wie folgt implementieren. Die TM hat zwei Bänder : Band 1 ist das Eingabeband und auf Band 2 werden die Mengen Vi,j berechnet. Die TM hat ein zusätzliches Gedächtnis, in dem die Regeln der Grammatik gespeichert werden. Das Bandalphabet von Band 1 ist also Σ, und Kopf 1 ist ein Lesekopf. Band 2 hat als Bandalphabet die Potenzmenge 2V aller Mengen von Variablen. Die Felder von Band 2 sind mit zwei Indizes nummeriert, wir nehmen also an, dass es für jedes Paar i, j = 1, 2, 3, . . . genau ein Feld xij auf Band 2 gibt. Band 1 (Eingabeband) . . . s1 s2 s3 s4 . . . sn Band 2 (Hilfsband für Vi,j ) ... x11 x12 x22 x13 x23 x33 x14 ... . . . xnn . . . Im ersten Schritt werden die Felder xi1 , i = 1, . . . , n (wobei n die Länge der Eingabe ist) mit Vi,1 = {A ∈ V ; A → si ist eine Regel} und die Felder xij , 1 < j ≤ n − i + 1 mit ∅ beschriftet. Der rekursive Schritt wird wie im CYK-Algorithmus durchgeführt: nachdem alle Felder xi,1 , . . . , xi,j−1 (i ≤ n) beschriftet wurden, wird xi,j mit Vi,j = {A ∈ V ; A → BC für B ∈ Vi,k und C ∈ Vi+k,j−k , wobei k < j} beschriftet. Am Ende überprüft die TM, ob im Feld x1n eine Menge, die S enthält, steht oder nicht. Bemerkung 2. Ein direkter Weg wäre, jeden Kellerautomaten durch eine TM zu simulieren. Das stieße aber auf die Schwierigkeit, dass Kellerautomaten nichtdeterministisch sind. Wir führen den entsprechenden Begriff für TM in Abschnitt 3.4 ein. Satz 1. Falls L und L0 rekursive Sprachen sind, sind auch die Sprachen L + L0 , L ∩ L0 , LL0 und L∗ rekursiv. Beweis. Sei M eine TM, die L akzeptiert, und M 0 eine TM, die L0 akzeptiert. Wir nehmen an, dass M und M 0 auf jede Eingabe halten. 1. L + L0 . Diese Sprache wird von einer 2-Band TM akzeptiert, die auf Band 1 die Maschine M und gleichzeitig auf Band 2 die Maschine M 0 simuliert. Falls beide Maschinen halten, ist der Zustand der neuen Maschine genau dann final, wenn einer der entsprechenden Zustände (von M oder M 0 ) final ist. 2. L∩L0 . Der Beweis ist analog zu 1., nur ist ein Zustand genau dann final, wenn beide Zustände (von M sowie von M 0 ) final sind. 3. LL0 . Hier benutzen wir eine 4-Band-Turingmaschine M . Band 1 ist ein Eingabeband mit einem read-only-Kopf. Auf Band 2 steht die Zahl i der Etappe (am Anfang i = 0). Auf Band 3 wird M simuliert, und auf Band 4 wird M 0 simuliert. Jede Eingabe s1 . . . sn der Länge n wird in n + 1 Etappen berechnet. Die i-te Etappe besteht daraus, dass das Wort s1 . . . si auf Band 3 und das Wort si+1 . . . sn auf Band 4 kopiert werden, und dann simuliert unsere TM die Maschine M auf Band 2 und die Maschine M 0 auf Band 3, bis beide Maschinen M und M 0 halten. Falls sie beide akzeptieren, hält auch M und akzeptiert. Falls M oder M 0 nicht akzeptiert und i < n, wird die nächste Etappe mit i := i + 1 durchgeführt. Falls M oder M 0 nicht akzeptiert und i = n, hält M und akzeptiert nicht. 88 KAPITEL 3. TURINGMASCHINEN 4. L∗ . Dieser Beweis ist analog zu 3. Zunächst prüft M , ob das Eingabeband leer ist und akzeptiert gegebenenfalls. Ansonsten erzeugen wir auf Band 2, statt nur einer Zahl i allein, alle möglichen aufsteigenden Listen (i0 , i1 , . . . , ir ) von Zahlen mit 0 = i 0 < i1 < i2 < · · · < i r = n wobei r = 1, . . . , n. Band 3 simuliert M : wir kopieren erst s1 s2 . . . si1 auf Band 3 und, falls die Simulation in einem finalen Zustand von M hält, si1 +1 si1 +2 . . . si2 auf Band 3 und, falls die Simulation wieder in einem finalen Zustand hält, si2 +1 . . . si3 auf Band 3 usw. Falls alle Simulationen in finalen Zuständen von M halten, wird die Eingabe von M akzeptiert. Falls irgendeine der Simulationen in einem nichtfinalen Zustand hält, beginnt eine neue Etappe (mit der nächsten Liste auf Band 2). Wenn alle Listen auf Band 2 durchgegangen worden sind, ohne dass bis dahin M akzeptiert hat, hält M in einem nichtfinalen Zustand. Bemerkung 3. Die Bezeichnung rekursiv aufzählbar“ für die von TM akzeptier” ten Sprachen stammt von einer anderen Weise, wie TM angewendet werden können: zur Erzeugung von Sprachen. Wir beginnen mit dem leeren Band, also mit der Konfiguration (q0 , ###) und lassen die TM berechnen (bis sie hält, oder unendlich lange, falls sie nie hält). Alle Konfigurationen, die den finalen Zustand qF haben, werden durchsucht und das Wort w rechts vom Lesekopf wird notiert; die Konfiguration hat also die Form (qF , vsw) (v ∈ Σ∗ , s ∈ Σ), und wir notieren w. Die Sprache aller Wörter w, die so auf dem Band erzeugt werden, wird mit G(M ) bezeichnet. Formale Definition: G(M ) = {w; w ∈ Σ∗ und es existieren v ∈ Σ∗ und s ∈ Σ mit (q0 , ###) `∗ (qF , vsw)} Wir nennen G(M ) die von M aufgezählte Sprache. Beispiel 4. Die TM M = ({q0 , q1 , qF }, {|}, δ, q0, qF ) mit den Übergangsregeln (q0 , |) → (q1 , L) (q0 , #) → (q0 , |) (q1 , |) → (qF , L) (q1 , #) → (q1 , |) (qF , #) → (q0 , |) berechnet die leere Eingabe wie folgt: (q0 , ###) ` (q0 , #|#) ` (q1 , #|#) ` (q1 , #||#) ` (qF , #||#) also || ∈ G(M ) ` (q0 , #|||#) ` (q1 , #|||#) ` (q1 , #||||#) ` (qF , #||||#) also |||| ∈ G(M ) ` (q0 , #|||||#) .. . Wir sehen, dass M die Sprache aller positiven geraden Zahlen aufzählt. Satz 2. Jede Sprache G(M ), die von einer Turingmaschine M aufgezählt wird, ist rekursiv aufzählbar. Beweis. Wir konstruieren eine 2-Band Turingmaschine M 0 , die die Sprache G(M ) akzeptiert. Band 1 ist ein read-only-Eingabeband. Auf Band 2 wird die Maschine 3.3. ENTSCHEIDBARE PROBLEME UND REKURSIVE SPRACHEN 89 M simuliert (mit einem zu Beginn leeren Band 2). Jedesmal, wenn M ihren finalen Zustand erreicht, überprüft die Maschine M 0 , ob das Wort rechts des Kopfes auf Band 2 mit der Eingabe auf Band 1 übereinstimmt. Falls ja, hält M 0 und akzeptiert. Falls nein, geht die Simulation auf Band 2 weiter. Dann gilt L(M 0 ) = G(M ). Satz 3. Jede rekursiv aufzählbare Sprache L kann durch eine Turingmaschine aufgezählt werden, d.h. hat die Form L = G(M ) für eine Turingmaschine M . Beweis. 1. Für jede rekursive Sprache L zeigen wir, dass L von einer TM aufgezählt werden kann. Wir haben also eine Turingmaschine M0 mit L = L(M0 ), die auf jede Eingabe hält. Wir konstruieren eine 4-Band-TM M , die die Sprache L aufzählt (und dann simulieren wir M mit einer 1-Band-TM). ... | {z ... k−mal ... ... Band 1: L(M0 ) wird aufgezählt } Band 2: Schrittzähler Band 3: Alle Wörter der Länge ≤ k über Σ werden erzeugt Band 4: Simuliert M0 mit Eingabe aus Band 3 Am Anfang sind alle Bänder leer. Die Maschine M schreibt in Etappe Nummer k die Zahl k auf Band 2 (am Anfang ist k = 0) und erzeugt auf Band 3 systematisch alle Wörter s1 . . . sn über Σ mit n ≤ k. Jedes Wort s1 . . . sn auf Band 3 wird von M auf Band 4 kopiert, und anschließend simuliert M auf Band 4 die Maschine M0 mit dieser Eingabe. Falls s1 . . . sn von M0 akzeptiert wird, wird das Wort auf Band 1 kopiert, der Kopf wird ein Feld links von s1 gestellt und der Zustand zu qF geändert. Danach wird Band 1 wieder gelöscht. Falls s1 . . . sn nicht akzeptiert wird, wird das nächste Wort auf Band 3 erzeugt, oder, falls schon alle geprüft wurden, die nächste Etappe (k := k + 1 auf Band 2) wird begonnen. Es ist klar, dass die Maschine M auf Band 1 die Sprache L(M0 ) aufzählt. 2. Für jede rekursiv aufzählbare (aber nicht notwendigerweise rekursive) Sprache zeigen wir, dass L von einer TM aufgezählt werden kann. Der Unterschied zum Fall 1. ist der, dass M0 hier nicht immer halten muss. Wir lösen dieses Problem, indem wir die Simulation von M0 immer nur für höchstens k Schritte (wobei k der Inhalt des Bandes 2 ist) erlauben. Das heißt: falls M0 auf die Eingabe aus Band 3 in höchstens k Schritten hält und akzeptiert, aktivieren wir den Kopf auf Band 1 wie oben. Falls M0 entweder in höchstens k Schritten hält und nicht akzeptiert, oder nach k Schritten noch nicht gehalten hat, gehen wir zum nächsten Wort auf Band 3 (oder zur nächsten Etappe) über. 90 3.4 KAPITEL 3. TURINGMASCHINEN Nichtdeterministische Turingmaschinen Analog zum Fall nichtdeterministischer Automaten führen wir hier nichtdeterministische TM ein. Statt einer partiellen Funktion δ : Q × Σ → Q × Σ ∪ {L,R} haben wir hier eine Relation δ: Definition. Eine nichtdeterministische Turingmaschine M (NTM) ist ein Fünftupel M = (Q, Σ, δ, q0 , qF ), das wie eine TM definiert wird, außer dass hier δ eine Relation δ ⊆ [Q × Σ] × [Q × (Σ ∪ {L,R})] ist. Wir schreiben, wie oben, (q, s) → (q 0 , s0 ) falls die Relation δ das Quadrupel (q, s, q 0 , s0 ) enthält. Der ganze Unterschied bezüglich der Notation zwischen einer TM und einer nichtdeterministischen TM ist, dass für eine deterministische TM für zwei beliebige Übergangsregeln (q, s) → (q 0 , s0 ) und (q, s) → (q 0 , s0 ) gilt, dass, falls die linken Seiten gleich sind (q = q und s = s), auch die rechten Seiten gleich sein müssen (q 0 = s0 und s0 = s0 ). Für nichtdeterministische TM gilt keine solche Einschränkung. Beispiel 1. stochastischer Zahlengenerator. Wir beschreiben eine nichtdeterministische Turingmaschine M , die auf ihr Band entweder eine beliebige Zahl n ≥ 1 (in binärer Form) schreibt und hält oder nie hält. Im Initialzustand q0 schreibt M eine 1 und geht zum Zustand q1 , in dem die folgende Wahl getroffen wird: entweder wird der Haltezustand qF erreicht, oder es wird ein neues Symbol 0, 1 geschrieben und (unter Verwendung eines Hilfezustandes q2 ) der Kopf nach rechts bewegt. Formal: M = ({q0 , q1 , q2 , qF }, {0, 1}, δ, q0, qF ) wobei δ durch die folgenden Übergangsregeln beschrieben wird: (q0 , #) → (q0 , 1) (q0 , 1) → (q1 , R) (q1 , #) → (q2 , 0) (q1 , #) → (q2 , 1) (q1 , #) → (qF , #) (q2 , i) → (q1 , R) für i = 0, 1. Beispiel: 3.4. NICHTDETERMINISTISCHE TURINGMASCHINEN ... 91 ... ⇑ q0 ... 1 ⇑ q0 ... ... 1 ... ⇑ q1 ... 1 0 ⇑ q2 ... ... 1 0 ... ⇑ q1 ... 1 0 1 ⇑ q2 ... ... 1 0 1 ... ⇑ q1 ... 1 0 1 ... ⇑ qF Konfigurationen und die Berechnung von Eingaben sind genauso definiert wie für die (deterministischen) TM. Hier hat eine Eingabe natürlich nicht nur eine, sondern mehrere Berechnungen. Definition. Eine nichtdeterministische Turingmaschine M akzeptiert die Eingabe w ∈ Σ∗ , falls es für w mindestens eine Berechnung gibt, so dass M nach endlich vielen Schritten eine Haltekonfiguration mit dem finalen Zustand erreicht. Die Sprache aller Eingaben, die M akzeptiert, wird mit L(M ) bezeichnet. Bemerkung 1. Die k-Band-TM lassen sich analog zu den nichtdeterministischen k-Band-TM verallgemeinern: hier ist δ eine Relation k δ ⊆ [Q × Σ ] × [Q × (Σ ∪ {L,R})k ]. Beispiel 2. Test der Zerlegbarkeit. Wir zeigen eine nichtdeterministische 3-Band-TM, die die Sprache L ⊆ {|}∗ aller zerlegbarer Zahlen, also Zahlen der Form n = pq mit p > 1 und q > 1 akzeptiert. Wie in Beispiel 3 in Abschnitt 3.2.4 hat M ein Eingabeband, ein Testzahlband und ein Hilfsband. Im Initialzustand schreibt M die Zahl zwei (||) auf Band 2 (jede Testzahl ist größer oder gleich ||) und verändert den Zustand zu q1 . In q1 , dem einzigen nichtdeterministischen Zustand, gibt es zwei Möglichkeiten: entweder wird ein neuer Strich auf Band 2 geschrieben, und der Zustand q1 bleibt, oder der Zustand verändert sich zu q2 . Im Zustand q2 wird wie folgt deterministisch berechnet: 92 KAPITEL 3. TURINGMASCHINEN 1. Die Zahl n auf Band 1 wird mit der Zahl m auf Band 2 verglichen. Falls n ≤ m ist, hält die Maschine, ohne zu akzeptieren. 2. Falls n > m, wird n auf Band 3 kopiert. 3. Band 2 wird von Band 3 abgezogen, bis auf Band 3 der Rest der Division von n durch die Testzahl steht. Dann hält die Maschine. 4. Falls Band 3 leer ist, wird die Eingabe akzeptiert, falls Band 3 nicht leer ist, wird sie nicht akzeptiert. Wir sehen, dass die Testzahl m eine beliebige Zahl m = 2, 3, 4, . . . sein kann. Die Eingabe n wird genau dann akzeptiert, wenn es ein m < n gibt, das n teilt. Beispiel 3. Simulation eines Kellerautomaten Wir können einfach jeden Kellerautomaten durch eine nichtdeterministische 2Band-Turingmaschine M simulieren, bei der auf Band 1 die Eingabe des Kellerautomaten und auf Band 2 der Kellerinhalt steht. M hat ein zusätzliches Gedächtnis, in dem die Übergangsregeln des Kellerautomaten notiert werden. Am Anfang schreibt die NTM das Symbol k0 auf Band 2. Jede Übergangsregel (q, s, k) → (q 0 , k1 . . . kn ), s ∈ Σ, des Kellerautomaten wird wie folgt simuliert: Band 1 Band 2 . . . s s0 s00 . . . ⇑ . . . k k 0 k 00 . . . ⇑ Übergang . . . s s0 s00 . . . ⇑ k1 . . . kn k 0 k 00 . . . ⇑ Falls die Maschine M im Zustand q die Symbole s (Band 1) und k (Band 2) liest, ändert sie ihren Zustand zu q 0 , bewegt den Kopf 1 einen Schritt nach rechts und macht folgendes auf Band 2: 1. Falls n 6= 0 (also k1 . . . kn 6= ε), wird k von kn überschrieben, und der Kopf 2 schreibt, sich nach links bewegend, die Symbole kn−1 , . . . , k1 . 2. Falls n = 0, löscht Kopf 2 das Symbol k und bewegt sich einen Schritt nach rechts. Analog wird jede spontane Übergangsregel (q, #, k) → (q 0 , k1 . . . kn ) simuliert: der einzige Unterschied ist, dass hierbei Kopf 1 stehenbleibt. Satz 1. Jede NTM kann durch eine (deterministische) TM simuliert werden. Beweis. Sei M eine NTM, und sei r eine Zahl, so dass es für jedes Paar (q, s) aus Q × (Σ ∪ {#}) höchstens r Übergänge (q, s) → (q 0 , s0 ) gibt. Dann können wir die Übergänge durchnummerieren: (q, s) → (q 0 i , s0 i ) für i = 1, 2, . . . , r (Wiederholungen sind erlaubt). Die einzige Ausnahme ist δ(q, s) = ∅ (Haltekonfiguration). Wir simulieren M mit einer 4-Band-TM wie folgt: Band 1 ist das Eingabeband mit einem read-only Kopf. Auf Band 2 werden systematisch alle Zahlen k = 0, 1, 2, 3, . . . 3.5. BERECHENBARE FUNKTIONEN 93 geschrieben, sie geben die Länge der Berechnung vor. Auf Band 3 werden systematisch alle k-Tupel aus Zahlen 1, . . . , r erzeugt (k = 1, 2, 3, . . . ). Auf Band 4 werden für jeden Eintrag i1 i2 . . . i k von Band 3 die ersten k Takte der Maschine M simuliert, aber in jedem Takt wählen wir den Übergang, dessen Index auf Band 2 steht. Also wird im Takt n der Übergang (q, s) → (q 0 in , s0 in ) gewählt, wobei q der momentane Zustand ist und s das gerade gelesene Symbol. In einer Haltekonfiguration von M mit q = qF hält M und akzeptiert die Eingabe, andernfalls, also auch bei Haltekonfigurationen mit q 6= qF wird k erhöht und die Simulation fortgesetzt. Es gibt also die folgenden Möglichkeiten für die Berechnung einer Eingabe w: 1. M hält auf w nach k Schritten für irgendeine Zahl k und akzeptiert w, d.h., es gibt eine akzeptierende Berechnung der Länge k von w. Dann hält auch M auf w und akzeptiert w (mit einem der r k möglichen Inhalte von Band 3); 2. M akzeptiert w nicht, d.h., alle von M bei Eingabe w erreichbaren Haltekonfigurationen haben einen von qF verschienedenen Zustand. Dann hält M nie, denn M schreibt immer länger werdende k-Tupel (k = 1, 2, 3, . . . ) auf Band 2. Damit gehört w weder zu L(M ) noch zu L(M). Es folgt, dass L(M ) = L(M). Korollar 1. Jede von einer nichtdeterministischen TM akzeptierte Sprache ist rekursiv aufzählbar. Satz 2. Falls L und L0 rekursiv aufzählbare Sprachen sind, sind auch die Sprachen L + L0 , L ∩ L0 , LL0 und L∗ rekursiv aufzählbar. Beweis. Für L + L0 und L ∩ L0 ist der Beweis gleich dem für rekursive Sprachen (siehe Satz 1 in Abschnitt 3.3). LL0 : sei M eine TM, die L akzeptiert, und M 0 eine TM, die L0 akzeptiert. Wir definieren eine nichtdeterministische 4-Band-TM M , die LL0 akzeptiert. Band 1 ist das Eingabeband mit der Eingabe s1 s2 . . . sn , auf Band 2 schreibt M nichtdeterministisch eine Zahl i = 0, 1, 2, . . . , auf Band 3 wird M mit Eingabe s1 s2 . . . si simuliert, und auf Band 4 wird M 0 mit Eingabe si+1 . . . sn simuliert. Die Maschine M akzeptiert genau dann, wenn sowohl M als auch M 0 halten und akzeptieren. L∗ : Dieser Beweis ist analog zu LL0 , nur werden auf Band 2 statt nur einer Zahl i nichtdeterministisch Listen (i0 , i1 , . . . , ir ) von Zahlen mit 0 ≤ i0 < i1 < · · · < ir ≤ n geschrieben, und auf Band 3 wird M mit Eingabe s1 . . . si , si1+1 . . . si2 , . . . , sir−1+1 . . . sir simuliert. Falls M alle diese Eingaben akzeptiert, hält M und akzeptiert. 3.5 Berechenbare Funktionen Wie im Fall endlicher Automaten, können auch Turingmaschinen nicht nur als Akzeptoren von Sprachen, sondern als Maschinen für die Berechnung von Funktionen betrachtet werden. Hier benötigen wir sogar keine Modifikation der Maschine, denn 94 KAPITEL 3. TURINGMASCHINEN sie kann das Ergebnis einfach auf das Band schreiben. Allgemein können wir Berechnungen von Funktionen von Σ∗ nach Γ∗ formalisieren, wobei Σ das Alphabet ist, in dem die Eingaben codiert werden, und Γ das Alphabet der Ausgaben. Definition. Wir sagen, eine Turingmaschine M berechnet die Funktion f : Σ ∗ → Γ∗ falls das Eingabealphabet von M die Menge Σ ∪ Γ enthält, die Maschine M auf jede Eingabe w aus Σ∗ hält und der Bandinhalt dann gleich f (w) ist. Beispiel 1. Die Funktion f (n) = 2n, wobei n unär (über Σ = {|}) dargestellt ist, wird von der folgenden TM berechnet: falls das erste Symbol # ist (also n = 0), hält die TM. Falls das erste Symbol | ist, löscht die Maschine dieses Symbol, geht nach links, schreibt | vor das letzte Symbol | am linken Wortrand, geht nach rechts und schreibt das gelöschte Symbol | wieder (q0 , |) → (q1 , #) (q1 , #) → (q2 , L) (q2 , |) → (q2 , L) (q2 , #) → (q3 , |) hin usw.: (q3 , |) → (q3 , R) (q3 , #) → (q4 , |) (q4 , |) → (q0 , R) Genauer, die TM M = ({q0 , q1 , q2 , q3 , q4 , qF }, {0, 1}, δ, q0, qF ), deren Übergangsfunktion δ oben gegeben ist, berechnet die Funktion f (n) = 2n. Beispiel 2. Die Funktion f : Σ∗ → {|}∗ der Länge der Worte f (s1 s2 . . . sn ) = n (unär dargestellt) wird von der folgenden TM berechnet: M = ({q0 }, Σ ∪ {|}, δ, q0 , q0 ), wobei δ wie folgt definiert wird (q0 , x) → (q0 , |) für alle x ∈ Σ (q0 , |) → (q0 , R) Bemerkung. 1. Wie im Fall von Sprachenakzeptanz können wir auch für Funktionen den Begriff der TM modifizieren und zum Beispiel eine Mehrband-TM benutzen. Es ist dann üblich, Band 1 als Eingabeband und Band 2 als Ausgabeband (mit Inhalt f (w), nachdem die TM hält) zu verwenden. 2. Der Finalzustand spielt bei Berechnungen keine Rolle (und könnte, für diese Anwendung der TM, aus der Definition entfernt werden). 3. Für Funktionen zweier (oder mehrerer) Variablen werden die verschiedenen Variablen voneinander durch eine leere Zelle getrennt. Also zum Beispiel eine Funktion f (w1 , w2 ) zweier Variabler aus Σ∗ mit Werten in Γ∗ wird von einer TM berechnet, falls die TM auf jede Eingabe w1 #w2 mit Bandinhalt f (w1 , w2 ) hält. Beispiel 3. Addition. Wir wollen die Funktion f (n, m) = n + m (unär dargestellt) durch eine TM berechnen: es genügt, das erste Symbol |“ zu streichen und die ” Lücke, die die zwei Variablen voneinander trennt, durch |“ zu ersetzen: ” 3.5. BERECHENBARE FUNKTIONEN 95 (q0 , |) → (q1 , #) (q0 , #) → (qF , R) (q1 , #) → (q2 , R) (q2 , |) → (q2 , R) (q2 , #) → (qF , |) Genauer, die TM M = ({q0 , q1 , q2 , qF }, {|}, δ, q0, qF ) mit der oben definierten Übergangsfunktion δ berechnet die Addition in unärer Darstellung. Beispiel 4. Multiplikation. Die Funktion f (n, m) = n ∗ m (unär dargestellt) kann von der folgenden 2-Band-TM berechnet werden: Band 1 ist das Eingabeband, aus Band 2 schreibt die Maschine n-mal hintereinander die Zahl m, das heißt, m Symbole |“. Dann hält sie und hat auf Band 2 ” (Ausgabeband) die Zahl n ∗ m. Definition. Eine Funktion (einer oder mehrerer Variablen) von Σ∗ nach Γ∗ heißt berechenbar oder Turing-berechenbar, falls sie durch eine TM berechnet werden kann. Beispiele 1. f (n) = 2n, f (n, m) = n + m, f (n, m) = n ∗ m und die Funktion f : Σ∗ → N , die die Länge berechnet, sind berechenbar. Bemerkung. 4. Wer der Churchschen These glaubt, erwartet, dass jede durch einen (terminierenden) Algorithmus gegebene, voll-definierte Funktion durch eine TM berechenbar sein muss: man implementiert einfach den Algorithmus auf einer TM. 5. Für partiell definierte Funktionen f : Σ∗ → Γ∗ können wir auch den Begriff von Berechnung durch eine TM einführen: die Situation, bei der f (w) nicht definiert ist, entspricht der Berechnung der Eingabe w, wobei die TM nicht hält: Definition. Eine TM berechnet die partielle Funktion f : Σ∗ → Γ∗ , falls ihr Eingabealphabet Σ ∪ Γ enthält und die TM auf jede Eingabe w aus Σ∗ genau dann hält, wenn f (w) definiert ist, und sie dann den Bandinhalt f (w) hat. Solche Funktionen heißen partiell-berechenbar . Beispiel 5. Division. Die Funktion n : m (ganzzahlig) falls m 6= 0 f (n, m) = undefiniert falls m = 0 kann von der folgenden 2-Band-TM berechnet werden: Band 1 ist das Eingabeband, auf Band 2 schreibt die TM erst n und dann versucht sie, m Striche auf Band 2 wegzuwischen“. Falls dies nicht möglich ist, hält sie. Falls es jedoch möglich ist, ” versucht die Maschine erneut, m Striche auf Band 2 zu löschen und so weiter. Beispiel 6. Eine unberechenbare Funktion β : → . Diese Funktion, die als busy beaver“ (fleißiger Biber) bekannt ist, ist wie folgt ” definiert: β(0) = 0 und für jedes n > 0 ist β(n) = k, 96 KAPITEL 3. TURINGMASCHINEN falls k die größte Zahl ist, die eine TM mit n Zuständen auf die leere Eingabe schreiben kann. D.h., die TM hält auf der leeren Eingabe mit |k auf dem Band. Wir können β(n) einfach bestimmen, wenn wir alle TM mit n Zuständen durchgehen (und die, die auf die leere Eingabe nicht halten, ausschließen). Die TM mit der einzigen Übergangsregel (q0 , #) → (q0 , |) schreibt | auf die leere Eingabe. Daraus folgt β(1) ≥ 1. Aber jede Maschine mit nur einem Zustand, die mehr als einen Strich auf die leere Eingabe schreibt, hält nie. Also gilt β(1) = 1. Bei zwei Zuständen darf δ nur auf drei Elementen der vierelementigen Menge Q × Σ definiert sein, damit die Maschine hält. Daraus folgt sofort β(2) = 2. Im allgemeinen gilt (∗) β(n + 2) > β(n) für jedes n. In der Tat, falls β(n) = k, d.h., falls eine Turingmaschine M mit n Zuständen |k schreibt, konstruieren wir eine Turingmaschine, M 0 , die n + 2 Zustände hat und |k+1 schreibt – woraus β(n + 2) ≥ k + 1 > β(n) folgt. Wir fügen zwei neue Zustände q 0 und q 00 zu den Zuständen von M hinzu. Hält M im Zustand q auf einem Feld |, so ergänzen wir M um drei neue Übergangsregeln: (q, |) → (q 0 , L) (q 0 , |) → (q 0 , L) (q 0 , #) → (q 00 , |). Hält dagegen M im Zustand q auf einem Feld #, so kann sich dieses Feld wegen der Maximalität von β(n) nur direkt neben dem Ergebnis |k von M befinden. Wir können M nun um die Übergangsregel (q, #) → (q 00 , |) ergänzen. In jedem Fall hält die Maschine M 0 im Zustand q 00 , nachdem sie |k+1 geschrieben hat. Satz 1. Für jede berechenbare Funktion f (n) gibt es eine Konstante r mit der Eigenschaft, dass β(n + r) ≥ f (n) für alle n. Beweis. f (n) wird von einer Turingmaschine M berechnet. Sei r die Zahl aller Zustände von M . Wir konstruieren für jede Zahl n eine Turingmaschine Mn , die n + r Zustände hat und f (n) Striche auf die leere Eingabe schreibt – damit ist β(n + r) ≥ f (n) bewiesen. Zu den Zuständen von M werden n neue Zustände q 0 (initial), q 1 , . . . , q n−1 hinzugefügt, sodass Mn auf die leere Eingabe n-mal einen | schreibt und sich dabei nach links bewegt: für i = 0, . . . , n − 1 (q i , #) → (q i , |) (q i , |) → (q i+1 , L) für i = 0, . . . , n − 2 (q n−1 , |) → (q0 , |) Der letzte Übergang bedeutet, dass von jetzt an die Maschine M (mit der Eingabe |n ) simuliert wird – sie schreibt also |f (n) und hält. Korollar 1. Die busy-beaver-Funktion β(n) ist nicht Turing-berechenbar. Falls nämlich β(n) berechenbar wäre, müsste auch β(2n) berechenbar sein (wir hätten eine TM, die erst die Zahl aller |0 e der Eingabe verdoppelt, siehe Beispiel 1 und dann die TM für β(n) simuliert). Dann würde es eine Konstante r geben mit β(n + r) ≥ β(2n) für alle n. Speziell ergibt n = r + 2 β(2r + 2) ≥ β(2r + 4), ein Widerspruch zu (∗). Bemerkung 1. Obwohl β(1) = 1, β(2) = 2 und β(3) = 3, gilt β(10) > 4000 (es existiert eine DTM mit 10 Zuständen, die 4098 schreibt und hält. Dazu benötigt die TM über 200 Mio. Berechnungsschritte). Kapitel 4 Churchsche These Die Churchsche These behauptet, dass die intuitive Klasse aller berechenbaren ” Funktionen“ mit den formal definierten Turing-berechenbaren Funktionen übereinstimmt. Diese These kann zwar nicht bewiesen werden, aber sie lässt sich untermauern, indem man beweist, dass andere natürliche formale Darstellungen des Algorithmenbegriffs dasselbe Ergebnis liefern. Z. B. kann eine Funktion mit Hilfe von PASCAL genau dann auf einem modernen Rechner implementiert werden, wenn sie Turing-berechenbar ist. In diesem Kapitel zeigen wir verschiedene Modelle des Algorithmenbegriffs und beweisen, dass alle diese Modelle äquivalent zu Turingmaschinen sind. Es ist trotzdem möglich, dass irgendwann ein neues, generell akzeptables Modell für Algorithmen gefunden wird, das allgemeiner als Turingmaschinen ist – aber niemand hält so etwas heute für wahrscheinlich. Die Tatsache, dass moderne Rechner und Turingmaschinen dieselbe Mächtigkeit besitzen, illustrieren wir an RAMs (oder Registermaschinen), die realen Rechnern viel näher als Turingmaschinen stehen. Wir beweisen exakt, dass Turing-berechenbare und RAM-berechenbare Funktionen dieselben Klassen formen. Ein Modell ganz anderen Stils ist die formale Grammatik, eine Verallgemeinerung kontextfreier Grammatiken. Wir beweisen, dass eine Sprache genau dann von einer solchen Grammatik erzeugt werden kann, wenn sie von einer Turingmaschine akzeptiert werden kann. Schließlich widmen wir uns den rekursiven Funktionen und zeigen auch hier, dass diese genau die Turing-berechenbaren Funktionen sind. 4.1 RAM Eine RAM, d.h. Random-Access-Maschine (oder Registermaschine) ist ein Modell einer Berechnung, die realen Rechnern dadurch näher steht als TM, dass sie Programm und Datei separat behandelt. Gemeinsam mit TM hat dieses Modell aber die präzise mathematische Definition und die Annahme, dass eine unbegrenzte Speicherkapazität zur Verfügung steht. Die einzelnen Register haben die Fähigkeit, beliebig große Zahlen zu enthalten. 97 98 KAPITEL 4. CHURCHSCHE THESE Eingabeband Zeile: 0 READ 0 1 LOAD 3 13 0 1 0 ⇑ 2 / BZ k | ... STOP {z } Programm STEUEREINHEIT o SPEICHER / R0 R1 R2 . . . ↑ Akkumulator ⇓ 2 0 14 Ausgabeband SCHEMA EINER RAM Eine RAM besteht aus den folgenden Komponenten: 1. Eine Steuereinheit, die über ein Programm verfügt. Ein Programm ist eine durchnummerierte Liste von Befehlen, die weiter unten aufgeführt sind. Die Steuereinheit enthält ein Register, das Befehlszähler (BZ) heißt und dessen Inhalt <BZ>= i eine natürliche Zahl ist. Das bedeutet, dass der Befehl Nr. i auszuführen ist. 2. Einen Speicher , der aus durchnummerierten Registern R0, R1, R2, . . . besteht. Jedes Register Ri enthält eine natürliche Zahl <Ri>. Das Register R0 heißt Akkumulator . 3. Einem Eingabeband, das aus Feldern besteht. Jedes Feld enthält eine natürliche Zahl. (Ein Feld, das 0 enthält, wird als leer angenommen – das entspricht unserer Darstellung N = {|}∗ .) Auf dem Eingabeband steht ein read-only Kopf, der nur lesen und sich dann sofort ein Feld nach rechts bewegen kann. Die gelesene Zahl wird mit <read> bezeichnet. 4. Einem Ausgabeband, das aus Feldern besteht und auf dem ein write-only Kopf steht, der nur ein Feld beschriften und sich anschließend sofort ein Feld nach rechts bewegen kann. Die RAM arbeitet taktweise: in jedem Takt wird der Befehl aus der Zeile <BZ> durchgeführt. Anfang der Berechnung: Die Eingabe steht auf dem Eingabeband, das Ausgabeband ist leer, und alle Register (einschließlich des Befehlszählers und des Akkumulators) sind leer (Zahl 0). Ende der Berechnung: Die Berechnung endet, falls 1. die Instruktion STOP durchgeführt wird oder 2. eine GOTO m Instruktion durchgeführt wird, obwohl kein Befehl die Nummer m hat. 4.1. RAM 99 Hier ist die Liste aller Befehle: Befehl Wirkung READ <R0>:=<read>, <BZ>:=<BZ> + 1, der Lesekopf bewegt sich nach rechts WRITE Der Schreibkopf schreibt <R0> und bewegt sich nach rechts, <BZ>:=<BZ> + 1. LOAD i <R0>:=<Ri> und <BZ>:=<BZ> + 1 STORE i <Ri>:=<R0> und <BZ>:=<BZ> + 1 ADD i <R0>:=<Ri> + <R0> und <BZ>:=<BZ> + 1 PRED <R0>:=pred <R0> und <BZ>:=<BZ> + 1. Hier gilt: pred (n + 1) = n und pred 0 = 0. GOTO m <BZ>:= m m falls Ri = 0 IF Ri = 0 GOTO m <BZ>:= <BZ> + 1 sonst m falls <Ri> > 0 IF Ri > 0 GOTO m <BZ>:= <BZ> + 1 sonst STOP Maschine hält. Bemerkung 1. Für indirekte Adressierung dürfen wir ∗i (statt i) benutzen, z.B. hat LOAD ∗i die Wirkung <R0>:=<<Ri>> (also wird im Akkumulator der Inhalt des Registers, dessen Adresse in Ri steht, gespeichert). Analog für STORE ∗i und ADD ∗i. Außerdem benutzen wir !i statt i für Konstanten: z.B. hat STORE !i die Wirkung <R0>:= i und <BZ>:=<BZ> + 1. Die obige Liste von Befehlen ist kurz, um das Modell übersichtlich zu gestalten, aber weitere Befehle lassen sich leicht programmieren: Beispiel 1. SUCC i. Wir wollen den Befehl benutzen, der den Inhalt des Registers Ri um eins erhöht. SUCC i ist dann dieses Unterprogramm: LOAD !1 o[1 in den Akkumulator] ADD i [<Ri>:=<Ri> +1] STORE i Beispiel 2. PRED i. Der Befehl, der die Wirkung <Ri>:=<Ri> −1, falls <Ri> > 0 ist, hat, lässt sich analog programmieren. Beispiel 3. SUB i. Der Befehl, der die folgende Wirkung <Ri> − <R0>, falls <Ri> ≥ <R0> und R0 := 0 ansonsten hat, hat das folgende Programm: 0. IF R0 = 0 GOTO 4 1. PRED 2. PRED i 3. GOTO 0 4. LOAD i Beispiel 4. IF Ri = k GOTO m. Für jede Konstante k können wir diesen Sprungbefehl durch das folgende Unterprogramm ersetzen: LOAD !k SUB i STORE i IF Ri = 0 GOTO m Beispiel 5. Multiplikation. Die Funktion f (n, m) = n ∗ m kann wie folgt programmiert werden: wir speichern erst die Eingabe n in R1 und m in R2: 100 KAPITEL 4. CHURCHSCHE THESE 0. READ 1. STORE 1 2. READ 3. STORE 2 Jetzt wird R1 solange zu R3 (= Speicher des Ergebnisses) addiert, bis <R2>= 0 ist, wobei bei jedem Schritt <R2>:=<R2> − 1 gesetzt wird. Falls <R2>= 0, springen wir zur Zeile a, die den WRITE-Befehl ausführt: 4. IF R2 = 0 GOTO a 5. LOAD 1 6. ADD 3 7. STORE 3 8. PRED R2 9. GOTO 4 a = 10. LOAD 3 11. WRITE Beispiel 6. Simulation einer Turingmaschine. Für jede TM können wir ein Programm für RAM schreiben, das die Arbeit der TM Schritt für Schritt simuliert. Wir nehmen an, dass die Zustände der TM durchnummeriert sind: Q = {q0 , q1 , . . . , qn }, wobei q0 der Initialzustand ist, sowie auch die Symbole des Bandalphabetes: def. Σ = {s1 , s2 , . . . , sm } und s0 = #. Schließlich werden auch die Felder des Bandes durchnummeriert: 0 für das erste Feld der Eingabe und 1, 2, 3, . . . für die weiter rechts stehenden Felder. Um die Notation zu vereinfachen, nehmen wir an, dass die TM die Felder links von 0 nie besucht. (Sonst könnten wir z.B. die Felder rechts von 0 nur mit geraden Zahlen nummerieren und die links von 0 stehenden mit ungeraden Zahlen.) Um die Simulation zu vereinfachen, nehmen wir weiter an, dass die TM ein Spezialsymbol @ benutzt, das immer als letztes Symbol auf dem Band steht. Die Eingabe si0 . . . sik hat also die Form ... s i0 s i1 s i2 s ik @ # # . . . k k+1k+2 0 1 2 Bei der obigen Nummerierung von Σ sei @ = sm . Die Eingabe wird im Eingabeband der RAM entsprechend codiert: ... i0 i1 i2 ik m 0 0 . . . Die Register der RAM spielen die folgende Rolle: R0 (Akkumulator) R1 (Zustand) enthält i, falls die TM im Zustand qi ist R2 (Kopfposition) enthält k + 2, falls der Kopf am Feld k steht R(3 + i) (Bandinhalt) enthält t, falls im Feld i das Symbol st steht. Das Programm der RAM, das die TM simuliert, besteht aus drei Teilen: Teil 1 sorgt dafür, dass die Eingabe ... s i0 s i1 s i2 s in @ = s m ... in die Register R3, R4, . . . , R(3 + n) und R(3 + n + 1) gelesen wird. Wir lesen also (mit READ) die Eingaben so lange, bis m (der Index von @ = sm ) gelesen wird. Dabei lassen wir die Register R1 und R2 zunächst leer. Es ist einfach, so ein Programm mit Hilfe der obigen Beispiele 1 bis 3 in Abschnitt 4.1 zu schreiben: 0. LOAD !3 1. STORE 2 4.1. RAM 2. 3. 4. 5. 6. 101 READ STORE ∗2 IF R0 = m GOTO 7 SUCC 2 GOTO 2 Teil 2 (in den gesprungen wird, falls die Eingabe m ist) beginnt damit, das der Kopf nach links gestellt wird (<R2>:= 4) und der Zustand q0 (<R1>:= 0) ist. Dann werden die einzelnen Zeilen der Übergangstabelle programmiert. In dem Fall, dass kein Übergang existiert, wird zu Teil 3 (Ausgabe) gesprungen. Teil 3 des Programms schreibt <R3>, <R4>, . . . , bis es auf die Zahl <Rk>:= m (d.h. auf das Endsymbol @) stößt. Dann hält es: Zeile Befehl k LOAD !3 k + 1 STORE 4 [Am Anfang: <R6>= 3] k + 2 LOAD 2 k + 3 WRITE k + 4 SUCC 2 k + 5 IF R0 = m GOTO (k + 7) k + 6 GOTO (k + 2) k + 7 STOP Beispiel 7. RAM-Simulation einer einfachen TM. Die folgende TM realisiert die Funktion SUCC: M = ({q0 , q1 }, {|, @}, δ, q0, q1 ) mit den folgenden Übergängen (1) (q0 , |) → (q0 , R) (2) (q0 , @) → (q1 , |) (3) (q1 , |) → (q1 , R) (4) (q1 , #) → (q1 , @) Die Simulation hat die drei oberen Teile, wobei Teil 2 wie folgt die vier Übergänge simuliert: Zeile Befehl Kommentar 7. LOAD !3 8. STORE 2 Initialposition des Kopfes (+ 3) 9. LOAD ∗2 n R0 steht das momentan gelesene Symbol 10. IF R1 = 0 GOTO a a-Übergänge (1), (2) (Zustand q0 ) 11. IF R0 = 1 GOTO b Hier Zustand q1 , b-Übergang (3) 12. IF R0 = 0 GOTO c Hier Zustand q1 , c-Übergang (4) 13. GOTO k Zustand q1 , Symbol @-Sprung in den Teil 3 a = 14. IF R0 = 1 GOTO d d-Übergang (1) 15. IF R0 = 2 GOTO e e-Übergang (2) d = 16. SUCC 2 Kopf nach rechts GOTO 9 e = 17. LOAD !1 Statt @ = 2 wird | = 1 geschrieben 18. STORE ∗2 19. STORE 1 Zustand q1 20. GOTO 9. b = 21. SUCC 2 Kopf nach rechts 22. GOTO 9. c = 23. LOAD !2 24. STORE ∗2 25. GOTO k Also ist Zeile k = 26 der Anfang von Teil 3 102 4.2 KAPITEL 4. CHURCHSCHE THESE RAM-Berechenbarkeit Definition. Eine RAM berechnet eine Funktion f (n1 , n2 , . . . , nk ), deren Variablen und Werte in liegen, falls die RAM auf die Eingabe n1 , n2 , . . . , nk hält und auf dem Ausgabeband m (nur eine Zahl) steht, wobei f (n1 , . . . , nk ) = m. Eine Funktion, die von einer (geeignet programmierten) RAM berechnet werden kann, heißt RAMberechenbar . Beispiel 1. Die Funktionen f (n, m) = n + m und f (n, m) = n ∗ m sind RAM-berechenbar. Das Programmieren von RAMs ist zwar im Vergleich zu modernen Programmiersprachen aufwendig und kompliziert, trotzdem ist es nicht schwer zu zeigen, dass jede Funktion, die sich mit einem PASCAL-Programm berechnen lässt, auch in einer RAM programmiert werden kann. Obwohl Turingmaschinen weniger realistisch als RAMs sind (und viel einfacher), sind sie keineswegs schwächer: Satz 1. Jede RAM-berechenbare Funktion ist Turing-berechenbar. Beweis. Wir haben ein RAM-Programm für die Funktion f (a1 , . . . , ak ), und wir simulieren es mit einer 6-Band TM mit zusätzlichem Gedächtnis wir folgt: ... ak $ Band 1 (Eingabeband) $ a1 $ a2 $ Band 2 (Speicher) $ $ 1 $ Band 3 (Akkumulator) <R0> Band 4 (Befehlszähler) <BZ> <R1> $$ 2 $ <R2> $ $ ... Band 5 (Hilfsband) Band 6 (Ausgabeband) f (a1 , . . . , ak ) Die TM hat also das Bandalphabet Σ = {|, $}, und die Eingabe der RAM wird mit Trennungssymbolen $ auf Band 1 geschrieben. Band 2 enthält den Speicher der RAM: falls Register Ri benutzt wurde und momentan n enthält, finden wir auf Band 2 die Kombination $ $ i $ n $$, was <Ri>= n bedeutet. (Wir können aber mehrere solcher Kombinationen mit demselben i auf Band 2 finden. In diesem Fall nehmen wir nur die, die am weitesten rechts steht). Band 3 enthält den Inhalt des Akkumulators und Band 4 den des Befehlszählers. Band 6 ist das Ausgabeband. Das (endliche) Programm der RAM ist im zusätzlichen Gedächtnis der TM gespeichert. Anfang der Simulation: Alle Bänder außer Band 1 sind leer. Speziell wird Befehl Nr. 0 (<BZ>= 0) simuliert. Simulation der Befehle: Es wird immer der Befehl, dessen Zeilennummer auf Band 4 steht, simuliert. Wir zeigen einige Beispiele: READ Auf Band 1 steht der Kopf unter $, jetzt bewegt er sich, bis er auf dem nächsten $ stehen bleibt, wobei die Zahl ai auf Band 3 geschrieben wird. Danach wird der Befehlszähler (Band 4) um 1 erhöht. STORE i Auf Band 2 wird nach dem letzten Symbol $ die Kombination i $ n $ $ geschrieben, wobei n der Inhalt des Akkumulators (Band 3) ist. 4.3. GRAMMATIKEN UND TURINGMASCHINEN STORE ∗i 103 Auf Band 3 steht eine Zahl n. Diese soll in das Register Rj, wobei j der Inhalt von Ri ist, gespeichert werden. Also sucht der Kopf auf Band 2 die (am weitesten rechts stehende) Konfiguration $ $ i $ j $ $, und wenn er sie gefunden hat, schreibt er j auf das Hilfsband 5. Jetzt schreibt die TM auf Band 2 hinter das letzte Symbol $ die Kombination j $ n $ $. Der Leser sollte jetzt keine Schwierigkeiten haben, jeden Befehl der RAM entsprechend zu simulieren. Wenn die RAM hält, hält auch die TM (nachdem sie die Instruktion WRITE simuliert hat). Sie hat dann f (a1 , . . . , ak ) auf dem Ausgabeband. Korollar 1. RAM-berechenbare und Turing-berechenbare Funktionen sind dieselben. In der Tat ist jede Turing-berechenbare Funktion RAM-berechenbar: siehe Beispiel 6 in Abschnitt 4.1. 4.3 Grammatiken und Turingmaschinen In Kapitel 2 sprachen wir von kontextfreien Grammatiken, die es erlauben, eine Variable durch ein Wort zu ersetzen. Das ist ein Spezialfall einer Grammatik (auch unbeschränkte Grammatik oder Grammatik des Typs 0 genannt), die es allgemein erlaubt, ein Wort durch ein anderes zu ersetzen. Es zeigt sich, dass diese Grammatiken genau die rekursiv aufzählbaren Sprachen definieren. In diesem Sinn erhalten wir also ein vollkommen neues Modell von Sprachen, die Turing-akzeptierbar sind. Definition. Eine Grammatik G ist ein Quadrupel G = (Σ, V, S, R), wobei Σ das Alphabet aller Terminalsymbole, V das Alphabet aller Variablen (zu Σ disjunkt), S ∈ V das Startsymbol und R eine endliche Menge an Paaren (α, β) von Wörtern über Σ ∪ V mit α 6= ε ist. Bemerkung 1. Elemente (α, β) aus R werden mit α→β bezeichnet und werden Produktionen oder Ersetzungsregeln genannt. Die Anwendung einer Regel α → β auf ein Wort w ist genau dann möglich, wenn w die Form w = w0 αw00 (w0 , w00 Wörter über Σ ∪ V ) hat. Das Ergebnis der Anwendung ist das Wort w0 βw00 . Notation. 1. Mit ⇒ bezeichnen wir die Anwendung einer einzigen Regel; also schreiben wir für zwei Wörter u, w in (Σ ∪ V )∗ u ⇒ v, falls es eine Regel α → β in R und Wörter u1 , u2 in (Σ ∪ V )∗ gibt, so dass u = u1 αu2 und v = u1 βu2 . 2. Mit ⇒∗ bezeichnen wir die reflexive und transitive Hülle der Relation ⇒. Definition. Für jede Grammatik G heißt die Menge aller Wörter über Σ, die vom Startsymbol ableitbar sind, die Sprache L(G) erzeugt durch G. Kürzer: L(G) = {w ∈ Σ∗ ; S ⇒∗ w}. Alle oben definierten Begriffe verallgemeinern die in Kapitel 2 eingeführten Begriffe für kontextfreie Sprachen. Aber die allgemeinen Grammatiken erzeugen Sprachen, die nicht kontextfrei sein müssen: 104 KAPITEL 4. CHURCHSCHE THESE Beispiel 1. Eine Grammatik für die Sprache {|, ||, ||||, . . . } = {2n ; n ∈ } (die nicht kontextfrei ist! ). Die Idee ist, dass wir mit dem Wort [A] anfangen und die Zahl von A’s verdoppelt werden kann. Dafür verwenden wir eine Variable D, die links auftauchen kann (also [ → [D) und rechts verschwinden kann (also D] → ]), und die auf ihrem Weg nach rechts A verdoppelt: DA → AAD. Am Ende bekommen wir [AA · · · A], wobei die Anzahl der A’s gleich 2n ist. Jetzt brauchen wir nur die Klammern zu entfernen und A in | umwandeln. Formal: G = ({|}, {S, A, D, [, ]}, S, R), wobei R die folgenden Produktionen sind: (1) S → [A] (2) [ → [D (3) D] → ] (4) DA → AAD (5) [ →ε (6) ] →ε (7) A → | Es gilt: L(G) = {2n ; n ∈ }. Beweis. Erst zeigen wir, wie 2n abgeleitet wird, also {2n ; n ∈ S ⇒ [A] Regel (1) ⇒∗ [Dn A] Regel (2) n-mal ⇒ [Dn−1 AAD] Regel (4) 1-mal ⇒∗ [Dn−2 AAAAD2 ] Regel (4) 2-mal .. . ⇒∗ ⇒∗ ⇒ ⇒ ⇒ n [A2 Dn ] n [A2 ] n A2 ] n A2 n 2 Regel Regel Regel Regel Regel } ⊆ L(G): (4) n-mal (3) n-mal (5) (6) (7) Ist umgekehrt w eine Zahl ist, also ein Wort über {|} mit S ⇒∗ w, beweisen wir w = 2n , das heißt L(G) ⊆ {2n ; n ∈ }. Sei S ⇒ w1 ⇒ w2 ⇒ · · · ⇒ w k ⇒ w eine Ableitung von w. Bezeichnen wir durch m die Anzahl von Indizes i, für welche die Regel (2) die Basis für wi ⇒ wi+1 ist. Da wk kein D enthält, musste die Regel (3) genau m-mal angewandt werden. Dabei wurde die Anzahl der A’s bei jedem Durchgang“ eines D’s (von links also [D, nach rechts, d. h. D]) immer verdoppelt, ” da dieser Durchgang nur auf Grund der Regel (4) möglich ist. Am Anfang gibt es genau ein A: aus S ⇒ w1 folgt w1 = [A]. Also entstehen im Laufe der Ableitung genau 2m Symbole A. Da das terminale Symbol | nur durch die Regel (7) erscheinen kann und wk = w keine Variablen enthält, beweist dies, dass m w = |2 . Beispiel 2. Eine Grammatik für die (nicht kontextfreie) Sprache L = {an bn cn ; n ≥ 1}. Sei G = ({a, b, c}, {B, C, S}, S, R) die Grammatik mit den Regeln (1) S → aBC | aSBC (2) CB → BC (3) aB → ab (4) bB → bb (5) bC → bc (6) cC → cc 4.3. GRAMMATIKEN UND TURINGMASCHINEN 105 Das Wort an bn cn , n ≥ 1, liegt in L(G), da es sich wie folgt ableiten lässt: S ⇒∗ an−1 S(BC)n−1 [Regel S → aSBC, (n − 1)-mal angewendet] ⇒ an (BC)n [Regel S → aBC] ⇒∗ a n B n C n [Regel BC → CB, (n − 1)-mal angewendet] ⇒ an bB n−1 C n [Regel aB → ab] ⇒∗ a n bn C n [Regel bB → bb, (n − 1)-mal angewendet] ⇒ ⇒∗ an bn cC n−1 a n bn cn [Regel bC → bc] [Regel cC → cc, (n − 1)-mal angewendet] Umgekehrt beweisen wir, dass nur Wörter der Form an bn cn ableitbar sind. In der Tat: falls w ein Wort ist, das von S ableitbar ist und keine Variable enthält, beweisen wir das folgende: 1. Die Anzahl von a’s im Wort w ist dieselbe wie die von b’s und dieselbe wie die von c’s . In der Tat, die Regeln (2) - (6) ändern die Anzahl der Buchstaben a, b/B oder c/C nicht, und Regel (1) erhöht alle drei dieser Zahlen gleichzeitig um 1. 2. Alle a’s stehen links im Wort w, das heißt, w hat die Form w = an v (und v besteht aus n b’s und n c’s ). Keine der Regeln (1) - (6) ändert nämlich die linke Position von a. 3. Das Wort w enthält nicht die Kombination cb (das heißt, w hat nicht die Form w = ucbv). Um das zu beweisen, betrachten wir die Regeln (3) - (6): diese ändern weder Anzahl noch Position der Buchstaben a, b/B oder c/C im Wort, sie wandeln nur B → b oder C → c um. Wir können daher annehmen, dass in der Ableitung S ⇒∗ w zuerst nur die Regeln (1) und (2) benutzt werden, und dann erst werden die Regeln (3) - (6) angewendet. Genauer: es gibt eine Ableitung: S ⇒ w1 ⇒ w2 ⇒ · · · ⇒ wi ⇒ · · · ⇒ wk = w, wobei für S ⇒ · · · ⇒ wi nur die Regeln (1) und (2) angewendet werden und für wi ⇒ · · · ⇒ wk nur die Regeln (3) - (6). Dann unterscheiden sich die Wörter wi und wk nur dadurch, dass an der Stelle im Wort, an der b steht, wi den Buchstaben B hat und dasselbe gilt analog für c/C. Das Wort wi enthält die Kombination CB nicht, denn keine der Regeln (3) - (6) kann B in b umwandeln, falls vor diesem B entweder C oder c steht. Es folgt, dass das Wort w = wk die Kombination cb nicht enthält. 4. w = an bn cn , denn in 2. haben wir ein Wort v mit n b’s, n c’s und ohne die Kombination cb – das einzige Wort ist v = bn cn . Beispiel 3. Simulation einer TM. Wir zeigen jetzt, wie die Arbeit einer TM vollständig von einer Grammatik simuliert werden kann. Erinnern wir uns an das Konzept von Konfigurationen (q, u, a, v) aus Kapitel 3.1: ... ... a } ⇑| {z } v q Die Konfigurationen werden jetzt statt (q, uav) durch das Wort [uqav] über Σ ∪ Q ∪ {[, ], #} bezeichnet. Also ist die Initialkonfiguration mit Eingabe s1 . . . sn das Wort [q0 s1 . . . sn ]. | {z u Die Arbeit der TM wird durch die Relation ` ( Folgekonfiguration“) beschrieben. ” Wir konstruieren jetzt eine Grammatik G, in der für zwei Konfigurationen gilt: 106 KAPITEL 4. CHURCHSCHE THESE [uqav] ` [u0 q 0 a0 v 0 ] genau dann, wenn [u0 q 0 a0 v 0 ] ⇒ [uqav]. (Also beschreibt die Ableitung in der Grammatik G die Berechnung rückwärts.) Wir benutzen die Bandsymbole Σ der TM als terminale Symbole und die folgenden Variablen: V = Q ∪ {S, #, [, ]}; wir setzen V ∩ Σ = ∅ wie üblich voraus. Also G = (Σ, V, S, R), und die Produktionen R entsprechen den Möglichkeiten von ` (siehe Tabelle 3.1 in Abschnitt 3.1): 1. Für jede Übergangsregel (q, s) → (q 0 , s0 ) der TM mit s0 in Σ ∪ {#} haben wir die Folgekonfigurationen [uqsv] ` [uq 0 s0 v], und wir benötigen also die Produktion (in der Gegenrichtung) (1) q 0 s0 → qs. 2. Für jede Übergangsregel (q, s) → (q 0 , R) der TM haben wir die Folgekonfigurationen [uqsv] ` [usq 0 v] falls v 6= ε und [uqs] ` [usq 0 #] falls v = ε. Wir benötigen dafür die Produktionen (2) sq 0 → qs (3) sq 0 #] → qs] 3. Für jede Übergangsregel (q, s) → (q 0 , L) brauchen wir die Produktionen (4) q 0 s0 s → s0 qs ∀s0 ∈ Σ ∪ {#} 0 (5) [q #s → [qs Nehmen wir jetzt an, dass die TM ein Wort s1 . . . sn über Σ akzeptiert, und dass sie ihr Eingabeband löscht, bevor sie hält. Dann haben wir eine Berechnung, die mit der Initialkonfiguration [q0 s1 . . . sn ] beginnt und mit der Finalkonfiguration [qF #] endet. Das heißt, aufgrund der Produktionen (1) (5) gibt es eine Ableitung (in der Gegenrichtung!) [qF #] ⇒ . . . ⇒ [q0 s1 . . . sn ]. Wir fügen jetzt drei Produktionen hinzu, so dass wir dann vom Startsymbol S das Wort s1 . . . sn ableiten: (6) S → [qF #] (7) [q0 → ε (8) ] → ε Wir haben also die Grammatik GM = (Σ, V ∪ {#, [, ], S}, S, R) mit den Produktionen (1) - (8). Wir beweisen jetzt, dass sie die Sprache L(M ) erzeugt. Satz 1. Falls M eine TM ist, die ihr Band immer löscht, bevor sie hält, dann gilt für die obige Grammatik GM , dass L(M ) = L(GM ). Beweis. 1. Jedes Wort w = s1 . . . sn , das M akzeptiert, ist aus GM ableitbar, das heißt, L(M ) ⊆ L(GM ). In der Tat, für eine gegebene Berechnung, die in der Konfiguration [q0 s1 . . . sn ] beginnt und in [qF #] endet, seien k0 = [q0 s1 . . . sn ] ` k1 ` . . . ` kM = [qF #] die Konfigurationen der Berechnung. Dann gilt S ⇒ [qF #] ⇒ kM −1 ⇒ kM −2 ⇒ · · · ⇒ k1 ⇒ [q0 s1 . . . sn ] ⇒∗ s1 . . . sn , wobei am Anfang die Produktion (6) und am Ende die Produktionen (7) und (8) verwendet wurden. Also gehört s1 . . . sn zu L(GM ). 4.3. GRAMMATIKEN UND TURINGMASCHINEN 107 2. Sei w = s1 . . . sn ein Wort, das von S ableitbar ist. Wir haben eine Ableitung der Form S ⇒ [qF #] ⇒ w1 ⇒ w2 ⇒ . . . ⇒ wM = s1 . . . sn . Wir dürfen annehmen, dass die Regeln (7) und (8) (die bestimmt angewendet wurden, da w1 die beiden Klammern enthält, aber wM nicht) erst am Ende der Ableitung angewendet wurden, also wM −2 = [q0 s1 . . . sn ]. Für die Ableitung w1 ⇒∗ wM −2 wurden nur die Regeln (1) - (6) angewendet. Es ist also hinreichend, zu zeigen, dass, falls für zwei Konfigurationen w und w 0 , w0 ` w aufgrund von (1) - (6) gilt, dann folgt daraus w ` w 0 . (a) Falls die Produktion (1) angewendet wurde, gilt w 0 = [uq 0 s0 v] und w = [uqsv], wobei qs → q 0 s0 eine Übergangsregel ist. Dann ist w 0 eine Folgekonfiguration von w. (b) Falls die Produktion (2) angewendet wurde, gilt w 0 = [usq 0 v] und w = [uqsv]. Wieder ist w 0 eine Folgekonfiguration von w. (c) Falls die Produktion (3) angewendet wurde, gilt w 0 = [usq 0 #] und w = [uqs], und auch diesmal ist w 0 eine Folgekonfiguration von w. Analog mit den Produktionen (4) und (5). Also für w1 = [qF #] und wM −2 = [q0 s1 . . . sn ] folgt aus w1 ⇒∗ wM −2 , dass wM −2 `∗ w1 . Das bedeutet, dass die TM auf die Eingabe s1 . . . sn hält und akzeptiert. Also gehört s1 . . . sn zu L(M ). Korollar 1. Für jede rekursiv-aufzählbare Sprache L gibt es eine Grammatik, die L erzeugt. Beweis. Es gibt eine TM, die L akzeptiert. Sei M eine Modifikation dieser TM, die sich nur dadurch unterscheidet, dass M ihr Band löscht, bevor sie hält. Dann gilt L = L(M ) = L(GM ). Beispiel 4. Die folgende TM akzeptiert die Sprache aller ungeraden Zahlen (über Σ = {|}): M = ({q0 , q1 , q2 }, {|}, δ, q0, qF ) mit Übergängen (q0 , |) → (q1 , #) (q1 , #) → (qF , R) (qF , |) → (q2 , #) (q2 , #) → (q0 , R) Dieser TM entspricht die folgende Grammatik GM = ({|}, {q0 , q1 , q2 , #, [, ], S}, S, R) mit den Produktionen S → [qF #] q1 # → q0 | #qF → q1 # #qF #] → q1 #] q2 # → qF | #q0 → q2 # #q2 #] → q2 #] [q0 →ε ] →ε Satz 2. Jede von einer Grammatik erzeugte Sprache ist rekursiv-aufzählbar. 108 KAPITEL 4. CHURCHSCHE THESE Beweis. Wir wollen zeigen, dass für jede Grammatik G die Sprache L(G) von einer TM akzeptiert werden kann. Wir benutzen eine nichtdeterministische 2-Band-TM, die alle Produktionen von G in einem zusätzlichen Gedächtnis hat. Band 1 ist ein read-only Eingabeband. Auf Band 2 schreibt die TM zu Beginn das Startsymbol S. In jedem Berechnungsschritt zerlegt die TM nichtdeterministisch das Wort w auf Band 2 in drei Wörter: w = upv u, p, v ∈ (Σ ∪ V )∗ mit p 6= ε. Zum Beispiel ist am Anfang die einzige mögliche Zerlegung u = ε, p = S und v = ε. Jetzt wählt die TM nichtdeterministisch eine Produktion von G von der Form p → q (falls keine solche Produktion existiert, hält die TM in einem nichtfinalen Zustand). Dann schreibt die TM das Wort w 0 = uqv auf Band 2 und vergleicht Band 1 mit Band 2. Falls die Inhalte gleich sind, hält die TM und akzeptiert. Falls sie nicht gleich sind, wird der neue Berechnungsschritt (Zerlegung des Wortes w 0 in drei Wörter usw.) gestartet. Es ist klar, dass die Eingabe auf Band 1, falls sie von S ableitbar ist, nach endlich vielen Berechnungsschritten (die der Ableitung der Eingabe aus S entsprechen) akzeptiert wird. Falls umgekehrt die Eingabe nicht zu L(G) gehört, ist jede mögliche Berechnung entweder unendlich oder hält und akzeptiert nicht. 4.4 Chomsky-Hierarchie In den 50er Jahren hat der berühmte Linguist Noah Chomsky formale Grammatiken eingeführt und spezielle Typen untersucht, von denen wir in diesem Skript schon einige kennengelernt haben: Grammatiken vom Typ 3 sind genau die regulären Grammatiken, die wir in Kapitel 2.4 eingeführt haben. Also die, die nur Produktionen der Form A → b1 . . . bn oder A → b1 . . . bn B (A, B sind Variablen und b1 , . . . , bn terminale Symbole) haben dürfen. Wie wir aus 2.4 wissen, erzeugen die regulären Grammatiken genau die regulären Sprachen. Grammatiken vom Typ 2 sind genau die kontextfreien Grammatiken aus Kapitel 2. Hier haben die Produktionen die Form A → a 1 . . . an (A ist eine Variable, a1 , . . . , an sind terminale Symbole oder Variablen). Die entsprechenden Sprachen sind die kontextfreien Sprachen. Grammatiken vom Typ 1 werden auch kontextsensitive Grammatiken genannt. Wir werden sie jetzt einführen und untersuchen. Die Produktionen haben hier die Eigenschaft, dass die Länge der linken Seite der Produktionen kleiner gleich der Länge der rechten Seite ist. Grammatiken vom Typ 0 heißen auch uneingeschränkte Grammatiken (weil es keine Einschränkung für die Produktionen gibt) oder einfach Grammatiken. Diese haben wir in Abschnitt 4.3 eingeführt. Sie entsprechen genau den rekursiv-aufzählbaren Sprachen. Definition. Eine Grammatik heißt kontextsensitiv oder Typ-1-Grammatik, falls in jeder Produktion α → β die Länge von α kleiner gleich der Länge von β ist. Eine Sprache heißt kontextsensitiv, falls sie von einer kontextsensitiven Grammatik erzeugt werden kann. Daraus folgt, dass eine kontextsensitive Sprache nie ε enthält. (Einige Autoren erlauben deswegen auch die Regel S → ε in kontextfreien Grammatiken. Wir aber nicht!) 4.4. CHOMSKY-HIERARCHIE 109 Beispiel 1. Die Sprache {an bn cn ; n ≥ 0}, die nicht kontextfrei ist (siehe 1 in Abschnitt 2.4) ist kontextsensitiv. In der Tat ist die Grammatik in Beispiel 1 in Abschnitt 4.3 offensichtlich kontextsensitiv. Beispiel 2. Jede kontextfreie Sprache, die ε nicht enthält, ist kontextsensitiv. Das folgt aus der Chomsky-Normalform, die immer kontextsensitiv ist, siehe 2.7. Bemerkung 1. Der Name kontextsensitiv“ stammt von der folgenden Form der ” Produktionen: uAw → uvw, wobei A eine Variable und v ein nicht leeres Wort über Σ ∪ V ist. Jede derartige Produktion erlaubt uns, A durch v zu ersetzen, falls sich A im Kontext u?w befindet. Es zeigt sich, dass jede kontextsensitive Sprache mit Hilfe dieser Regeln gegeben werden kann: Satz 1. Jede kontextsensitive Sprache kann von einer Grammatik mit Produktionen uAw → uvw, (A Variable; u, v, w Wörter in (Σ ∪ V )∗ und v 6= ε) erzeugt werden. Beweis. Sei G eine kontextsensitive Grammatik. Jede Produktion A1 A2 . . . An → B 1 B2 . . . Bm (n ≤ m) wird durch Produktionen des obigen Typs ersetzt. Wir nehmen an, dass Ai Variablen sind. (Sonst ersetzen wir Ai durch Variable Ai ∗ und fügen die Produktionen Ai ∗ → Ai hinzu.) Falls n = 2, ersetzen wir A1 A2 → B 1 B2 . . . Bm (m ≥ 2) durch die folgenden vier Produktionen, die neue Variablen C1 und C2 enthalten: A1 A2 → C 1 A2 C1 A2 → C 1 C2 C1 C2 B3 . . . B m → C 1 B2 B3 . . . B m C1 B2 B3 . . . B m → B 1 B2 B3 . . . B m . Jede dieser Produktionen hat die gewünschte Form. Und es ist klar, dass diese Ersetzung keinen Einfluss auf die erzeugte Sprache hat. Analog ersetzen wir für n = 3 A1 A2 A3 → B 1 B2 . . . Bm (m ≥ 3) durch sechs Produktionen mit neuen Variablen C1 , C2 , C3 wie folgt: A1 A2 A3 → C 1 A2 A3 C1 A2 A3 → C 1 C2 A3 C1 C2 A3 → C 1 C2 C3 C1 C2 C3 B4 . . . B m → C 1 C2 B3 B4 . . . B m C1 C2 B3 B4 . . . B m → C 1 B2 B3 B4 . . . B m C1 B2 B3 B4 . . . B m → B 1 B2 B3 B4 . . . B m Usw. für alle n ≥ 2. Beispiel 3. Eine Grammatik für {an bn cn ; n ≥ 1}, die nur Produktionen vom Typ uAw → uvw hat. Wir nehmen die Grammatik aus Beispiel 2 in Kapitel 4.3 und wenden die Prozedur des obigen Beweises darauf an. Statt CB → BC schreiben wir CB → C1 B C1 B → C 1 C2 C1 C2 → BC2 BC2 → BC Bemerkung 2. Die Entscheidung, ob für einen gegebenen gerichteten Graphen G und zwei Knoten x, y ein Pfad von x nach y führt, kann mit einem einfachen 110 KAPITEL 4. CHURCHSCHE THESE Algorithmus durchgeführt werden: wir berechnen die Menge M aller Knoten z, für die ein Pfad von x nach z führt wie folgt. Initialwert: M := {x}. Rekursiv setzen wir M := M ∪ E(M ), wobei E(M ) die Menge aller Endknoten w der Kanten (v, w) ∈ E mit v ∈ M bezeichnet. Der Algorithmus endet, wenn M nicht mehr wächst, und dann ist die Antwort genau dann JA, wenn y ∈ M ist. Satz 2. Jede kontextsensitive Sprache ist rekursiv. Beweis. Für jede kontextsensitive Grammatik G wollen wir einen Algorithmus finden, der für ein beliebiges Wort w entscheidet, ob w in L(G) liegt. Keine Ableitung von w benutzt Wörter länger als n, der Länge von w. Es genügt also, einen Graphen zu konstruieren, dessen Knoten alles Wörter über Σ ∪ V einer Länge ≤ n sind und genau die Relation ⇒ zwischen diesen Wörtern formen. Dieser Graph lässt sich mit einem einfachen brute-force“-Algorithmus konstruieren, der alle möglichen Pro” duktionskombinationen durchgeht. Jetzt reicht es, einen Algorithmus zu benutzen, der entscheidet, ob im Graph ein Pfad von S zu w führt. Schlussbemerkung. Die folgende Hierarchie von Klassen von Sprachen, die ε nicht enthalten, heißt Chomsky-Hierarchie: regulär ⊂ kontextfrei ⊂ kontextsensitiv ⊂ rekursiv ⊂ rekursiv-aufzählbar. Jede dieser Sprachklassen ist ein echter Teil der nächst höheren: die Sprache {0n 1n ; n ≥ 1} ist kontextfrei, aber nicht regulär (siehe 1.8 und 2.1), die Sprache {an bn cn ; n ≥ 0} ist kontextsensitiv, aber nicht kontextfrei. Im nächsten Kapitel zeigen wir eine Sprache Lhalt , die rekursiv aufzählbar, aber nicht rekursiv ist. Es gibt auch rekursive Sprachen, die nicht kontextsensitiv sind, das beweisen wir aber nicht. 4.5 Rekursive Funktionen Berechenbare Funktionen können auch ganz anders modelliert werden, als mit Maschinen, die sie berechnen: wir gehen von sehr einfachen Funktionen (z.B. den konstanten Funktionen und der Nachfolgerfunktion succ) aus und wenden dann Rekursion und Verknüpfung an. Wir erhalten eine sehr reiche Kollektion von Funktionen, die primitiv-rekursiv heißen. Es zeigt sich, dass jede primitiv-rekursive Funktion Turing-berechenbar ist. Leider gilt die umgekehrte Aussage nicht: es gibt Turingberechenbare Funktionen, die nicht primitiv-rekursiv sind. Deshalb wird noch ein Minimierungsoperator µ eingeführt. Funktionen, die sich mit primitiver Rekursion und Minimierung ableiten lassen, heißen rekursiv (oder auch µ-rekursiv). Daraus ergibt sich eine neue Charakterisierung von Turing-berechenbaren Funktionen: es sind genau die rekursiven Funktionen. Das ist eine weitere Bestätigung der Churchschen These. Wir wollen also erst aus einfachen Funktionen, die Basisfunktionen heißen, mit Hilfe von Verknüpfung und Rekursion weitere Funktionen definieren. Die Fakultätsfunktion definiert man z.B. rekursiv mit Multiplikation, die Multiplikation wiederum rekursiv mit Addition und die Addition rekursiv mit der Nachfolgerfunktion succ. Hier endet aber diese Kette: succ ist eine der Basisfunktionen. Wir arbeiten hier mit k-stelligen Funktionen natürlicher Zahlen, d.h. mit Funktionen f : k → , wobei k = × · · · × (k-mal), für k = 1, 2, 3, . . . . f hat also k Variablen im Bereich . Die konstante Funktion Ki mit Ki (n) = i für alle n gilt als 0-stellig, da sie von keiner Variablen abhängt. Nicht-konstante Funktionen sind k-stelllig für k ≥ 1. Besonders einfache k-stellige Funktionen sind die Projektionen π1k , . . . , πkk : die Projektion πik ordnet jedem k-Tupel sein i-tes Element zu, 4.5. REKURSIVE FUNKTIONEN 111 πik (n1 , n2 , . . . , nk ) = ni . Für k = 2 gibt es z.B. zwei Projektionen π12 (n, m) = n und π22 (n, m) = m. Für k = 1 ist π11 (n) = n die Identitätsfunktion. Definition. Die folgenden Funktionen heißen Basisfunktionen: 1. die Nachfolgerfunktion succ (mit succ(n) = n + 1) 2. die Nullfunktion K0 (mit dem einzigen Wert 0) und 3. die Projektionen πik für alle 1 ≤ i ≤ k, k = 1, 2, 3, . . . . Aus den Basisfunktionen können weitere Funktionen mit Hilfe der Verknüpfung definiert werden: Beispiel 1. Konstante Funktionen. Die konstante Funktion K1 entspricht der Verknüpfung von K0 mit succ: K1 = succ(K0 ). Analog K2 = succ(K1 ) = succ(succ(K0 )) usw. Beispiel 2. Die Funktion f (n) = n + 2 für alle n ∈ succ mit sich selbst: f (n) = succ(succ(n)). ist die Verknüpfung von Beispiel 3. Die Funktion g(n, m) = m + 2 (für alle n, m ∈ ) ist eine Verknüpfung der zweiten Projektion π22 (n, m) (die n wegfallen lässt) und der Funktion f aus Beispiel 2: g(n, m) = f (π22 (n, m)) = succ(succ(π22 (n, m)). Bemerkung 1. 1. Im Allgemeinen definieren wir die Verknüpfung mehrstelliger Funktionen wie üblich: falls (k ≥ 1) f: k → eine k-stellige Funktion ist und g1 , . . . , gk : m → (m ≥ 0) k m-stellige Funktionen sind, ist die Verknüpfung von f mit g1 , . . . , gk die m-stellige Funktion h: m → , die durch h(n1 , . . . , nm ) = f (g1 (n1 , . . . , nm ), g2 (n1 , . . . , nm ), . . . , gk (n1 , . . . , nm )) für alle (n1 , . . . , nm ) auf m definiert wird. 2. Neben der Verknüpfung wollen wir die sogenannte primitive Rekursion verwenden, um neue Funktionen zu erzeugen. Zum Beispiel lässt sich die Fakultätsfunktion f (n) = n! mit Hilfe primitiver Rekursion durch die Multiplikation h(n, m) = n ∗ m und den Initialwert 1 = f (0) wie folgt definieren: f (0) = 1; f (n + 1) = h(n, f (n)) = n ∗ f (n). Die Definition einer einstelligen Funktion f (n) durch primitive Rekursion hat zwei Bestandteile: eine Konstante k und eine zweistellige Funktion h(n, m). Dann definiert man f (0) = k und f (n + 1) = h(n, f (n)). 112 KAPITEL 4. CHURCHSCHE THESE Allgemeiner: Definition. Wir sagen, dass eine k-stellige Funktion f (n1 , . . . , nk ) durch primitive Rekursion mit Hilfe einer (k − 1)-stelligen Funktion g und einer (k + 1)-stelligen Funktion h definiert ist, falls für alle n1 , . . . , nk−1 , m ∈ gilt f (n1 , . . . , nk−1 , 0) = g(n1 , . . . , nk−1 ) und f (n1 , . . . , nk−1 , m + 1) = h(n1 , . . . , nk−1 , m, f (n1 , . . . , nk−1 , m)). Beispiel 4. Addition. Es gilt n+0=n und n + (m + 1) = succ(n + m). Also ist add(n, m) = n + m durch primitive Rekursion mit g(n) = n = π11 (n) und h(n, m, i) = succ i = succ(π33 (n, m, i)) definiert. In der Tat gilt add(n, 0) = g(n) add(n, m + 1) = h(n, m, add(n, m)). Beispiel 5. Die Multiplikation ist die (primitiv-)rekursive Funktion: n∗0 = 0 n ∗ (m + 1) = (n ∗ m) + m. Genauer: für mal(n, m) = n ∗ m definieren wir g(n) = K0 und h(n, m, i) = add(m, i) = add(π23 (n, m, i), π33 (n, m, i)). Dann gilt mal(n, 0) = g(n) mal(n, m + 1) = h(n, m, mal(n, m)). Definition. Eine Funktion heißt primitiv-rekursiv , falls sie durch endlich viele Anwendungen von Verknüpfung und primitiver Rekursion auf die Basisfunktionen definiert werden kann. Mit anderen Worten ist die kleinste Klasse von Funktionen, die alle Basisfunktionen enthält und unter Verknüpfung und primitiver Rekursion abgeschlossen ist, die Klasse aller primitiv-rekursiver Funktionen. Beispiele: Kn , f (n) = n + 2, g(n, m) = m + 2, add(n, m) und mal(n, m) sind primitiv-rekursiv. Beispiel 6. Die Fakultätsfunktion m! ist primitiv-rekursiv, da sie mit der folgenden primitiven Rekursion definiert werden kann: 0! = 1 (m + 1)! = mal(m + 1, m!). Hier ist also g = K1 und h(x, y) = mal(x + 1, y) = mal(succ(π12 (x, y), π22 (x, y)). Da g und h beide primitiv-rekursiv sind, ist auch m! primitiv-rekursiv. Beispiel 7. Die Vorgängerfunktion in der Form 0 falls n = 0 f (n) = n − 1 falls n > 0 ist primitiv-rekursiv: f (0) = 0 = K0 f (n + 1) = n = π12 (n, f (n)). Also g = K0 und h(n, m) = π12 (n, m). 4.5. REKURSIVE FUNKTIONEN 113 Beispiel 8. Diemodifizierte Subtraktion n − m falls n ≥ m n −̇ m = 0 falls n < m ist primitiv-rekursiv: n −̇ 0 = n n −̇ (m + 1) = f (n −̇ m) für f aus Beispiel 7. Hier gilt also g(n) = n und h(n, m, i) = f (π33 (n, m, i)) = f (i). Bemerkung 2. Die Klasse aller primitiv-rekursiven Funktionen ist so mächtig, dass es nicht einfach ist, ein Beispiel einer Funktion außerhalb dieser Klasse zu finden (siehe Beispiel 9). Deswegen ist der folgende Satz eine neue Bestätigung der Stärke von Turingmaschinen. Satz 1. Jede primitiv-rekursive Funktion ist Turing-berechenbar. Beweis. Es genügt, zu beweisen, dass gilt: 1. alle Basisfunktionen sind Turing-berechenbar, 2. die Verknüpfung Turing-berechenbarer Funktionen ist Turing-berechenbar, und 3. die primitive Rekursion, die mit zwei Turing-berechenbaren Funktionen arbeitet, ergibt eine Turing-berechenbare Funktion. Dann sind alle primitiv-rekursiven Funktionen Turing-berechenbar. (1) ist trivial und (2) auch: Die Verknüpfung f (g(n)) wird z.B. von einer 2-BandTM berechnet, wobei Band 1 die Funktion g(n) berechnet und das Ergebnis als Eingabe der Funktion f auf Band 2 kopiert. Wir wollen also (3) beweisen, d.h., dass es für die Funktion f mit f (n1 , . . . , nk , 0) = g(n1 , . . . , nk ) und f (n1 , . . . , nk , m + 1) = h(n1 , . . . , nk , m, f (n1 , . . . , nk , m)) eine TM gibt, falls Mg und Mh zwei TM sind, die g und h berechnen. Unsere TM hat fünf Bänder: Band 1 (Eingabeband) Band 2 (Schrittzähler) n1 $ n2 $ ... $ nk m Band 3 (simuliert Mg ) FUNKTION g Band 4 (simuliert Mh ) FUNKTION h Band 5 (Ausgabeband) ZWISCHENERGEBNIS Die Berechnung von f erfolgt in Schritten Nr. m = 0, 1, 2, . . . , die auf Band 2 gezählt werden und die wie folgt ablaufen: Band 2 enthält 0, auf Band 3 wird n1 , . . . , nk−1 (von Band 1) Schritt 0: kopiert und g(n1 , . . . , nk−1 ) wird berechnet. Das Ergebnis wird auf Band 5 geschrieben. Schritt m + 1: Falls nk der Inhalt von Band 2 ist, hält die TM. (Band 5 enthält dann das Ergebnis.) Falls nicht, wird auf Band 4 die Eingabe n1 $ . . . $ n k $ m $ j geschrieben. j = f (n1 , . . . , nk−1 , m) ist der Inhalt von Band 5, m der von Band 2. Jetzt wird h(n1 , . . . , nk , m, j) berechnet und das Ergebnis auf Band 5 geschrieben. Der Inhalt von Band 2 wird um eins erhöht. 114 KAPITEL 4. CHURCHSCHE THESE Bemerkung 3. Nicht jede Turing-berechenbare Funktion ist primitiv-rekursiv. In der Tat sind alle primitiv-rekursiven total (d.h. überall definiert), und es gibt partielle Turing-berechenbare Funktionen. Aber auch alle totalen Turing-berechenbaren Funktionen sind leider nicht primitivrekursiv. Das können wir abstrakt wie folgt zeigen: alle primitiv-rekursiven Funktionen können wir systematisch aufzählen, z.B. setzen wir f0 = K0 , f1 = succ, f2 = π11 . Mit den gegebenen Funktionen f0 , . . . , fi machen wir alle möglichen Verknüpfungen und primitiven Rekursionen. Dabei entstehen fi+1 , . . . , fj , dann ist fj+1 die nächste noch nicht eingenommene Projektion, usw. Diese Aufzählung kann bestimmt eine TM durchführen. Dann ist die Funktion P (n) = 1 + fn (n, n, . . . , n) Turing-berechenbar. Aber P ist nicht primitiv-rekursiv: falls nämlich P = fn , haben wir P (n) = 1 + fn (n) 6= fn (n) – ein Widerspruch. Es ist U. Ackermann 1928 gelungen, ein viel konkreteres Beispiel einer Funktion anzugeben, die nicht primitiv-rekursiv ist, sich aber mit einem einfachen Algorithmus berechnen läßt. Die Funktion, die man heute Ackermann-Funktion nennt, ist eine von R. Peter und R. M. Robinson später entdeckte Vereinfachung der ursprünglichen Idee: Beispiel 9. Die Ackermann-Funktion A : 2 → ist wie folgt definiert: A(0, m) = m + 1 A(n + 1, 0) = A(n, 1) und A(n + 1, m + 1) = A(n, A(n + 1, m)). Es gilt also A(0, 0) = 1, A(0, 1) = 2, A(1, 0) = A(0, 1) = 2, A(0, 2) = 3, A(1, 1) = A(0, A(1, 0)) = A(0, 2) = 3, A(2, 0) = A(1, 1) = 3, usw. Wir erhalten einen Algorithmus, um jeden Wert A(n, m) zu berechnen: alle möglichen Paare (n, m) werden so aufgezählt, dass der Wert A(n, m) direkt aus den vorigen Werten berechnet wird: (0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0), . . . , Das können wir durch eine TM realisieren, und wir sehen also, dass die Ackermann-Funktion TM-berechenbar ist. Trotzdem ist sie nicht primitiv-rekursiv! Man kann nämlich beweisen, dass sie schneller wächst, als jede primitiv-rekursive Funktion. Es gilt z.B. folgendes, wie sich leicht durch Induktion über m beweisen lässt: A(1, m) = m + 2 A(2, m) = 2m + 3 A(3, m) = 2m+3 − 3 .. 2 .. 2 A(4, m) = 22 − 3, wobei 22 m + 2 Exponentiationen hat. Zum Beispiel 16 A(4, 1) = 216 − 3 und A(4, 2) = 22 − 3 > 101000 . Bemerkung 4. Wir wollen jetzt die Klasse aller primitiv-rekursiven Funktionen durch eine neue Operation ergänzen, um alle berechenbaren Funktionen repräsentieren zu können. Das wird der Minimierungsoperator µ sein, der z.B. jeder 2-stelligen Funktion f (n, m) die 1-stellige Funktion µf (n) = min{m; f (n, m) = 0} zuordnet. Hier müssen wir aber aufpassen: µf ist nicht immer definiert, da es für eine Zahl n geschehen kann, dass f (n, m) 6= 0 für alle m ∈ . Deshalb arbeiten 4.5. REKURSIVE FUNKTIONEN 115 wir jetzt mit partiellen Funktionen (das ist nicht überraschend, denn die Turingberechenbaren Funktionen sind im allgemeinen auch partiell). Definition. Für jede partielle (k +1)-stellige Funktion f (n1 , . . . , nk , nk+1 ) bezeichnen wir mit µf die folgende partielle k-stellige Funktion: µf (n1 , . . . , nk ) ist die kleinste Zahl i mit f (n1 , . . . , nk , i) = 0; falls keine solche Zahl i existiert, ist µf (n1 , . . . , nk ) undefiniert. Eine Funktion heißt rekursiv (oder µ-rekursiv), wenn sie durch die Basisfunktionen und endlich viele Anwendungen von 1. Verknüpfung, 2. primitiver Rekursion und 3. Minimierung µ definiert werden kann. Beispiel 10. Diepartielle Vorgängerfunktion n − 1 falls n > 0 pred(n) = undef. für n = 0 ist rekursiv, denn für die Funktion f (n, m) = (succ m) −̇ n (siehe Beispiel 8) gilt pred(n) = µ((succ m) −̇ n). Beispiel 11. Die Subtraktion n − m falls n ≥ m sub(n, m) = undef. falls n < m ist rekursiv: wir haben sub(n, 0) = n sub(n, m + 1) = pred(sub(n, m)), also ist sub primitiv-rekursiv durch g(n) = π11 (n) und h(n, m, i) = pred(i) = pred(π33 (n, m, i)) definiert (g und h sind rekursiv). Beispiel 12. Die Division k falls n = mk n:m= undef. falls n nicht durch m teilbar ist ist rekursiv. Der erste Versuch wäre, n : m als µ(n − m ∗ k) zu definieren, denn n − m ∗ k = 0 genau dann, wenn k = n : m. Das ergibt leider 0 : 0 = 0. Deswegen müssen wir n − m ∗ k durch n − (succ(pred(m)) ∗ k ersetzen: n : m = µf (n, m) für f (n, m, k) = n − succ(pred(m)) ∗ k = sub(n, mal(succ(pred(m))), k). Jetzt gilt: die Division durch m = 0 ist undefiniert, für m > 0 ist f (n, m, k) = n − m ∗ k und µf (n, m) = n : m genau dann, wenn n : m definiert ist. Satz 2. Jede rekursive Funktion ist Turing-berechenbar. Beweis. Es genügt zu den Punkten 1. - 3. aus Satz 1 einen vierten Punkt hinzuzufügen: 4. Falls f Turing-berechenbar ist, so ist es auch µf . 116 KAPITEL 4. CHURCHSCHE THESE Sei M eine TM, die f berechnet. Wir konstruieren eine 3-Band TM für µf wie folgt: n1 $ n2 $ . . . $ nk Band 1 (Eingabeband) Band 2 (Schrittzähler) i Band 3 (simuliert M ) FUNKTION f Am Anfang wird i = 0 auf Band 2 geschrieben, und dann wird auf Band 3 immer f (n1 , . . . , nk , i) berechnet. Falls das Ergebnis 0 ist, hält die TM, und Band 2 enthält die Ausgabe. Falls das Ergebnis nicht 0 ist, wird Band 2 um 1 erhöht (i := i + 1), und f (n1 , . . . , nk , i) wird erneut berechnet, usw. Satz 3. (Ohne Beweis) Jede Turing-berechenbare Funktion ist rekursiv. Schlussbemerkung: Wir sehen, dass viele Modelle dieselbe Klasse von entscheidbaren Problemen beschreiben: • Turingmaschinen (und alle ihre Modifikationen), • RAMs, • Grammatiken, • rekursive Funktionen. Das ist eine Untermauerung der Churchschen These. Überlegen Sie sich, warum die Bemerkung nach Satz 1 nicht auf µ-rekursive Funktionen verallgemeinert werden kann (was Satz 3 widerlegen würde!). Die Regel P (n) = 1+fn(n), ergibt nämlich keinen Algorithmus, der die Funktion P berechnet, da fn partielle Funktionen sind! Kapitel 5 Unentscheidbare Probleme Es gibt wichtige praktische Fragen, die sich von keinem Algorithmus lösen lassen. Beispiel: die Entscheidung, ob ein gegebenes Programm (sagen wir in PASCAL) auf eine gegebene Eingabedatei hält. Es wäre von größter praktischer Bedeutung, einen Algorithmus zur Verfügung zu haben, der als Eingabe ein Paar (P, D) hat, wobei P ein PASCAL-Programmcode und D eine Datei für P ist, und das die richtige Ausgabe hält“ oder hält nicht“ ergibt. Solch ein Algorithmus existiert aber ” ” nicht. Das beweisen wir für eine Variante, die (statt mit PASCAL-Programmen) mit Turingmaschinen arbeitet. Außerdem zeigen wir weitere Beispiele unentscheidbarer Probleme. Der formale Beweis, dass es vernünftige“ und wichtige Fragen gibt, die einfach kein ” Algorithmus lösen kann, ist eines der wichtigsten Ergebnisse in diesem Skript, denn daraus folgt, dass man bei dem Versuch, eine Aufgabe zu lösen, immer darauf achten muss, dass die Aufgabe keine Variante eines unlösbaren Problems ist. Wir beginnen aber mit einem positiven Ergebnis: es gibt eine universelle Turingmaschine, also eine, die (wie moderne Rechner) programmiert werden kann. 5.1 Universelle Turingmaschine Wir konstruieren jetzt eine universelle (oder programmierbare“) TM, die bei Ein” gaben der Form (c, w) c – Algorithmus, w – Datei die Datei w entsprechend des Algorithmus c berechnet. Da wir Algorithmen als Turingmaschinen interpretieren, können wir genauer sagen: eine universelle Turingmaschine Mu erhält als Eingabe ein Wort c(M )w, wobei c(M ) eine passende Codierung der (beliebigen) Turingmaschine M und w ein (beliebiges) Eingabewort für M ist. Dann berechnet Mu die Eingabe und liefert genau dasselbe Ergebnis, das die Maschine M auf Eingabe w liefert. Das können wir entweder in der Akzeptor-Variante interpretieren, also Mu hält genau dann auf c(M )w, wenn M auf w hält, und dann akzeptiert Mu genau dann, wenn M akzeptiert, oder in der Rechner-Variante, also Mu führt für c(M )w zu der gleichen Ausgabe wie M für w. Es zeigt sich, dass die Maschine Mu , die wir jetzt beschreiben, beide Rollen erfüllt. 117 118 KAPITEL 5. UNENTSCHEIDBARE PROBLEME Bemerkung 1. 1. Jede TM kann durch eine TM mit dem Bandalphabet Σ = {0, 1} simuliert werden. Wir codieren die ursprünglichen Eingabesymbole si und das ursprüngliche Blanksymbol wie folgt: Symbol # s1 s2 ... sk Code 01 011 013 . . . 01k+1 Die neue Maschine hat also nur an den noch nicht beschrifteten Feldern Blanksymbole. Die einzelnen Übergänge werden wie folgt simuliert: (a) ein Schritt nach rechts wird durch eine Bewegung des Kopfes unter die nächste 0 nach rechts simuliert; analog für links (b) Überschreibung von si und sj wird dadurch simuliert, dass 01j+1 statt 01i+1 geschrieben wird. Dazu müssen, falls z.B. i = 1 und j = 2, alle Symbole 0, 1 rechts vom Lesekopf ein Feld nach rechts geschoben werden (und vorher muss die momentane Kopfposition gespeichert werden – z.B. dadurch, dass die momentan gelesene 0 gelöscht wird). 2. Eigentlich kann jede TM durch eine TM mit Σ = {|} simuliert werden. Die Idee ist gleich, aber die Details sind aufwendiger. Wir beschränken uns auf TM mit dem binären Bandalphabet Σ = {0, 1}. Also hat die universelle Turingmaschine Mu sowie alle simulierten Maschinen M dieses Eingabealphabet. Codierung c(M ) von Turingmaschinen M : Für jede TM M = (Q, {0, 1}, δ, q0, q1 ) deren Zustände Q = {q0 , q1 , . . . , qn−1 } so durchnummeriert sind, dass q0 der Initialzustand und q1 der Finalzustand ist, definieren wir ein Codewort c(M ) ∈ {0, 1}∗ wie folgt. Wir benutzen 0i um die Zahl i zu codieren und 1 als Trennungssymbol. Das Wort c(M ) hat die folgende Form: Am Anfang steht 111 als Trennungssymbol, dann folgt 0n , das die Anzahl n aller Zustände bezeichnet. Dann werden die einzelnen t Übergangsregeln aus R durch binäre Wörter w1 , . . . , wt codiert, wie später erklärt wird, und durch eine 1 voneinander getrennt. Am Ende schreiben wir wieder 111. Der Code hat also die Form c(M ) = 1110n1w1 1w2 1 . . . 1wt 111. Um die Übergangsregeln zu codieren, schreiben wir für Zustände 10i+1 statt qi und codieren die Symbole L, R, #, 0, 1 wie folgt Symbol Code L 10 R 100 # 10000 0 104 1 105 Die Übergangsregel erhält also den Code (qi , 0) → (qj , L) w = 10i+1 104 10j+1 10, die Übergangsregel den Code (qi , #) → (qj , 0) w = 10i+1 103 10j+1 104 usw. 5.1. UNIVERSELLE TURINGMASCHINE 119 Beispiel 1. Wir codieren die Maschine M1 mit Zuständen q0 , q1 und Übergangsregeln (q0 , 1) → (q1 , R) (q1 , #) → (q1 , 1) wie folgt: c(M1 ) = 111001w11w2 111 wobei w1 der Code für (q0 , 1) → (q1 , R) ist: w1 = 10105100100 und w2 der Code für (q1 , #) → (q1 , 1) ist: w2 = 100103100105. Insgesamt ergibt sich c(M1 ) = 111001101051001001100103100105111. Wir bemerken, dass einzelne Übergangsregeln voneinander durch 11 getrennt werden. Jede Turingmaschine wird durch ihren Code vollständig beschrieben. Beispiel 2. Falls eine Turingmaschine den Code c(M2 ) = 1110001101051010311010310101100104103 100111 hat, muss es die Maschine M2 = ({q0 , q1 , q2 }, {0, 1}, δ, q0, q1 ) mit den Übergangsregeln (q0 , 1) → (q0 , #) (q0 , #) → (q0 , L) (q1 , 0) → (q2 , R) sein. Bemerkung 2. Erinnern wir uns an die in Kapitel 3 eingeführte Sprache Lcode = { c(M ) | M ist eine TM, die c(M ) nicht akzeptiert } . Zum Beispiel das Wort c(M1 ) in Beispiel 1 ist ein Codewort einer TM. Akzeptiert diese TM das Wort c(M1 ) ? Wir haben Konfigurationen (q0 , 111 . . . 111) ` (q1 , 111 . . . 111) | {z } | {z } c(M1 ) c(M1 ) und da kein Übergang (q1 , 1) →? definiert ist, hält M1 im Finalzustand q1 . Das Wort c(M1 ) wird also akzeptiert, das heißt, c(M1 ) ∈ / Lcode. In Beispiel 2 wird c(M2 ) von M2 wie folgt berechnet: erst löscht der Kopf das erste Symbol 1 und dann bewegt er sich immer nach links. Also hält M2 nicht, deswegen akzeptiert sie das Wort c(M2 ) nicht, woraus folgt c(M2 ) ∈ Lcode. 120 KAPITEL 5. UNENTSCHEIDBARE PROBLEME Wie in Abschnitt 3.3 bewiesen, ist die Sprache Lcode nicht rekursiv-aufzählbar. Das bedeutet, dass kein Algorithmus entscheiden kann, ob eine beliebige TM ihr eigenes Wort akzeptiert oder nicht. In konkreten Fällen ist diese Entscheidung trotzdem möglich. Die Unentscheidbarkeit von Lcode (oder eines beliebigen anderen Problems) bezieht sich immer nur auf die Klasse aller möglichen Eingaben, nie auf einen Einzelfall. Universelle Turingmaschine Mu Wir konstruieren jetzt eine universelle Turingmaschine Mu . Also reagiert sie auf die Eingabe c(M )w, wobei M eine TM und w ein Wort über {0, 1} ist, wie folgt: 1. Mu hält genau dann, wenn M auf das Wort w hält, 2. Mu akzeptiert genau dann, wenn M das Wort w akzeptiert 3. falls M gehalten hat, hat Mu auf Band 1 dasselbe Ausgabewort wie M . Die Maschine Mu wird als eine 3-Band TM beschrieben, aber wir wissen, dass das unwichtig ist, weil wir eine 1-Band TM konstruieren können, die Mu simuliert. BAND 1 BAND 2 # 1 1 1 | ... {z c(M ) 1 1 1 1 0 1 ... } | {z w 1 # # } ... Enthält c(M ) 0 0 ... | {z BAND 3 i+1 0 } Zustand qi Band 1 enthält am Anfang die Eingabe c(M )w und die Bänder 2 und 3 sind, wie üblich, leer. Zur Vorbereitung auf die Simulation führt Mu die folgenden Schritte aus: 1. c(M ) wird von Band 1 auf Band 2 kopiert und auf Band 1 gelöscht, 2. der Kopf von Band 1 wird auf das erste Symbol von w gestellt 3. Auf Band 3 wird 0 geschrieben (Zustand q0 ), und der Kopf wird auf die 0 gestellt. BAND 1 # 1 0 1 ... | {z 1 # # } ... {z 1 1 1 } ⇑ BAND 2 c(M ) 1 1 1 | ⇑ BAND 3 # 0 # ⇑ c(M ) ... 5.1. UNIVERSELLE TURINGMASCHINE 121 Dann wird M in rekursiven Schritten wie folgt simuliert (so dass das Band von M identisch mit dem Band 1 von Mu ist und der Zustand von M gleich qi ist, wobei 0i+1 auf Band 3 von Mu steht): Simulation von M : Der Kopf von Band 1 liest s = #, 0 oder 1, also ein Symbol, das den Code 10p hat, wobei p = 3 (#), p = 4 (0) oder p = 5 (1) gilt. Jetzt beginnt der Kopf auf Band 2 eine systematische Suche nach der Kombination 10i+1 10p , wobei i + 1 die Zahl der 0’en auf Band 3 ist. Falls die Kombination 10i+1 10p nicht gefunden wurde, hat die Maschine M keine Übergangsregel (qi , s) →?, deshalb hält M . Also hält auch Mu (wenn sie die rechte Gruppe 111 auf Band 2 erreicht hat, ohne die gesuchte Kombination zu finden). Mu akzeptiert genau dann, wenn Band 3 den Inhalt 00 hat, d.h., genau dann, wenn M im Finalzustand q1 gehalten hat. Falls die Kombination 10i+1 10p gefunden wurde, liest der Kopf auf Band 2 weiter bis zur nächsten Gruppe 11. Wir haben jetzt das Wort 10i+1 10p 10j+1 10r 11 . . . auf Band 2 und das bedeutet, dass eine Übergangsregel von M die Form (qi , s) → (qj , s0 ) s0 hat den Code 10r (r = 1, . . . , 5) hat. Die Maschine Mu ändert den Bandinhalt von Band 3 zu 0j+1 und bewegt den Kopf auf Band 1 nach links oder rechts, falls r = 1 oder 2 ist, oder Mu überschreibt s mit #(falls r = 3), 0 (r = 4) oder 1 (r = 5). Jetzt ist Mu für den nächsten Simulationsschritt vorbereitet. Bemerkung 3. 1. Die obige Codierung kann auch auf nichtdeterministische Turingmaschinen mit dem Bandalphabet {0, 1} angewendet werden. 2. Es ist einfach zu entscheiden, ob ein binäres Wort v der Code einer (deterministischen oder nichtdeterministischen) TM ist. Die Codierungen sind nämlich alle von der Form (1) v = 1110n1w1 1w2 1 . . . 1wt 111, wobei w1 , . . . , wt verschiedene Wörter der Form (2) 10i+1 10p 10j+1 10r mit i, j = 0, . . . , n − 1, p = 3, 4, 5 und r = 1, 2, 3, 4, 5 sind. Umgekehrt ist jedes Wort v, das (1) und (2) erfüllt, der Code einer TM. Mit anderen Worten ist die Sprache aller Codierungen von allen nichtdeterministischen TM rekursiv. Auch die Sprache aller Codierungen aller deterministischen TM ist rekursiv: hier muss der Algorithmus nur noch für alle Paare k, k 0 = 1, . . . , t von Indizes mit wk = 10i+1 10p 10j+1 10r und wk0 = 10i + 110p 10j überprüfen, ob j = j 0 und r = r0 . 0 +1 10r 0 122 KAPITEL 5. UNENTSCHEIDBARE PROBLEME 5.2 Das Halteproblem Gibt es einen Algorithmus, der für jedes Paar (Algorithmus c, Datei w) entscheidet, ob c auf die Datei w hält? Aus Abschnitt 5.1 wissen wir, dass es einen Algorithmus gibt, der auf die Eingabe (c, w) das Ergebnis von c auf die Datei w berechnet - das macht die universale Turingmaschine! Dennoch ist die Antwort auf die obige Frage, die als Halteproblem bekannt ist, negativ. Auch dann, wenn wir uns nur auf die Algorithmen beschränken, die von TM mit dem Bandalphabet {0, 1} repräsentiert werden, ist die Antwort negativ. Für diese Maschinen M haben wir die Codierung c(M ) aus Abschnitt 5.1, und wir können das Halteproblem präziser formulieren: ist die Sprache Lhalt = { v | v = c(M )w für ein binäres Wort w und eine Turingmaschine M , die auf Eingabe w hält } rekursiv? Wir beweisen, dass Lhalt nicht rekursiv (also das Halteproblem nicht entscheidbar) ist, sie aber rekursiv-aufzählbar ist. Daraus folgt, dass das Komplement Lhalt nicht rekursiv-aufzählbar ist. Das bedeutet, dass das Problem, ob ein Algorithmus c auf die Datei w nicht hält, nicht einmal mehr semi-entscheidbar ist. Bemerken wir, dass in jedem Wort v = c(M )w der Code c(M ) eindeutig bestimmt ist (aufgrund der Trenngruppen 111 am Anfang und Ende von c(M )) und also auch w eindeutig bestimmt ist. Es gibt einen Algorithmus, der überprüft, ob u diese Form hat – siehe Bemerkung in Abschnitt 5.1. Bemerkung 1. Viele (auch ungelöste!) mathematische Probleme kann man umformulieren zu Fragen, ob eine leicht konstruierbare TM auf eine Eingabe hält. Beispiel 1. Beispiel einer TM mit sehr interessantem Halteproblem. Es ist ziemlich trivial, eine 5-Band-TM zu konstruieren, die auf Band 2 systematisch alle Zahlen n = 3, 4, 5, . . . schreibt und für jede Zahl n auf die Bänder 3 - 5 systematisch alle Zahlen a, b, c ≥ 2 schreibt und dann auf Band 1 die Zahl an + b n − c n berechnet. Falls diese Zahl 0 ist, hält die TM. Falls nicht, berechnet die TM den nächsten Quadrupel (n, a, b, c). Die Entscheidung, ob diese Turingmaschine M auf die leere Eingabe hält, das heißt, ob c(M ) ∈ Lhalt gilt, ist bestimmt höchst kompliziert: dies ist äquivalent zum Beweis des berühmten Satzes von Fermat! Satz 1. Die Sprache Lhalt ist rekursiv-aufzählbar. Beweis. Die folgende Turingmaschine akzeptiert Lhalt : TURINGMASCHINE M0 v EINGABE / Hat v die Form v = c(M )w für eine TM M ? JA / Hält Mu auf Eingabe v? NEIN NEIN v nicht akzeptiert v nicht akzeptiert JA / v akzeptiert 5.2. DAS HALTEPROBLEM 123 Also überprüft M0 , ob die Eingabe die Form c(M )w hat (siehe Bemerkung in 5.1), und falls das der Fall ist, simuliert sie die universale Turingmaschine Mu . Die Eingabe v wird genau dann von M0 akzeptiert, wenn v = c(M )w und Mu (akzeptierend oder nicht akzeptierend) auf die Eingabe v hält. Äquivalent dazu ist: genau dann, wenn M auf die Eingabe w hält. Kürzer: L(M0 ) = Lhalt . Satz 2 (Unentscheidbarkeit des Halteproblems). Die Sprache Lhalt ist nicht rekursiv. Beweis. Die Annahme, dass Lhalt rekursiv ist, führt zu einem Widerspruch: es folgt, dass die Sprache Lcode = {w; w = c(M ) für eine Turingmaschine M mit w ∈ / L(M )} rekursiv-aufzählbar ist. Das ist aber falsch, siehe Beispiel 2 in Kapitel 3.3. Sei Mhalt eine TM, die Lhalt akzeptiert und auf jede Eingabe hält. Dann lässt sich in der Tat eine TM konstruieren, die die Sprache Lcode akzeptiert: TURINGMASCHINE Mcode w EINGABE / Hat w die Form w = c(M ) für eine TM M ? NEIN JA / Akzeptiert Mhalt Eingabe ww? JA / Akzeptiert Mu Eingabe ww? NEIN w nicht akzeptiert JA / w nicht akzeptiert NEIN w akzeptiert w akzeptiert Das heißt, dass die Turingmaschine Mcode eine Eingabe w wie folgt berechnet: 1. Mcode überprüft, ob w = c(M ) für eine Turingmaschine M gilt (siehe Bemerkung in 5.1). 2. Falls ja, wiederholt Mcode die Eingabe und schreibt also ww = c(M )w auf das Band. 3. Jetzt simuliert Mcode die Maschine Mhalt bis sie hält. (a) Falls Mhalt die Eingabe ww nicht akzeptiert, hält Mcode und akzeptiert w. In diesem Fall hält nämlich die Maschine M nicht auf die Eingabe w (denn c(M )w ∈ / Lhalt ); also wird w von M nicht akzeptiert – es folgt w ∈ Lcode. (b) Falls Mhalt akzeptiert, simuliert Mcode die universale TM auf dieselbe Eingabe ww. Da c(M )w ∈ Lhalt gilt, hält M auf die Eingabe w, also hält die universale TM auf die Eingabe c(M )w. Mcode akzeptiert genau dann, wenn Mu nicht akzeptiert. Die Turingmaschine Mcode hält auf jede Eingabe: der erste Schritt hält (denn die Sprache aller Codes ist rekursiv, siehe 5.1), der zweite hält nach unserer Voraussetzung von Mhalt , und der letzte hält, denn Mu erhält nur solche Eingaben ww, die von Mhalt akzeptiert werden, das heißt Eingaben c(M )w mit w = c(M ), so dass M auf w hält (oder äquivalent: Mu hält auf die Eingabe c(M )w = ww). Welche Eingaben w akzeptiert Mcode? Genau die der Form w = c(M ), wobei entweder 124 KAPITEL 5. UNENTSCHEIDBARE PROBLEME • M auf w nicht hält, d.h., Mhalt akzeptiert die Eingabe c(M )w nicht, oder • M auf w hält und nicht akzeptiert, d.h., Mu akzeptiert die Eingabe c(M )w nicht. Also gilt: w ∈ L(Mcode) genau dann, wenn w = c(M ) und w ∈ / L(M ); oder kürzer: L(Mcode) = Lcode, ein Widerspruch. Korollar 1. Das Problem, ob eine TM nicht hält, ist nicht semi-entscheidbar. D.h., die Sprache Lhalt ist nicht rekursiv-aufzählbar. Beweis. Das folgt aus Satz ??? : falls Lhalt und Lhalt rekursiv-aufzählbar wären, wäre Lhalt rekursiv. 5.3 Weitere unentscheidbare Probleme Wir zeigen jetzt weitere Probleme, die nicht entscheidbar sind. Wir benutzen ständig die Codierung c(M ) von (deterministischen und nichtdeterministischen) Turingmaschinen M aus Kapitel 5.1. Auch alle Modifikationen von Turingmaschinen mit Bandalphabet {0, 1} aus Abschnitt 3.2 sind damit codiert. Falls M z.B. eine nichtdeterministische k-Band TM ist, bezeichnen wir mit c(M ) den Code einer 1-BandTM, die M simuliert. Auch für jeden Kellerautomaten erhalten wir eine Codierung, in dem Sinne, dass wir ihn mit einer nichtdeterministischen 2-Band TM simulieren (Beispiel 3 in Kapitel 3.4) und den Code der TM verwenden. Wir werden eine TM, die auf jede Eingabe hält und die Sprache L akzeptiert, kurz Algorithmus für L nennen. 5.3.1 Das Akzeptanzproblem Erinnern wir uns an den CYK-Algorithmus (Kapitel 2.8), der für jede kontextfreie Grammatik G mit Terminalsymbolen aus {0, 1} und jedes Wort w über {0, 1} entscheidet, ob w in L(G) liegt. Daraus folgt, dass das Akzeptanzproblem für Kellerautomaten entscheidbar ist; mit anderen Worten haben wir einen Algorithmus, der für jeden Kellerautomaten M und jedes Wort w entscheidet, ob M das Wort w akzeptiert. Oder kürzer: die Sprache L(K) acc = {u; u = c(M )w für einen Kellerautomaten M und ein Wort w aus L(M )} (K) ist rekursiv. In der Tat kann ein Algorithmus, der Lacc entscheidet, wie folgt konstruiert werden: 1. Wir überprüfen, ob die Eingabe u die Form u = c(M )w, wobei M ein Kellerautomat ist, hat – vergleiche die Bemerkung in 5.1. 2. Für den gegebenen Kellerautomaten M konstruieren wir eine kontextfreie Grammatik G(M ), die die Sprache L(M ) erzeugt. 3. Der CYK-Algorithmus wird auf G(M ) und w angewendet. (K) Falls also M0 eine TM ist, die diesen Algorithmus repräsentiert, gilt Lacc = L(M0 ). Im Kontrast hierzu zeigen wir jetzt, dass das Akzeptanzproblem für Turingmaschinen, also die Frage, ob eine gegebene Turingmaschine ein gegebenes Eingabewort akzeptiert, unentscheidbar ist. Kürzer: die Sprache Lacc = {u; u = c(M )w für eine Turingmaschine M und ein Wort w aus L(M )} 5.3. WEITERE UNENTSCHEIDBARE PROBLEME 125 ist nicht rekursiv. Wir merken erst an, dass es zu jeder Turingmaschine M eine Turingmaschine M gibt, die sich von M nur darin unterscheidet, dass finale und nichtfinale Zustände ausgetauscht werden. (Genauer: wenn wir in M die finalen und nichtfinalen Zustände austauschen, erhalten wir eine TM mit mehreren finalen Zuständen, und M ist eine TM, die M simuliert, siehe Abschnitt 3.2.1) Der Übergang von M zu M lässt sich offensichtlich durch einen (kleinen) Algorithmus implementieren. Das bedeutet, dass es eine Turingmaschine M̂ gibt, die auf die Eingabe c(M ) die Ausgabe c(M ) berechnet. Es gilt w ∈ L(M) genau dann, wenn M auf die Eingabe w hält und nicht akzeptiert. Wir beweisen jetzt, dass die Annahme, dass Lacc rekursiv ist, zu einem Widerspruch führt: wenn Lacc rekursiv wäre, würde folgen, dass Lhalt rekursiv ist. In der Tat: falls Lacc von einer Turingmaschine Macc akzeptiert wird, die auf jede Eingabe hält, können wir die folgende Turingmaschine Mhalt konstruieren, die Lhalt akzeptiert und auf jede Eingabe hält: TURINGMASCHINE Mhalt u u nicht akzeptiert O EINGABE Hat u die Form u = c(M )w für eine TM M ? NEIN NEIN Akzeptiert JA / NEIN/ c(M ) wird Macc Eingabe von M̂ c(M )w? berechnet Akzeptiert / Macc Eingabe JA u nicht akzeptiert c(M )w? JA u akzeptiert u akzeptiert Diese TM akzeptiert genau die Eingaben u = c(M )w, für die gilt, dass • entweder M akzeptiert w (d.h., Macc akzeptiert c(M )w), oder • M akzeptiert w (d.h., Macc akzeptiert c(M )w). Das heißt, genau die Eingaben c(M )w, für die M auf die Eingabe w hält. Kürzer: L(Mhalt ) = Lhalt . Darüber hinaus hält Mhalt auf jede Eingabe – ein Widerspruch zu Satz 2 aus Kapitel 5.2. 5.3.2 Akzeptanz des leeren Wortes Eine noch einfachere Frage ist, ob eine TM die leere Eingabe akzeptiert. Auch diese Frage ist aber unentscheidbar, d.h., die Sprache Lε = {c(M ); M ist eine TM die ε akzeptiert} ist nicht rekursiv. Wir merken erst an, dass es für jede Turingmaschine M und jedes Wort w eine Turingmaschine Mw gibt, die das leere Wort genauso berechnet wie M das Wort w. Mw schreibt erst das Wort w = s1 . . . sn von links nach rechts auf ihr Band (mit Hilfe von n neuen Zuständen q1 , . . . , qn , wobei qn der Initialzustand von Mw ist) und dann geht sie in den Initialzustand q0 der Maschine M über und beginnt 126 KAPITEL 5. UNENTSCHEIDBARE PROBLEME die Berechnung wie M . Das bedeutet, dass zu den Übergangsregeln von M die folgenden Regeln hinzugefügt werden: (qn , #) → (qn , sn ) (qn , sn ) → (qn−1 , L) (qn−1 , #) → (qn−1 , sn−1 ) (qn−1 , sn−1 ) → (qn−2 , L) .. . (q1 , #) → (q1 , s1 ) (q1 , s1 ) → (q0 , s1 ) (Jetzt steht der Kopf im Zustand q0 am Anfang des Wortes w = s1 . . . sn .) Offensichtlich kann der Übergang von (M, w) zu Mw durch einen Algorithmus implementiert werden, d.h., es gibt eine Turingmaschine M̂, die auf die Eingabe c(M )w die Ausgabe c(Mw ) berechnet. Die Annahme, dass Lε rekursiv ist, führt zu einem Widerspruch: daraus würde folgen, dass Lacc rekursiv ist. In der Tat haben wir, falls Mε ein Algorithmus für Lε ist, den folgenden Algorithmus für Lacc : TURINGMASCHINE Macc u EINGABE / Hat u die Form u = c(M )w für eine TM M ? JA / c(Mw ) wird von M̂ berechnet. NEIN Akzeptiert / Mε Eingabe NEIN/ u nicht c(Mw )? akzeptiert JA u nicht akzeptiert u akzeptiert Es ist klar, dass Mε die Eingabe u = c(M )w genau dann akzeptiert, wenn Mw das leere Wort akzeptiert und das geschieht genau dann, wenn M das Wort w akzeptiert. Das heißt, genau dann, wenn die Eingabe u = c(M )w in Lacc liegt. Kürzer: L(Macc ) = Lacc . Außerdem hält Macc auf jede Eingabe – ein Widerspruch zu 5.3.1 5.3.3 Ist eine TM ein Algorithmus? Auch diese Frage, d.h., das Problem, ob eine gegebene TM auf jede Eingabe hält, ist unentscheidbar. Mit anderen Worten ist die Sprache Lalg = {c(M ); M ist eine TM, die auf jede Eingabe hält} nicht rekursiv. Wir merken erst an, dass es für jede Turingmaschine M eine Turingmaschine M 0 gibt, die jede Eingabe so berechnet wie M die Eingabe ε: M 0 löscht erst das Band und dann simuliert sie M . Offensichtlich kann der Übergang von M zu M 0 durch einen Algorithmus durchgeführt werden. Die Annahme, dass Lalg rekursiv ist, führt zu einem Widerspruch: daraus würde folgen, dass Lε rekursiv ist. In der Tat haben wir den folgenden Algorithmus für Lε , falls Malg ein Algorithmus für die Sprache Lalg ist: 5.3. WEITERE UNENTSCHEIDBARE PROBLEME 127 TURINGMASCHINE Mε u u akzeptiert O EINGABE JA Hat u die Form u = c(M ) für eine TM M ? JA / c(M 0 ) wird von M̂ berechnet. NEIN Akzeptiert / Malg Eingabe JA c(M 0 )? u nicht akzeptiert c(M 0 )? NEIN NEIN Akzeptiert Mu / die Eingabe u nicht akzeptiert u nicht akzeptiert Die Maschine Mε hält auf jede Eingabe u: nur im letzten Schritt müssen wir aufpassen, ob Mu auf die Eingabe c(M 0 ) hält (äquivalent: ob M 0 auf die Eingabe ε hält) – das folgt daraus, dass Malg die Eingabe c(M 0 ) akzeptiert. Und eine Eingabe u wird genau dann von Mε akzeptiert, wenn u = c(M ) für eine Turingmaschine, für die gilt: M 0 hält auf jede Eingabe und M 0 akzeptiert ε. Das ist äquivalent dazu, dass M auf ε hält und akzeptiert. Also u ∈ L(Mε ) genau dann, wenn u = c(M ) ∈ Lε . Das steht im Widerspruch zu 5.3.2 5.3.4 Satz von Rice Ist es entscheidbar, ob für eine Turingmaschine M die akzeptierte Sprache L(M ) • regulär, • kontextfrei, oder • nichtleer ist? Alle drei Antworten sind negativ. In der Tat gilt ein überraschend allgemeiner Satz in diesem Gebiet. Sei S eine beliebige Eigenschaft formaler Sprachen (z.B. regulär, kontextfrei, nicht leer, usw.) Wir fragen, ob es entscheidbar ist, dass eine TM eine Sprache mit der Eigenschaft S akzeptiert. Kürzer, ob die Sprache LS = {c(M ); M ist eine TM und L(M ) hat die Eigenschaft S} rekursiv ist. Das ist selbstverständlich der Fall, falls S trivial ist, d.h., • entweder hat jede Sprache L(M ) die Eigenschaft S, oder • keine Sprache L(M ) hat die Eigenschaft S. Die drei oben erwähnten Eigenschaften sind bestimmt nicht trivial. Der folgende Satz ergibt also die negativen Antworten: Satz 1 (Satz von Rice). Für jede nichttriviale Eigenschaft S von Sprachen ist es unentscheidbar, ob für eine Turingmaschine M die Sprache L(M ) die Eigenschaft S hat. Kürzer: die Sprache LS ist nicht rekursiv. 128 KAPITEL 5. UNENTSCHEIDBARE PROBLEME Beweis. 1. Nehmen wir erst an, dass die leere Sprache ∅ die Eigenschaft S nicht hat. Da S nicht trivial ist, gibt es eine Turingmaschine M0 , so dass gilt L(M0 ) hat die Eigenschaft S. Für jede Turingmaschine M und jedes Wort w konstruieren wir die folgende Turingmaschine M w : TURINGMASCHINE M w u JA EINGABE / Akzeptiert M0 die Eingabe u? / Akzeptiert M die Eingabe w? NEIN JA / u akzeptiert NEIN u nicht akzeptiert u nicht akzeptiert Es gilt L(M w ) = ( L(M0 ) falls M die Eingabe w akzeptiert ∅ falls M die Eingabe w nicht akzeptiert Der Übergang von (M, w) zu M w kann offensichtlich durch einen Algorithmus implementiert werden. Es gibt also eine Turingmaschine M̂ , die auf die Eingabe c(M )w die Ausgabe c(M w ) berechnet. Die Annahme, dass LS rekursiv ist, führt zu einem Widerspruch: es würde folgen, dass Lacc (5.3.1) rekursiv ist. In der Tat erhalten wir, falls MS ein Algorithmus für die Sprache LS ist, den folgenden Algorithmus für Lacc : TURINGMASCHINE Macc u u nicht akzeptiert O EINGABE NEIN Hat u die Form u = c(M )w für eine TM M ? NEIN JA / c(M w ) wird von M̂ berechnet. Akzeptiert / MS Eingabe c(M w )? JA u nicht akzeptiert u nicht akzeptiert In der Tat akzeptiert Macc genau die Wörter c(M )w, für die MS die Eingabe c(M w ) akzeptiert, d.h., für die die Sprache L(M w ) die Eigenschaft S hat. Es gilt: L(M w ) hat die Eigenschaft S ⇐⇒ M akzeptiert w, denn für L(M w ) haben wir nur zwei Möglichkeiten: L(M w ) = L(M0 ) und L(M0 ) hat die Eigenschaft S, oder L(M w ) = ∅, und ∅ hat die Eigenschaft S nicht. Also: Macc akzeptiert genau die Wörter c(M )w, die in Lacc liegen. Da Macc auf jede Eingabe hält, bekommen wir einen Widerspruch zu 5.3.1. 2. Nehmen wir an, dass die leere Sprache ∅ die Eigenschaft S hat. Sei S die komplementäre Eigenschaft (das heißt, die Negation von S), die genau die Sprachen haben, die die Eigenschaft S nicht haben. Speziell hat ∅ also nicht die Eigenschaft S, und S ist sicher nichttrivial. Aus (1) folgt, dass LS nicht rekursiv ist. Daraus folgt, dass die Sprache LS (aller Wörter, die nicht in LS liegen) nicht rekursiv ist, denn LS ist der Durchschnitt von LS und der 5.3. WEITERE UNENTSCHEIDBARE PROBLEME 129 Sprache aller Codes {c(M ); M eine TM}. Die letztere Sprache ist rekursiv, siehe Bemerkung in 5.1 Falls also auch LS rekursiv wäre, müsste LS rekursiv sein. Aus Satz ??? folgt, dass LS nicht rekursiv ist. 5.3.5 Minimierung von Turingmaschinen Wir zeigen, dass es im Gegensatz zu endlichen Automaten keinen Minimierungsalgorithmus für Turingmaschinen gibt. Für jede TM (die, wie oben, das Bandalphabet {0, 1} hat) bezeichnen wir mit fM die partielle Funktion, die M wie folgt berechnet: falls M die Eingabe n (binär) hat, und falls M hält, ist fM (n) die Zahl, die auf dem Band steht, wenn alle Blanksymbole und eventuell am Anfang stehende Nullen ignoriert werden. Ein Minimierungsalgorithmus für Turingmaschinen ist ein Algorithmus A, der jeder Turingmaschine M eine Turingmaschine A(M ) mit der minimalen Anzahl von Zuständen zuordnet, die dieselbe Funktion berechnet, fM (n) = fA(M ) (n) für alle n. Beispiel 1. Für jede Turingmaschine M , die die Identitätsfunktion berechnet, d.h., fM (n) = n für alle n ∈ erfüllt, hat die Turingmaschine A(M ) nur einen Zustand. Denn die Identitätsfunktion kann von einer TM mit einem einzigen Zustand und keiner Übergangsregel realisiert werden. Satz 2. Es gibt keinen Minimierungsalgorithmus für Turingmaschinen. Beweis. Wir merken erst an, dass es für jede Turingmaschine M und jedes Wort w möglich ist, die folgende Turingmaschine M(w) zu konstruieren TURINGMASCHINE M(w) n EINGABE / (binär) Hält M auf die NEIN / M(w) lässt n ausgeben Eingabe w in höchstens n Schritten? JA M(w) schreibt Ausgabe 0 Also simuliert M(w) die Turingmaschine M auf die Eingabe w für k ≤ n Schritte, bis M hält, und dann schreibt M(w) die Ausgabe 0; falls M in n Schritten nicht hält, schreibt M(w) die Ausgabe n. Der Übergang von M und w zu M(w) kann offensichtlich von einer Turingmaschine M̂ durchgeführt werden (M̂ ist eine einfache Modifikation der universalen TM). Also ist M̂ eine TM, die auf die Eingabe c(M )w die Ausgabe c(M(w) ) liefert. Es gilt: fM(w) (n) = n, falls M auf Eingabe w nicht hält, d.h., die Machine M(w) berechnet die Identitätsfunktion. Also gilt für jeden Minimierungsalgorithmus A, A(M(w) ) hat 1 Zustand, falls M auf w nicht hält. Umgekehrt gilt: falls M auf Eingabe w hält, ist fM(w) nicht die Identitätsfunktion. Es gilt also: M hält nicht auf Eingabe w ⇐⇒ A(M(w) ) berechnet die Identitätsfunktion. 130 KAPITEL 5. UNENTSCHEIDBARE PROBLEME Die Annahme, dass es einen Minimierungsalgorithmus A gibt, führt zu einem Widerspruch: es folgt, dass die Sprache Lhalt rekursiv-aufzählbar ist (siehe Korollar in 5.2). In der Tat akzeptiert die folgende Turingmaschine M ∗ die Sprache Lhalt : TURINGMASCHINE M ∗ u EINGABE / Hat u die Form u = c(M )w für eine TM M ? JA / c(M(w) ) wird von M̂ berechnet. / M(w) wird von A minimiert. / NEIN u nicht akzeptiert / Hat A(M(w) ) nur einen Zustand? NEIN JA / Berechnet A(M(w) ) die Identitätsfunktion? JA / u akzeptiert NEIN u nicht akzeptiert u nicht akzeptiert (Die letzte Entscheidung, ob eine TM mit nur einem Zustand die Identitätsfunktion berechnet, lässt sich bestimmt mit einem kleinen Algorithmus durchführen.) Die Maschine M ∗ hält auf jede Eingabe und akzeptiert alle Wörter u = c(M )w, wobei M(w) die Identitätsfunktion berechnet. Da fM(w) genau dann die Identitätsfunktion ist, wenn M auf die Eingabe w nicht hält, gilt M ∗ akzeptiert c(M )w ⇐⇒ M hält nicht auf w. Kürzer: L(M ∗ ) = Lhalt , ein Widerspruch. Kapitel 6 Komplexität von Algorithmen Bisher haben wir uns die Frage gestellt, ob ein Problem entscheidbar (d.h. mit Hilfe eines Algorithmus lösbar) ist. Jetzt wollen wir auch die Effizienz von Algorithmen diskutieren. Es gibt wichtige Aufgaben, wie z.B. jeden Graphen mit der kleinstmöglichen Zahl an Farben zu färben (ohne dass eine Kante gleichfarbige Knoten verbindet), für die es zwar Algorithmen gibt, aber kein effizienter Algorithmus bekannt ist. Wir führen zuerst die Klasse P aller Probleme ein, die effizient lösbar sind; z.B. das Problem, jeden Graphen, für den es möglich ist, mit zwei Farben zu färben. Effi” zient“ bedeutet: in polynomialer Zeit durchführbar. Genauer: ein Problem gehört der Klasse P an, falls es mit einem Algorithmus lösbar ist, für den es ein Polynom p(m) gibt, so dass für jede Eingabe der Größe m die Lösung in p(m) Zeiteinheiten gefunden werden kann. Es zeigt sich, dass die Klasse P nicht von dem Modell der Berechnung abhängt: es kann eine Turingmaschine, eine RAM oder eine moderne Workstation sein. (Natürlich wird für diese drei Modelle das ausgewählte Polynom p(n) ganz verschieden sein, d.h., der Grad der Effizienz“ hängt sehr von der kon” kreten Implementierung ab. Aber die prinzipielle Möglichkeit, die Zeit durch ein Polynom zu beschränken, ist implementierungsunabhängig.) Danach wird die Klasse N P aller Probleme eingeführt, für die wenigstens die Überprüfung, ob eine gegebene Datei das Problem löst, effizient ist. Z.B. das Problem, jeden Graphen, für den es möglich ist, mit drei Farben zu färben: es ist kein effizienter Algorithmus bekannt, aber die Überprüfung, ob eine vorgeschlagene Färbung wirklich drei Farben benutzt und keine Kante zwischen gleichfarbigen Knoten ergibt, ist effizient. Leider ist es bis heute nicht bekannt, ob P = N P. Aber es sind viele Probleme bekannt, die N P-vollständig“ sind - für diese gilt: wäre eines dieser ” Probleme effizient lösbar, wären es alle anderen auch, denn dann folgt P = N P. Das erwähnte Problem der Dreifärbung von Graphen ist, wie wir beweisen werden, N Pvollständig. Es scheint sehr unwahrscheinlich, dass dieses Problem effizient lösbar ist, aber falls ja, würde daraus folgen, dass viele andere wichtige Probleme (z.B. Traveling Salesman Problem) effizient lösbar wären. Dieses Kapitel hat, wie die vorigen, theoretischen Charakter; z.B. benutzt die Klasse P beliebige Polynome zur Zeiteinschränkung und das ist nicht realistisch“, falls ” das Polynom einen zu großen Exponenten hat. Dennoch hat Komplexitätstheorie wichtige praktische Aspekte. Stellen Sie sich vor, dass Ihr Chef Sie damit beauftragt hat, ein Programm zu schreiben, das überprüft, ob eine vorgeschlagene Produktspe131 132 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN zifikation realisierbar ist. Trotz einigen Wochen intensiven Versuchens ist es Ihnen nicht gelungen, das Programm zu schreiben. Was jetzt? Wenn Sie die Produktspezifikation analysieren und feststellen, dass sie sehr allgemein formuliert ist, liegt es vielleicht an der Allgemeinheit und nicht an Ihrer Unfähigkeit. Es wäre z.B. toll, wenn Sie zeigen können, dass das von Ihnen verlangte Programm eigentlich auch das Halteproblem lösen könnte – dann können Sie Ihrem Chef beweisen, dass er unlösbare Aufgaben erteilt. Das ist aber leider nicht sehr wahrscheinlich, denn das Halteproblem ist doch sehr allgemein. Also versuchen Sie zu zeigen, dass Ihr Programm eines von den hunderten N P-vollständiger Problemen lösen würde – das zeigt nicht, dass die Aufgabe prinzipiell nicht effektiv implementierbar wäre, aber dass es schon einer Schar ausgezeichneter Programmierer nicht gelungen ist, einen effizienten Algorithmus zu entwickeln. 6.1 Beispiele effizienter Algorithmen In diesem Abschnitt illustrieren wir eine genaue Analyse der Effizienz von Algorithmen an einigen wichtigen Beispielen von Graphen-Algorithmen. Ein gerichteter Graph G = (V, E), wobei V die Menge aller (n) Knoten und E die Menge aller Kanten (d.h. geordneten Paaren von Knoten) ist, wird gewöhnlich durch seine n × n-Adjazenzmatrix (aij ) repräsentiert, wobei aij = ( 1 falls (i, j) eine Kante in E ist 0 sonst Oder durch Adjazenzlisten, d.h., durch n lineare Listen, wobei die i-te Liste alle Knoten j mit (i, j) ∈ E enthält und die heads (Listenköpfe) in einem Array gespeichert werden. Beispiel: für den gerichteten Graphen 89:; ?>=< 1 O 89:; ?>=< / 2 89:; ?>=< 3 _? ? 89:; ?>=< 5 o 89:; ?>=< ?? ?? ? 4 haben wir die Adjazenzmatrix der Gesamtgröße m = n2 0 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 1 0 und die Adjazenzlisten der Gesamtgröße m = n + k 6.1. BEISPIELE EFFIZIENTER ALGORITHMEN 133 1 / 2 2 / 2 / 4 4 / 5 / 3 5 / 1 / 3 3 Beispiel 1 (Topologisches Sortieren). In Abschnitt 2.7 haben wir den folgenden Algorithmus für das topologische Sortieren eines gerichteten Graphen G = (V, E) beschrieben: 1: {(1) Initialisierung} 2: i := 0 3: W := V {W – die Menge der noch nicht bearbeiteten Knoten} 4: {(2) Rekursionsschritt} 5: while ein Knoten x ∈ W ohne Vorgänger existiert do 6: i := i + 1; 7: ord(x) = i; 8: W := W − {x} 9: Löschen des Knotens x aus dem Graphen 10: od Wie lange dauert dieser Algorithmus für einen Graphen mit n Knoten? Nehmen wir an, dass eine Eintragung in die Liste ord sowie die Modifikation der Variablen i und W eine konstante Zahl A von Zeiteinheiten dauert. Um einen Knoten x ohne Vorgänger zu finden, suchen wir in der Adjazenzmatrix eine Spalte mit lauter Nullen; das dauert Km2 Zeiteinheiten, wobei K eine Konstante ist und m die aktuelle Knotenzahl ( m = n, n − 1, . . . , 1), und die Entfernung eines Knotens dauert eine konstante Zahl L von Zeiteinheiten. Dann ist die gesamte Zahl von Zeiteinheiten für diesen Algorithmus T = 2A + n X (Km2 + 3A + L) > Cn3 für eine Konstante C. m=1 Dieser Algorithmus kann viel effizienter implementiert werden. Diesmal stellen wir den Graphen mittels Adjazenzlisten dar. Wir bezeichnen für jeden Knoten v mit IN [v] (ein Array, v = 1, . . . , n) die Zahl aller Kanten mit dem Endknoten v und wir setzen U = {v; v ∈ V und IN [v] = 0}. Algorithmus für Topologisches Sortieren Eingabe: Gerichteter Graph G = (V, E) mit n Knoten und k Kanten Ausgabe: Topologische Sortierung ord : V → {1, . . . , n} von G, falls G azyklisch ist 1: {(1) Initialisierung} 2: i := 0 {i – die letzte Zahl, die ord benutzt hat} 3: U := ∅ {U - die Menge aller Knoten v mit IN [v] = 0} 4: IN [1] := 0, . . . , IN [n] := 0 134 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN for alle Knoten v in V do for alle Knoten w mit einer Kante (v, w) in E do IN [w] := IN [w] + 1 end for end for for alle Knoten v in V do if IN [w] = 0 then U := U ∪ {v} end if end for {(2) Rekursionsschritt} while U einen Knoten v enthält do U := U − v i := i + 1 ord(v) := i for alle Knoten w mit (v, w) ∈ E do IN [w] := IN [w] − 1 if IN [w] = 0 then U := U ∪ {w} end if end for od {(3) Ausgabe} Falls n = i, ist ord eine topologische Sortierung von G. Falls n > i, ist die Ausgabe ein Code dafür, dass G nicht azyklisch ist. Korrektheit: Für jeden azyklischen Graphen G ist ord eine topologische Sortierung von G. Das folgt daraus, dass jeder azyklische Graph einen Knoten ohne Vorgänger hat. Deshalb ist U 6= ∅, solange nicht alle Knoten sortiert worden sind. Für jede Kante (v, w) von G gilt: falls in einem Durchgang der Schleife 16–26 der Wert ord(v) := i zugeordnet wird, hat vor diesem Durchgang IN [w] einen Wert ≥ 1. Deswegen wird der Wert ord(w) erst in einem Durchgang i + k, k ≥ 1, zugewiesen und es folgt ord(v) < ord(w). Zeitkomplexität: Wir wollen die Zahl der Zeiteinheiten bestimmen, die dieser Algorithmus für Graphen mit n Knoten und k Kanten braucht. Das hängt von der Implementierung ab. Wir nehmen an, dass die mengentheoretischen Operationen (insert, delete) so implementiert werden, dass sie eine konstante Zahl A von Zeiteinheiten brauchen, und auch jede Zuweisung A Zeiteinheiten benötigt. Dann dauert die Initialisierung: Zeile 2. 3. 4. 5.–9. 10.–14. Zeitkomplexität A A An n + Ak 2An (3A + 1)n + Ak Zeiteinheiten Nur die Zeilen 5.–9. benötigt eine Erklärung: bezeichnen wir mit k(v) die Zahl aller Nachfolger von v. Die Implementierung mit Adjazenzlisten erlaubt Pn eine Durchführung der Schleife 6.–8. in Zeit Ak(v). Die ganze Schleife dauert n + v=1 Ak(v) = n + Ak Zeiteinheiten. Im Rekursionsschritt dauert 20.–25. 3Ak(v) Schritte. Da die Rekursion n-mal wie- 6.1. BEISPIELE EFFIZIENTER ALGORITHMEN 135 derholt wird, benötigt sie 17. 18. 19. 20.–25. An An An 3Ak 3A(n + k) Zeiteinheiten Die Zeitkomplexität des Algorithmus ist also (6A + 1)n + 4Ak Zeiteinheiten. Bemerkung 1. Die Konstante A hängt von der konkreten Implementierung ab. Um von solchen Details in unserer Analyse absehen zu können, führen wir, für jede Funktion t(n), die Klasse O(t(n)) (gelesen: O von t(n)“) ” ein, die aus allen Funktionen f (n) besteht, die nicht schneller als t(n) wachsen (für große Werte von n): Definition. O(t(n)) bezeichnet die Klasse aller Funktionen f (n), für die es Konstanten n0 und C gibt, so dass f (n) ≤ Ct(n) für alle n ≥ n0 . Beispiel 2. 1. Der Algorithmus für topologische Sortierung hat eine lineare Zeitkomplexität O(n + k) Es gilt (6A + 1)n + 4Ak ≤ C(n + k), wobei C = 6A + 1, für alle n ≥ 0. 2. Jedes quadratische Polynom gehört zur Klasse O(n2 ). In der Tat, für f (n) = a + bn + cn2 = a b + + c n2 n2 n gilt: falls n ≥ max{a, b}, ist f (n)leq(2 + c)n2 . Es genügt also, n0 = max{a, b} und C = 2 + c zu setzen. 3. Allgemeiner enthält die Klasse O(nk ) alle Polynome des Grades k. 4. Die exponentielle Funktion 2n gehört nicht zu der Klasse O(nk ), denn lim n→∞ 2n = ∞. nk Bemerkung 2. Falls Graphen als Adjazenzmatrizen implementiert werden, benötigt jeder Algorithmus für das topologische Sortieren mindestens n2 Schritte 2 136 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN In der Tat muss jeder Algorithmus für jedes der n2 Paare (i, j) entweder aij oder aji in der Adjazenzmatrix durchsuchen. (Stellen wir uns vor, dass ein Algorithmus A weder aij noch aji durchsucht. Für den Graphen G mit n Knoten und keiner Kante ergibt A ein topologisches Sortieren. Bezeichnen wir mit G den Graphen, der genau zwei Kanten i → j und j → i enthält. Dann wird G mit dem Algorithmus A genau wie G bearbeitet, obwohl G zyklisch ist. Das ist ein Widerspruch.) Also ist auch bei dieser Implementierung die Zeitkomplexität linear in der Größe n2 der Eingabe. Beispiel 3 (2-FÄRBUNG). Wir wollen einen (ungerichteten) Graphen G mit zwei Farben, z.B. rot und blau, so färben, dass keine zwei benachbarten Knoten gleichfarbig sind. Es ist klar, dass das für Graphen, die ein Dreieck enthalten, unmöglich ist. Allgemeiner: für einen Graphen mit einem Zyklus ungerader Länge existiert keine solche Färbung. In dem Fall, dass G keine Zyklen ungerader Länge hat, läßt sich ein einfacher Algorithmus wie folgt angeben: wir wählen einen Knoten v und färben ihn rot. Alle Nachbarn von v werden blau gefärbt – da G kein Dreieck enthält, verursacht diese Färbung keine Probleme. Dann werden alle Nachbarn der zuletzt gefärbten Knoten rot gefärbt - da G kein Dreieck und keinen Zyklus aus fünf Kanten enthält, verursacht auch dies keine Probleme. So wird fortgefahren, bis die ganze Komponente von v (d.h., alle Knoten, die mit v durch einen ungerichteten Weg verbunden sind) gefärbt ist. Dann wählen wir wieder einen beliebigen, noch nicht gefärbten, Knoten, der rot gefärbt wird, usw. Wir beschreiben diesen Algorithmus formal. Die Mengen aller (schon) roter oder blauer Knoten werden mit ROT und BLAU bezeichnet, die Menge aller zuletzt gefärbten Knoten mit F . Algorithmus für 2-Färbung Eingabe: Ungerichteter Graph G = (V, E) Ausgabe: Eine 2-Färbung V = ROT ∪ BLAU , falls es eine gibt. 1: {1. Initialisierung} 2: ROT := ∅ 3: BLAU := ∅ 4: F := ∅ 5: {2. Rekursionsschritt} 6: while V 6= ∅ do 7: wähle v aus V 8: V := V − {v} 9: ROT := ROT ∪ {v} 10: F := F ∪ {v} 11: while F 6= ∅ do 12: wähle w in F 13: for alle Knoten u ∈ V mit (u, w) ∈ E do 14: if w ∈ ROT then 15: BLAU := BLAU ∪ {u} 16: else 17: ROT := ROT ∪ {u} 18: end if 19: F := F ∪ {u} 20: V := V − {u} 21: end for 22: F := F − {w} 23: od 24: od 6.1. BEISPIELE EFFIZIENTER ALGORITHMEN 25: 26: 137 {3. Ausgabe} Falls ROT oder BLAU eine Kante aus E enthalten, ist die Ausgabe ein Code dafür, dass G keine 2-Färbung hat. Falls weder ROT noch BLAU eine Kante enthält, ist dies die gesuchte 2-Färbung. Korrektheit: In jedem Schritt des Algorithmus gilt für jeden Knoten v: entweder v ∈ V oder v ∈ ROT oder v ∈ BLAU . Da am Ende V = ∅ gilt, ist also jeder Knoten entweder rot oder blau gefärbt. Falls weder ROT noch BLAU eine Kante enthält, haben wir eine 2-Färbung gefunden. Es bleibt zu zeigen, dass G Zyklen ungerader Länge hat, falls ROT eine Kante enthält (analog für BLAU). Sei v der Knoten in 7. Wir beweisen, dass jeder Knoten, der in 17. rot (oder in 15. blau) gefärbt wird, einen Weg von gerader (oder ungerader) Länge nach v hat, wobei die Länge des leeren Weges“ von v nach v gleich 0 gesetzt ” wird. Am Anfang der Schleife ab 11. ist das klar, denn der einzige roten Knoten ist v, und blaue gibt es nicht. Jeder Durchgang dieser Schleife erhält diese Eigenschaft: falls w rot ist und also einen Weg der Länge 2k nach v hat, wird jeder blau zu färbende Knoten u (für den eine Kante (u, w) gegeben ist) einen Weg der Länge 2k + 1 nach v haben. Analoges gilt, falls w blau ist. Sei (u, u0 ) eine Kante in ROT . Wir haben einen Kreis, der mit einen Weg der Länge 2k von u nach v beginnt, dann mit einem Weg der Länge 2k 0 von v nach u0 weitergeht und mit der Kante (u0 , u) endet. Dieser Kreis hat die ungerade Länge 2k + 2k 0 + 1 und enthält also einen Zyklus ungerader Länge (denn ein Kreis, der nur Zyklen von gerader Länge enthält, hat selbst gerade Länge). Analog läßt sich für eine Kante in BLAU argumentieren. Zeitkomplexität: Falls Graphen als Adjazenzlisten implementiert werden und die mengentheoretischen Operationen konstante Zeit erforden, hat dieser Algorithmus eine lineare Zeitkomplexität O(n + k) (wobei n die Zahl aller Knoten und k die Zahl aller Kanten ist). In der Tat benötigt die Initialisierung die Zeit O(1). Die Färbung einer Komponente K (die Zeilen 8.–23.), deren Zahl von Kanten k(K) ist, dauert O(k(K)), da jede Kante nur einmal durchsucht wird. Falls der Graph G genau r Komponenten hat, gilt k = k(K1 ) + · · · + k(Kr ) und die r Durchgänge der Schleife 6.–24. dauern O(n + k) Schritte. Die Überprüfung, ob ROT oder BLAU eine Kante enthalten, benötigt auch die lineare Zeit O(n + k). Insgesamt wird der Algorithmus also in O(n + k) Schritten durchgeführt. Beispiel 4 (3-FÄRBUNG). Die analoge Aufgabe, einen gegebenen Graphen mit drei Farben zu färben, ist viel schwieriger. Kein effizienter Algorithmus ist bekannt – und später werden wir Gründe dafür kennenlernen, weshalb es unwahrscheinlich ist, dass ein effizienter Algorithmus existiert. Ineffizient können wir einfach alle möglichen Färbungen ausprobieren. Das ist bestimmt ein Algorithmus – aber er braucht O(3n ) Schritte, da es 3n Färbungsmöglichkeiten gibt. Und das ist sehr aufwendig. Beispiel 5 (GERICHTETER WEG). Für zwei Knoten v und w eines gerichteten Graphen ist ein Weg der Länge d von v nach w eine Liste v = v 0 , v1 , . . . , vd = w von Knoten, so dass (vi−1 , vi ) eine Kante für i = 1, . . . , d ist. 138 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Jeder Knoten hat einen (leeren) Weg der Länge 0 zu sich selbst. Seien ein gerichteter Graph G und zwei Knoten v und w gegeben, dann entscheiden wir in linearer Zeit O(n + k), ob ein Weg von v nach w führt. Sei M die Menge aller Knoten zu denen ein Weg von v führt. Algorithmus für gerichteter Weg Eingabe: Ein gerichteter Graph G = (V, E) und zwei Knoten v und w Augabe: JA, falls ein gerichteter Weg von v nach w führt, ansonsten NEIN {Initialisierung:} M := {v} {Rekursionsschritt:} while eine Kante (x, y) mit x ∈ M und y ∈ / M existiert do M := M ∪ {y} E := E − {(x, y)} od {Ausgabe:} JA, falls w ∈ M , NEIN falls w 6∈ M . Zeitkomplexität: Falls der Graph mit Adjazenzlisten implementiert ist, dauert dieser Algorithmus O(n + k) Schritte, denn jede Liste wird höchstens einmal durchsucht. 6.2 Komplexitätsklasse P Alle Probleme, die ein Rechner mit polynomialer Zeitkomplexität lösen kann, formen die Klasse P. Genauer: ein Entscheidungsproblem gehört zu P, falls es einen Algorithmus gibt, der für jede Eingabe der Länge n in höchstens p(n) Zeiteinheiten entscheidet, ob die Antwort JA oder NEIN ist, wobei p(n) ein (gegebenes) Polynom ist. Es entsteht die Frage: welche Implementierung haben wir hier im Sinn? Die Antwort ist: die Klasse P ist von der Implementierung unabhängig. Verschiedene Implementierungen können natürlich verschiedene Zeitkomplexitäten haben (wie im Fall des TOPOLOGISCHEN SORTIERENS in 6.1 gezeigt wurde); d.h., das Polynom p(n) wird für jede Implementierung individuell gewählt werden. Aber die Existenz eines Polynomes ist unabhängig von der Implementierung. Das zeigen wir, indem wir Turingmaschinen als Implementierungsmodell nehmen und dann beweisen, dass dieselbe Klasse P auch z.B. mit RAM als Modell entsteht. Der Beweis für andere Berechnungsmodelle folgt analog. Definition. Wir sagen, dass eine deterministische TM eine Zeitkomplexität t(n) hat, wobei t(n) eine Funktion aus der Menge ist, falls die TM für jede Eingabe der Länge n in höchstens t(n) Schritten hält. Beispiel 1. Die Sprache L ⊆ {0, 1}∗ aller Wörter, die keine zwei benachbarten Einsen enthalten, kann von der folgenden TM akzeptiert werden: M bleibt solange im Initialzustand q0 , wie sie Nullen liest, also (q0 , 0) → (q0, R). Falls M eine 1 liest, geht sie in den Zustand q1 über: (q0 , 1) → (q1, R). Falls nach der 1 gleich eine 0 folgt, gehen wir zurück zum Zustand q0 , falls aber noch eine 1 gelesen wird, hält die Maschine im (nichtfinalen) Zustand q1 . Und falls das Blanksymbol gelesen wird, hält die Maschine im finalen Zustand qF . Hier ist eine vollständige Beschreibung von M : M = ({q0 , q1 , qF }, {0, 1}, δ, q0, qF ) 6.2. KOMPLEXITÄTSKLASSE P 139 wobei δ durch die folgenden Übergangsregeln bestimmt wird: (q0 , 0) → (q0 , R) (q0 , 1) → (q1 , R) (q0 , #) → (qF , #) (q1 , 0) → (q0 , R) (q1 , #) → (qF , #) Jede Eingabe der Länge n liest die TM von links nach rechts und hält spätestens bei dem Symbol # hinter dem Eingabewort, also nach höchstens n + 1 Schritten. Sie hat also die Zeitkomplexität t(n) = n + 1. Bemerkung 1. 1. Im Kapitel 3 haben wir verschiedene Varianten von TM eingeführt (zum Beispiel mit zusätzlichem Gedächtnis, mit mehreren Bändern, usw.). Die Definition der Klasse P (s.u.) ist unabhängig davon, welche der Varianten als TM gemeint ist; das beweisen wir exakt im Abschnitt 6.4. 2. Zeitkomplexität ist nicht eindeutig definiert (denn sie ist nur eine Abschätzung für die Anzahl der Berechnungsschritte). Genau genommen ist jede Funktion t0 (n) mit t0 (n) ≥ n+1 für alle n auch eine Zeitkomplexität der TM aus Beispiel 1. Beispiel 2. Die Sprache aller Palindrome (siehe Abschnitt 2.1, Beispiel 3) wird von der folgenden Turingmaschine M akzeptiert. Die Maschine M hat ein zusätzliches Gedächtnis (siehe 3.2.2) für die Symbole aus Σ und vier Zustände: q0 , Initialzustand, qR und qL (für die Bewegung nach links oder rechts des Kopfes der Turingmaschine) und qF , einen finalen Zustand. Zustand q0 : Falls # gelesen wird, hält die TM und akzeptiert. Falls ein Symbol aus Σ gelesen wird, speichert die TM es im Gedächtnis, löscht es und geht zu qR über. Zustand qR bewegt den Kopf nach rechts bis er # liest, dann bewegt sich der Kopf einen Schritt nach links. [Problem: nach dem Löschen des ersten Symbols steht die TM im Zustand qR auf einem #; daher wird ein spezielles Löschsymbol benötigt.] Falls das jetzt gelesene Symbol mit dem Gedächtnis übereinstimmt, wird es gelöscht und die TM geht zu qL über; falls nicht, hält die TM und akzeptiert nicht. [Problem: zum Löschen am rechten Rand brauchen wir einen weiteren Zustand, etwa qC .] Zustand qL bewegt den Kopf nach links bis er # liest [bzw. das neue Löschsymbol], dann bewegt er den Kopf einen Schritt nach rechts und geht zu q0 über. Wie lange dauert die Berechnung einer Eingabe der Länge n? Der Übergang q0 → qR dauert einen Schritt und der Übergang qR → qL dauert n + 2 Schritte. Es dauert also 1 + (n + 2) + n = 2n + 3 Schritte, bis wieder q0 erreicht wird. Jetzt beginnt dieselbe Berechnung mit einem Wort der Länge n − 2. Der Zustand q0 wird also in 2(n − 2) + 3 Schritten wieder erreicht. (Wir nehmen immer den schlechtesten Fall an, hier also den Fall, dass die Eingabe wirklich ein Palindrom ist.) Die gesamte Berechnungszeit beträgt höchstens t(n) = (2n + 3) + (2n − 1) + · · · + 5 + 1 Schritte. Diese Summe ist gleich n2 + 4n + 4, wie durch Induktion leicht bewiesen werden kann (?). Das bedeutet, dass unsere TM die Zeitkomplexität t(n) = n2 + 4n + 4 140 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN hat. Bemerkung 2. Wir können für die Sprache aller Palindrome eine fast doppelt so schnelle TM konstruieren, indem wir die beiden ersten Buchstaben speichern (und löschen) und sie mit den beiden letzten vergleichen (und diese dann auch löschen). Eine noch schnellere TM würde drei (oder vier usw.) Buchstaben auf einmal vergleichen. Wir können also eine fast k-mal schnellere TM für ein beliebig großes k konstruieren. Wir beobachten, dass jede dieser TM eine Zeitkomplexität hat, die von einem quadratischen Polynom repräsentiert wird. Den gleichen Beschleunigungsprozess können wir mit jeder TM machen, indem wir stets in einem Schritt k Felder gleichzeitig lesen und bearbeiten. Aus diesem Grund ist nicht die Funktion t(n) selbst interessant, nur die Geschwindigkeit des Wachs” tums“ von t(n), also die Klasse O(t(n)). Definition. Wir bezeichnen mit P die Klasse aller formalen Sprachen, die von einer TM mit polynomialer Zeitkomplexität akzeptiert werden können. Genauer: eine Sprache L gehört zur Klasse P, falls es eine Turingmaschine M und ein Polynom p(n) gibt, so dass L = L(M ) und M hält auf Eingaben der Länge n in höchstens p(n) Schritten. Bemerkung 3. Erinnern wir uns daran, dass Entscheidungsproblem ≡ formale Sprache. Genau genommen müssen wir ein Entscheidungsproblem erst codieren (z.B. binär, mit Symbolen 0 und 1). Dann bezeichnet L ⊆ {0, 1}∗ die Sprache aller Codierungen der Eingaben, auf die die Entscheidung JA ist. Weiter nehmen wir immer an, dass die Codierung von Problemen vernünftig“ ist. ” Wenn nämlich jemand freiwillig eine extrem lange Codierung der Eingabe benutzt, kann er auch ein kompliziertes Problem in linearer Zeit p(n) = n, wobei n die unvernünftige“ Codelänge ist, lösen. Die folgenden Regeln sind als vernünftig“ ” ” anzusehen: 1. Zahlen werden binär oder dezimal repräsentiert. (Nicht unär!) 2. Graphen werden durch Adjazenzmatrizen oder Adjazenzlisten dargestellt (siehe Abschnitt 6.1). 3. Mengentheoretische Operationen (Insert, Delete, Vereinigung, Durchschnitt) werden so implementiert, dass ihre Ausführung eine konstante Zahl von Zeiteinheiten dauert. Beispiel 3 (PALINDROM). Die Entscheidung, ob ein Wort ein Palindrom ist, ist ein Problem der Klasse P, denn die TM aus Beispiel 2 hat die Zeitkomplexität O(n2 ). Beispiel 4 (2-FÄRBUNG). Das Problem, ob ein Graph mit zwei Farben gefärbt werden kann, gehört zur Klasse P. In Abschnitt 6.1 haben wir dafür einen Algorithmus mit linearer Zeitkomplexität beschrieben. Es ist nicht kompliziert, den Algorithmus mit einer TM zu implementieren und zu beweisen, dass diese TM polynomiale Zeitkomplexität hat. 6.2. KOMPLEXITÄTSKLASSE P 141 Beispiel 5 (2-ERFÜLLBARKEIT und 3-ERFÜLLBARKEIT). Analog zu der Situation der 2-Färbung und 3-Färbung haben wir hier ein anderes wichtiges Beispiel der Probleme, deren leichtere Variante zu P gehört und deren schwierige (wahrscheinlich) nicht. Es handelt sich um Boolesche Formeln über den Variablen x1 , . . . , xn . Die einfachsten Formeln sind die Variablen xi selbst und ihre Negationen ¬xi - diese Formeln heißen Literale. Die komplizierteren Formeln werden mit Hilfe der üblichen logischen Operationen, z.B. Konjunktion ∧, Disjunktion ∨ und Implikation → erzeugt. Jede Disjunktion von Literalen heißt Klausel . Beispiele: x ∨ y ∨ ¬z ¬x. und Jede Boolesche Formel phi hat eine konjunktive Normalform (KNF), d.h., φ = φ1 ∧ φ2 ∧ · · · ∧ φn ist eine Konjunktion der Klauseln φ1 , . . . , φn . Z.B. hat die Formel φ = (x → y ∧ z) ∧ (¬x → ¬z) die folgende KNF: wir benutzen die Äquivalenz von a→b und ¬a ∨ b und erhalten φ = (¬x ∨ (y ∧ z)) ∧ (x ∨ ¬z) Da ¬x ∨ (y ∧ z) äquivalent zu (¬x ∨ y) ∧ (¬x ∨ z) ist (de Morgansches Gesetz), gilt φ = (¬x ∨ y) ∧ (¬x ∨ z) ∧ (x ∨ ¬z). Das ist also eine Boolesche Formel, deren Klauseln je zwei Literale enthalten. Eine Formel φ heißt erfüllbar , falls die Variablen so mit true oder false belegt werden können, dass φ den Wert true annimmt. Beispiel: die obige Formel ist erfüllbar, denn für x = true, y = true, z = true gilt φ = true. Es ist kein effizienter Algorithmus bekannt, der für jede Boolesche Formel unterscheidet, ob sie erfüllbar ist. Das Problem m-ERFÜLLBARKEIT ist: Gegeben, eine Boolesche Formel φ in konjunktiver Normalform, wobei jede Klausel m Literale enthält, ist φ erfüllbar? Wir definieren die Größe der Eingabe φ als n + k, wobei n die Anzahl aller Variablen und k die Anzahl aller Klauseln von φ ist. 2-ERFÜLLBARKEIT gehört zur Klasse P. Wir könnten hier einen effizienten Algorithmus angeben, aber einfacher ist es zu zeigen (in Abschnitt 6.3), dass es eine effiziente Reduktion dieses Problems auf ein anderes Problem der Klasse P gibt – daraus folgt dann indirekt, dass 2-ERFÜLLBARKEIT zur Klasse P gehört. 3-ERFÜLLBARKEIT ist dagegen schwierig: in Abschnitt 6.4 zeigen wir, dass dieses Problem N P-vollständig ist, also genauso schwierig wie 3-FÄRBUNG. Beispiel 6 (UNIVERSALITÄT REGULÄRER AUSDRÜCKE). Das ist ein (rares) Beispiel eines leicht zu formulierenden Problems, für das bewiesen wurde, dass es nicht effizient lösbar ist. Reguläre Ausdrücke haben wir in Kapitel 1 eingeführt: sie werden aus Buchstaben des Alphabets Σ, z.B. Σ = {a, b}, und Symbolen ∅ und mit Hilfe der Operatoren +, ·, und ∗ erzeugt. Jetzt arbeiten wir mit komprimierter Notation: statt xx . . . x (n-mal) schreiben wir x ↑ n (n binär), z.B. xxxxx = x ↑ 101 142 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Der reguläre Ausdruck (aaa + b∗ )(aaa + b∗ ) ergibt also in komprimierter Notation (a ↑ 11 + b∗ ) ↑ 10. Ein regulärer Ausdruck über dem Alphabet Σ heißt universal , falls die dadurch definierte Sprache die ganze Sprache Σ∗ ist. Z.B. ist der obige reguläre Ausdruck (über Σ = {a, b}) nicht universal, aber (a∗ ↑ 11 + b∗ ) ↑ 10 ist universal. Jeder reguläre Ausdruck über Σ ist also ein Wort über dem Alphabet Σ ∪ {∗, +, (, ), 0, 1, ↑} und die Länge dieses Wortes ist dann die Größe der Eingabe. Satz 1. Das Problem, zu entscheiden, ob ein gegebener regulärer Ausdruck in komprimierter Notation über {a, b} universal ist, gehört nicht zu P. Den Beweis kann der Leser unter 13.15 im Buch von Hopcroft und Ullman (siehe Einleitung [?]) finden. 6.3 Berechnungsprobleme und Reduzierbarkeit Die Komplexitätsklasse P wurde für Entscheidungsprobleme eingeführt. Analog können wir für Berechnungsprobleme die Klasse FP einführen, die alle in polynomialer Zeit lösbaren Probleme enthält. Beispiel 1. 2-FÄRBUNG ist das Problem, zu jedem 2-färbbaren Graphen eine 2-Färbung zu berechnen. Darunter verstehen wir, wie üblich, eine Funktion f : {0, 1}∗ → {0, 1}∗ , die jedem binären Code w = c(G) eines Graphen G einen binären Code f (w) seiner 2-Färbung zuordnet, falls G eine 2-Färbung hat. So eine Funktion kann in linearer Zeit berechnet werden, siehe Beispiel 3 in 6.1. Wir verwenden wieder TM als Berechnungsmodell. Wir sagen, dass eine TM eine Funktion f : Σ ∗ → Γ∗ (Σ, Γ zwei Alphabete) berechnet, falls die TM für jede Eingabe s1 s2 . . . sn (aus Σ∗ ) nach endlich vielen Schritten mit dem Wort f (s1 . . . sn ) (aus Γ∗ ) auf dem Band hält, siehe Abschnitt 3.5 Definition. Wir bezeichnen mit FP die Klasse aller Funktionen f : Σ∗ → Γ∗ , die von einer TM in polynomialer Zeit berechnet werden können. D.h., für die eine Turingmaschine M und ein Polynom p(n) existieren, so dass M auf jede Eingabe s1 . . . sn aus Σ∗ in höchstens p(n) Schritten hält und f (s1 . . . sn ) auf das Band schreibt. 6.3. BERECHNUNGSPROBLEME UND REDUZIERBARKEIT 143 Beispiel 2 (STARKE KOMPONENTEN). Zwei Knoten eines gerichteten Graphen G können genau dann in beiden Richtungen durch einen gerichteten Weg verbunden werden, wenn sie in einem Kreis des Graphen liegen. Wir sagen dann, dass die beiden Knoten in derselben starken Komponente liegen. Genauer: eine starke Komponente von G ist eine maximale Menge von Knoten, die durch gerichtete Wege (in beiden Richtungen) miteinander verbunden werden können. Beispiel: der folgende Graph b <•E yy EEEE y y EE yy " a • oy l l l• c l l lll lll ul / o E • d EE • e EE yyyy EE yy " |y • f hat drei starke Komponenten: {a, b, c}, {d, e} und {f }. Aufgrund des Algorithmus aus Beispiel 5 in 6.1 können wir einen trivialen Algorithmus finden, der für einen Graphen mit n Knoten und k Kanten in der Zeit O(n2 (n + k)) die starken Komponenten aufzählt: wir wählen einen Knoten v und fragen für jeden Knoten w, ob ein Weg von v zu w sowie ein Weg von w nach v führt. Das braucht O(2(n + k)) = O(n + k) Schritte für jeden Knoten w, also insgesamt O(n(n + k)) Schritte. Damit wird die starke Komponente von v in der Zeit O(n(n + k)) bestimmt. Außerdem gibt es höchstens n starke Komponenten, also ist die gesamte Komplexität O(n2 (n + k)). Es existiert ein Algorithmus, der die starken Komponenten in linearer Zeit O(n + k) berechnet. Diesen werden wir hier aber nicht vorführen. Bemerkung 1. Starke Komponenten jedes Graphen G formen einen neuen gerichteten Graphen G. Genauer, die Knoten von G sind die starken Komponenten v der Knoten v von G. Und für zwei starke Komponenten v, w von G gilt: (v, w) ist eine Kante von G genau dann, wenn v 6= w und ein gerichteter Weg von v nach w führt in G. Zum Beispiel ergibt sich aus dem obigen Graphen G der folgende Graph • {a, b, c} • {d, e} • {f } Es ist klar, dass der neue Graph G azyklisch ist (denn jeder Kreis von G kann zu einem Kreis aus G ergänzt werden, der dann mehrere starke Komponenten verbinden würde, das ist jedoch nicht möglich). Aufgrund von Beispiel 1 in 6.1 können also die starken Komponenten jedes gerichteten Graphen so sortiert werden, dass ord(v) ≤ ord(w) für jede Kante (v, w) von G. Bemerkung 2. Wir wollen verschiedene Entscheidungsprobleme bezüglich ihrer Komplexität vergleichen. Wann kann man sagen, dass ein Problem L ⊆ Σ∗ nicht schwieriger ist, als ein Problem L0 ⊆ Γ∗ ? Falls wir eine Übersetzung f haben, die alle Instanzen des ersten Problems (d.h., Wörter über Σ) in Instanzen des zweiten 144 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN (Wörter über Γ) überführt, so dass die Lösungen von L genau den Lösungen von L0 entsprechen und f selbst effizient berechenbar ist: Definition. Wir sagen, dass eine Sprache L ⊆ Σ∗ in polynomialer Zeit auf eine Sprache L0 ⊆ Γ∗ reduzierbar ist, falls es eine Funktion f : Σ∗ → Γ∗ der Klasse FP mit x ∈ L genau dann, wenn f (x) ∈ L0 (für alle x ∈ Σ∗ ) gibt. Aufpassen! Die Voraussetzung, dass die Reduktion f zur Klasse FP gehört, ist der Kern dieser Definition! Es ist nämlich trivial, eine beliebige Funktion f zu definieren, für die gilt x ∈ L genau dann, wenn f (x) ∈ L0 : man wähle zwei Wörter w ∈ L0 und w0 ∈ / L0 und setze ( w falls x ∈ L f (x) = w0 falls x ∈ /L Beispiel 3 (KANTEN-2-FÄRBBARKEIT). Wir wollen für einen gegebenen ungerichteten Graphen G wissen, ob sich seine Kanten derart blau und rot färben lassen, so dass Kanten mit gemeinsamen Knoten nie gleichfarbig sind. [Achtung: Wir haben gerade ein Entscheidungproblem formuliert; das zugehörige Berechnugsproblem besteht darin, eine legitime Kantenfärbung zu konstruieren, oder festzustellen, daß keine existiert. Insofern können wir das Entscheidungprobem auf dem Umweg über das Berechnungsproblem lösen.] Dieses Entscheidungsproblem können wir wie folgt auf das Problem von 2-Färbbarkeit (von Knoten) reduzieren: für jeden ungerichteten Graphen G = (V, E) bezeichnen wir mit Ĝ = (E, H) den dualen Graphen, dessen Knoten die Kanten von G sind, und zwei Kanten von G formen in Ĝ eine Kante (also gehören sie zu H) genau dann, wenn sie in G benachbart sind. Beispiel: 3 •??? ?? ? •2 1• 5• •4 G •?(2, 3) ??? ?? (1, 3) • • (1, 2) •(2, 4) Ĝ Es gilt: jede 2-Färbung von Ĝ ergibt eine Kanten-2-Färbung von G und umgekehrt. Folglich ist Ĝ genau dann 2-färbbar, wenn dies für G gilt. Ist diese Reduktion in polynomialer Zeit durchführbar? Das heißt, gehört die Funktion f : {0, 1}∗ → {0, 1}∗, die jedem Code wG eines Graphen G den Code f (wG ) = wĜ des dualen Graphen zuordnet, zu FP? Falls die Graphen als Adjazenzmatrizen implementiert werden, wird zu einer Matrix M die folgende Matrix f (M ) zugeordnet: die Zeilen und Spalten von f (M ) sind mit allen Paaren (i, j) markiert, wobei i ≤ j und Mij = 1. Und f (M ) hat eine 1 in der Position von Zeile (i, j) und Spalte (i0 , j 0 ) genau dann, wenn i = i0 oder j = j 0 . Das können wir in linearer Zeit O(m), wobei m die Größe der Eingabe ist (m = n2 für Graphen mit n Knoten), berechnen. Satz 1. Falls eine Sprache L0 zur Klasse P gehört, gehören zu P auch alle Sprachen, die sich in polynomialer Zeit auf L0 reduzieren lassen. Beweis. Wir haben eine Turingmaschine M0 , die L0 ⊆ Γ∗ akzeptiert, und eine polynomiale Zeitkomplexität p(n) hat. Für jede Sprache L ⊆ Σ∗ und jede Funktion f : Σ∗ → Γ∗ der Klasse FP, die x ∈ L ⇐⇒ f (x) ∈ L0 erfüllt, zeigen wir, dass 6.3. BERECHNUNGSPROBLEME UND REDUZIERBARKEIT 145 die Sprache L zu P gehört. Sei M eine Turingmaschine mit polynomialer Zeitkomplexität q(n), die f berechnet. Wir benutzen die folgende 2-Band Turingmaschine M̃ : BAND 1: Eingabeband (Simulation von M ) s1 s2 ... sn BAND 2: Simulation von M0 Auf Band 1 wird erst M simuliert, so dass die Eingabe x = s1 s2 . . . sn , nachdem M gehalten hat, das Wort f (x) auf Band 1 ergibt. Das Wort wird jetzt auf Band 2 kopiert und M0 wird simuliert. Falls M0 akzeptiert, akzeptiert auch M̃, und umgekehrt. Die Maschine M̃ akzeptiert ein Wort x ∈ Σ∗ genau dann, wenn M0 das Wort f (x) akzeptiert, d.h., genau dann, wenn f (x) ∈ L0 gilt. Das ist äquivalent zu x ∈ L. Es gilt also L = L(M̃ ). Für Eingaben der Länge n hält M nach höchstens q(n) Schritten und beschriftet höchstens q(n) Felder. In q(n) Schritten kopieren wir das Wort auf Band 2 und dann hält M0 in höchstens p(q(n)) Schritten. Die Zeitkomplexität von M̃ ist also 2q(n) + p(q(n)). Dieser Ausdruck ist ein Polynom, also gilt L(M̃) ∈ P. Beispiel 4. 2-ERFÜLLBARKEIT kann in polynomialer Zeit auf STARKE KOMPONENTEN (Beispiel 2) reduziert werden; deswegen gehört 2-ERFÜLLBARKEIT zu P. [Achtung: STARKE KOMPONENTEN ist ein Berechnungsproblem; das zugehörige Entscheidungsproblem, das in Wirklichkeit Ziel unserer Reduktion ist, fragt, ob für einen gerichteten Graphen, dessen Knotenmenge V disjunkte Vereinigung zweier isomorpher Mengen V 0 und V 00 ist, und für eine Bijektion f : V 0 → V 00 die Knoten v 0 ∈ V 0 und f (v 0 ) ∈ V 00 immer in verschiedenen starken Komponenten liegen.] Wir beschreiben die Reduktion. Für jede Formel φ in konjunktiver Normalform mit 2 Literalen je Klausel konstruieren wir einen gerichteten Graphen Gφ wie folgt: Knoten: für jede Variable x von φ hat Gφ zwei Knoten, markiert mit x und ¬x. Kanten: für jede Klausel α ∨ β von φ gibt es zwei Kanten in G: β ¬β ¬α α /• /• • • und Beispiel: für die Formel φ = (x ∨ y) ∧ (¬x ∨ z) ∧ (¬z ∨ ¬y) haben wir den Graphen ! z y _@@ ? • @@ • @@ @@ @@ @@ @ @ • • ¬z ¬x • a ¬y x• Diese Konstruktion ist eine Reduktion in polynomialer Zeit, denn es gilt 146 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN 1. φ ist erfüllbar genau dann, wenn x und ¬x in verschiedenen starken Komponenten von G liegen (für jede Variable x), und 2. die Funktion f , die jeder Formel φ den Graphen Gφ zuordnet, hat eine lineare Zeitkomplexität. Es ist klar, dass (2) gilt: falls φ eine Formel der Größe n (= Anzahl aller Variablen + Anzahl aller Klauseln) ist, benötigt die Konstruktion von Gφ die Zeit O(n). Wir beweisen (1). 1. Sei φ erfüllbar. Wir haben also eine Belegung der Variablen, so dass jede Klausel von φ den Wert true hat (d.h., für jede Klausel α ∨ β gilt α = true oder β = true). Es folgt, dass von einem true Knoten in Gφ keine Kante zu einem false Knoten führt. (Für die Kante ¬α → β gilt, falls ¬α = true, dass β = true sein muss, denn α ∨ β ist eine Klausel von φ; analoges gilt für ¬β → α.) Falls die Variable x den Wert true hat, führt in Gφ also kein Weg zu ¬x; falls x = false ist, führt kein Weg von ¬x zu x. In beiden Fällen liegen x und ¬x in verschiedenen starken Komponenten. 2. Seien x und ¬x immer in verschiedenen starken Komponenten. Wir erinnern an die obige Bemerkung 1: die starken Komponenten v der Knoten v des Graphen Gφ können so sortiert werden, dass für jede Kante v → w von G ord(v) ≤ ord(w) gilt. Wir belegen die Variablen wie folgt: x = true genau dann, wenn ord(¬x) < ord(x) (d.h., x hat genau dann den Wert true, wenn die starke Komponente von ¬x vor der starken Komponente von x liegt). Wir müssen beweisen, dass für jede Klausel α ∨ β entweder α = true oder β = true gilt (denn dann gilt φ = true). Nehmen wir an, dass α = false, d.h., ord(α) ≤ ord(¬α), dann beweisen wir β = true. Da Gφ die Kante ¬α → β enthält, gilt ord(¬α) ≤ ord(β) und da er auch die Kante ¬β → α enthält, gilt ord(¬β) ≤ ord(α). Also ord(¬β) ≤ ord(α) ≤ ord(¬α) ≤ ord(β). Damit ist bewiesen, dass ord(¬β) < ord(β) (denn die Komponenten ¬β und β sind wohl verschieden), also β = true. Konkrete Beispiele: Die Formel oben ist erfüllbar, denn die starken Komponenten des Graphen Gφ sind {x, z, ¬y} und {¬x, y, ¬z}. Die Formel (y ∨ x) ∧ (¬y ∨ z) ∧ (¬z ∨ x) ∧ (¬x ∨ ¬t) ∧ (t ∨ ¬x) ist nicht erfüllbar, denn der entsprechende Graph 6.4. ROBUSTHEIT DER KLASSE P 147 / •z jj •t x • _@vUUUU y? • j j @@ UUUU jjj UUj @@ Uj Uj UUUU jj j @ j j UUUU jjjj@ ¬x •T tj ¬y • o 6 • ¬z * • ¬t hat eine einzige starke Komponente. Notation. Für zwei Sprachen L und L0 schreiben wir L / L0 falls L auf L0 in polynomialer Zeit reduzierbar ist. (Das Zeichen / ist dem Zeichen ≤ ähnlich und deutet an, dass die Komplexität von L kleiner gleich der von L0 ist.) Satz 2. Die Relation / ist transitiv: für Sprachen Li ⊆ Σ∗i (i = 1, 2, 3) gilt L1 / L2 / L3 =⇒ L1 / L3 . Beweis. Aus L1 / L2 folgt, dass eine Funktion f1 : Σ∗1 → Σ∗2 der Klasse FP x ∈ L1 ⇐⇒ f1 (x) ∈ L2 erfüllt; aus L2 / L3 folgt, dass eine Funktion f2 : Σ∗2 → Σ∗3 der Klasse FP y ∈ L2 ⇐⇒ f2 (y) ∈ L3 erfüllt. Sei h : Σ∗1 → Σ∗3 , h(x) = f2 (f1 (x)) die Verknüpfung von f1 und f2 . Es gilt x ∈ L1 ⇐⇒ f1 (x) ∈ L2 ⇐⇒ h(x) = f2 (f1 (x)) ∈ L3 . Also bleibt nur zu zeigen, dass h(x) in der Klasse FP liegt. In der Tat: die Funktion fi (i = 1, 2) wird durch eine TM Mi in polynomialer Zeit pi (n) berechnet. Dann wird die Funktion h(x) = f2 (f1 (x)) durch die folgende TM berechnet: x / M1 f1 (x) / M2 / f2 (f1 (x)) Für Wörter x der Länge n macht M1 höchstens p1 (n) Schritte und schreibt also höchstens p1 (n) Symbole. Das Wort f1 (x) hat daher die Länge ≤ n + p1 (n). Dann dauert die Berechnung von M2 höchstens p2 (n + p1 (n)) Schritte. Insgesamt braucht die obige TM höchstens p1 (n) + p2 (n + p1 (n)) Schritte, und das ist ein Polynom – also liegt h in FP. Natürlich ist die Relation / reflexiv, aber sie ist nicht antisymmetrisch. 6.4 Robustheit der Klasse P Die Definition der Klasse P war auf dem Modell von TM aufgebaut. Sie ist aber von diesem Modell unabhängig, wie wir jetzt demonstrieren werden. Zuerst zeigen wir, dass, falls verschiedene Modifikationen von TM benutzt worden wären, die Klasse P dieselbe geblieben wäre. Die Zeitkomplexität ist für k-Band-TM genau wie oben für TM definiert. 148 6.4.1 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN TM mit zusätzlichem Gedächtnis Erinnern wir daran, dass eine TM mit zusätzlichem Gedächtnis die Möglichkeit eines Zugriffs auf ein Gedächtnis hat, in dem Symbole eines endlichen Alphabets A gespeichert werden, siehe 3.2.2. Dies ist allerdings eine normale“ TM mit der ” Zustandsmenge Q × A. Für die Definition der Klasse P ist es also unerheblich, ob wir TM oder TM mit zusätzlichem Gedächtnis als Berechnungsmodell anwenden. 6.4.2 TM mit mehrspurigem Band Auch dieses Modell ändert die Klasse P nicht, denn wie in 3.2.3 gezeigt wurde, ist eine TM mit k-spurigem Band eine normale“ TM mit dem Bandalphabet ” Σ = (Σ1 ∪ {#}) × · · · × (Σk ∪ {#}) − {(#, . . . , #)}. 6.4.3 Mehr-Band TM In 3.2.4 haben wir das Modell einer k-Band-TM eingeführt: die TM hat k Bänder mit k unabhängigen Lese- und Schreibköpfen, aber mit einer Steuereinheit, die aufgrund des gegebenen Zustandes und der k gelesenen Symbole die Aktivität der k Köpfe steuert. Wir haben in 3.2.4 bewiesen, dass jede k-Band-TM durch eine TM simuliert werden kann. Jetzt beweisen wir, dass dies in polynomialer Zeit möglich ist: Satz 1. Jede k-Band-TM mit einer Zeitkomplexität t(n) ≥ n kann durch eine 1Band-TM mit einer Zeitkomplexität O(t(n)2 ) simuliert werden. Beweis. Wir führen den Beweis für k = 2 durch, der allgemeine Fall läßt sich ganz analog durchführen. Wir gehen von der Simulation, die in Kapitel 3 (siehe 3.2.2) beschrieben wurde, aus. Jeder Berechnungsschritt der Simulation hat drei Unterabschnitte. Abschnitt 1 (der Anfang) dauert einen Schritt, Abschnitt 2 (Kopfbewegung nach rechts oder links) benötigt höchstens O(t(n)) Schritte, denn der Kopf wird unter das nächste Symbol ⇑ bewegt und in der Zeit t(n) kann die k-BandTM auf jedem Band höchstens O(t(n)) neue Felder beschreiben. Im Abschnitt 3 wird die Berechnung von Kopf i simuliert (in konstanter Zeit für i = 1, 2) und der Kopf wird zwischen die beiden Symbole ⇑ (in O(t(n)) Schritten bewegt. Jeder Simulationsdurchgang dauert also höchstens O(t(n)) Schritte. Da wir höchstens t(n) Durchgänge benötigen, hat die 1-Band-TM die Zeitkomplexität O(t(n)2 ). Korollar 1. Jede Sprache, die von einer k-Band-TM mit polynomialer Zeitkomplexität akzeptiert wird, gehört zur Klasse P. Beweis. Falls t(n) ein Polynom ist, ist auch t(n)2 ein Polynom. Bemerkung 1. Mit anderen Worten würde die Klasse P die gleiche bleiben, falls wir bei der Definition von P anstelle der TM die k-Band-TM benutzt hätten. Das gilt auch für die Klasse FP. 6.4.4 RAM In Kapitel 4 haben wir RAM als ein realistischeres Berechnungsmodell als TM eingeführt. Dann haben wir bewiesen, dass die Modelle RAM und TM die gleiche Leistung haben. Das gilt auch für die entsprechenden Klassen FP der in polynomialer Zeit berechenbaren Funktionen. Zuerst müssen wir aber erklären, was Zeitkomplexität für RAMs bedeutet. Es gibt zwei Varianten: 6.4. ROBUSTHEIT DER KLASSE P 149 Uniforme Zeitkomplexität. Hierbei gilt analog zu TM, dass jede Durchführung eines Befehls einem Schritt entspricht. Trotz der Analogie zu TM ist diese Variante nicht realistisch genug: ein Feld der RAM kann nämlich eine beliebig große Zahl enthalten. Wir können z.B. die ganze Eingabe s1 . . . sn als eine (sehr große) Zahl i codieren und i in einem Feld speichern – dann hat die Eingabe einfach die Größe 1. Deshalb hat uniforme Zeitkomplexität nur geringere theoretische Bedeutung (obwohl sie manchmal benutzt wird mit der Voraussetzung, dass die Codierung vernünftig“ durchgeführt wurde). ” Logarithmische Zeitkomplexität zählt die Anzahl aller Ziffern, die die Operanden des Befehls berechnen. Also, falls in einem Feld eine Zahl n steht, hat n die Größe dig(n) = kleinste ganze Zahl größer oder gleich log n (dig(n) ist die Zahl aller Ziffern von n.) Jeder Befehl zählt als k+1 Schritte, wobei k die Summe der Größen“ der Operanden ” ist. Z.B. der Befehl STORE i dauert 1 + dig(i) + dig(n) Schritte, wobei hR0i = n. Und STORE ∗i dauert 1 + dig(i) + dig(n) + dig(m) Schritte, wobei hR0i = n und hRii = m. Satz 2. Jede RAM mit logarithmischer Zeitkomplexität t(n) kann von einer MehrBand TM mit der Zeitkomplexität O(t(n)2 ) simuliert werden. Beweis. In Satz 1 in 4.2 haben wir gezeigt, wie man eine RAM einem Programm von p Zeilen von einer 6-Band-TM simulieren kann. Wir müssen nur beweisen, dass diese TM die Zeitkomplexität O(t(n)2 ) hat. Für jede Eingabe der Länge n dauert die Berechnung der RAM höchstens t(n) Schritte, und es werden höchstens t(n) Befehle durchgeführt. Daraus folgt, dass jedes Register eine Zahl mit O(t(n)) Ziffern enthält. Wir zeigen, dass jeder Befehl in höchstens O(t(n)) Schritten mit der TM simuliert wird – daraus folgt, dass die ganze Berechnung nur O(t(n)2 ) Schritte dauert. Es ist klar, dass auf jedem Band der TM höchstens O(t(n)) Felder beschriftet werden. Der Beweis, dass jeder Befehl in O(t(n)) Schritten simuliert wird, muß für alle möglichen Befehle einzeln durchgeführt werden. Wir nehmen zur Illustration den Fall STORE ∗i (detailliert im Beweis von Satz 1 in 4.2 beschrieben); die Zeitkomplexität der anderen Befehle läßt sich analog schätzen. Zuerst sucht der Kopf auf Band 2 die Kombination $ $ i $ j $ $. Da auf Band 2 höchstens O(t(n)) Felder beschriftet worden sind, dauert die Suche höchstens O(t(n)) Schritte. Dann schreibt die TM die Zahl j auf Band 5, dazu werden auch O(t(n)) Schritte benötigt, denn j hat O(t(n)) Ziffern. Da 3t(n) = O(t(n)), sehen wir, dass STORE ∗i in O(t(n)) Schritten simuliert wird. Korollar 2. Jede RAM mit polynomialer logarithmischer Zeitkomplexität berechnet eine Funktion der Klasse FP. Beweis. In der Tat wird eine RAM, falls sie die Zeitkomplexität t(n) hat, wobei t(n) ein Polynom ist, von einer Mehr-Band-TM mit der Zeitkomplexität O(t(n)2 ) 150 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN simuliert und diese wird wiederum von einer Turingmaschine M mit der Zeitkomplexität O(n2 + (t(n))4 ) simuliert. Dann berechnet M dieselbe Funktion wie die RAM, und da n2 + t(n)4 ein Polynom ist, folgt daraus, dass die Funktion zu FP gehört. Schlußbemerkung: Die Klasse P ist unabhängig von unserer Wahl des Berechnungsmodells: wir konnten, statt TM, eine beliebige deterministische Variante von TM nehmen, um dieselbe Klasse zu beschreiben. Auch RAM, obwohl es ein viel stärkeres Modell ist, ergibt für Zahlenfunktionen keine größere Klasse von Funktionen, die polynomiale Zeitkomplexität haben, als die Klasse FP. 6.5 Geometrische Algorithmen und reelle RAM Viele Algorithmen, speziell in der Computer-Graphik, arbeiten mit geometrischen Objekten in der Ebene oder im Raum, und für ihre Komplexität wird ein modifiziertes Berechnungsmodell benutzt: RAM, die mit reellen Zahlen arbeitet. Reelle RAM ist genau wie RAM (siehe 4.1) definiert, nur enthält jedes Register und jedes Feld des Ein- und Ausgabebandes eine reelle Zahl. Auch die Liste aller Operationen ist gleich (zum Beispiel LOAD i, LOAD ∗i, LOAD !i für eine beliebige natürliche Zahl i), aber die Operanden von ADD sind reelle Zahlen. Wie in Kapitel 4 gezeigt wurde, sind weitere Operationen (für RAM oder reelle RAM) einfach zu programmieren, zum Beispiel die Multiplikation von zwei Zahlen. Wir nehmen ferner an, dass Multiplikation und Division an einer reellen RAM so programmiert werden, dass sie in O(1) Schritten durchgeführt werden. Für die uniforme Komplexität im Fall der reellen RAM definieren wir die Größe der reellen Zahl x = n10−m als dig(n) + dig(m). Beispiel 1 (LINIE). Eingabe: Punkte a, b und r der Ebene, a 6= b Ausgabe: JA, falls r auf der Linie L(a, b), von a und b bestimmt, liegt. Falls ( )x und ( )y die x- und y-Koordinaten bezeichnen, ist die Antwort genau dann JA, wenn bx − a x rx − a x = ry − a y by − a y (im Fall ry 6= ay und by 6= ay ) oder ganz allgemein: genau wenn (rx − ax )(by − ay ) = (bx − ax )(ry − ay ). Diese Entscheidung dauert nur O(1) Schritte auf einer reellen RAM. Beispiel 2 (ÜBER DER LINIE). Eingabe: Punkte a, b und r in der Ebene mit ax 6= bx Ausgabe: JA, falls r über der Linie L(a, b) liegt. b oo o • o ooo ooo o o oo ooo o o • ooa OOO r •O • a OOOOO OOO OOO OOO b O•OO r über L(a, b), mit k > 0 r über L(a, b), mit k < 0 r • 6.5. GEOMETRISCHE ALGORITHMEN UND REELLE RAM 151 Falls die Linie L(a, b) die Gleichung y = kx + q hat, liegt r genau dann über dieser Linie, wenn ry > krx + q. Auch diese Entscheidung dauert O(1) Schritte. Beispiel 3 (DAS INNERE EINES POLYGONS). Eingabe: Ein konvexes Polygon P und ein Punkt r. Ausgabe: Entscheidung, ob r im Inneren von P liegt. Bemerkung 1. Ein Polygon P ist eine Liste von Punkten, die als die Ecken von P bezeichnet werden. Ein Polygon P = (v0 , v1 , . . . , vn−1 ) heißt simple, falls sich die Strecken L(vi , vi+1 ) (wobei i + 1 modulo n berechnet wird) nur in den erwarteten“ ” Ecken schneiden, d.h., der Durchschnitt von L(vi , vi+1 ) und L(vj , vj+1 ) mit i 6= j ist vi , falls j + 1 = i, oder vj , falls i + 1 = j, und ansonsten leer. Falls wir aus der Ebene die Strecken eines simplen Polygons P entfernen, erhalten wir zwei zusammenhängende Teile, einen gebundenen, der das Innere von P genannt wird, und einen weiteren, der als das Äußere von P bezeichnet wird. Ein simples Polygon P heißt konvex , falls sein Inneres jede Strecke enthält, deren Endpunkte es enthält. Beispiele: •H HHHH HH HH • •// // // // // // • j j / jjjj •jj Konvexes Polygon •FF FFFF FF F • •11 11 11 • RRRRR 11 R 11 • 1 • Nichtkonvexes Polygon •H }} HHHH } HH }} HH }} } • } \\ \\ \\\\\\\\\\ • • rrr rrr •G GG GG • Nichtsimples Polygon Ein konvexes Polygon wird als eine Liste v0 , v1 , . . . , vn−1 von Punkten angegeben, wobei wir annehmen, dass die Orientierung im Uhrzeigersinn erfolgt und keine zwei benachbarten Ecken auf der gleichen Linie liegen: v1 •XXXXXX w •++ v2 www w v0 • ++ • · vn−1 •F · FF F aaaaa · • • vn−2 Um unseren Algorithmus zu vereinfachen, nehmen wir zusätzlich an, dass die xKoordinaten der Punkte v0 , . . . , vn−1 voneinander verschieden sind. Algorithmus für das INNERE EINES POLYGONS 1. Wir wählen einen Punkt p im Inneren von P . 2. Die Halblinien von p zu den Ecken v0 , . . . , vn−1 teilen die Ebene in n Sektoren. Wir bestimmen den Sektor, in dem sich der gegebene Punkt r befindet, in O(log n) Schritten wie folgt. 152 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN ' ' v0 'U • UUUUUUv1 k k U k ' k •k Dp k _ _ _•;_; _ _•'k D vi+1 ;; D ;; ;eeeeee•D D • • v D a i Wir suchen also i0 = 0, . . . , n − 1, so dass r im Sektor (vi0 , p, vi0 +1 ) liegt (hier wird i0 + 1 modulo n berechnet, d.h., (n − 1) + 1 = 0). Wir wenden binäres Suchen an: falls wir, für jedes i = 0, . . . , n − 1, in konstanter Schrittzahl O(1) entscheiden, ob i0 kleiner, gleich oder größer als i ist, berechnen wir i0 in O(log n) Schritten. Falls r rechts von p liegt (rx ≥ px ) brauchen wir nur die Ecken rechts von p betrachten. Sei also vi eine solche Ecke: y y y y y v i0 y •y/ y /// r • y // e y / e e e e e y e e • y e e v y Oe e e i0 +1 •O OO OO • vi O O O OO Falls r über L(p, vi ) liegt, gilt i0 > i. Falls r unter L(p, vi ), aber über L(p, vi+1 ) liegt, gilt i0 = i . Und falls r unter L(p, vi+1 ) liegt, gilt i0 < i. Diese Entscheidung benötigt eine konstante Zahl von Schritten. Analoges gilt für a links von p (rx ≤ px ). 3. Falls der Sektor (vi , p, vi+1 ), in dem r liegt, berechnet worden ist, gilt: r liegt genau dann im Inneren des Polygons P , wenn es im Inneren des Dreiecks (vi , p, vi+1 ) liegt. Dies bestimmen wir in konstanter Zahl O(1) von Schritten. (Sei αx + βy + γ = 0 die Gleichung der Linie L(vi , vi+1 ). Dann liegt r genau dann im Inneren des Dreiecks, wenn αx + βy + γ dieselben Zeichen für die Koordinaten von r und p hat.) Zeitkomplexität Der Algorithmus wird in O(1) + O(log n) + O(1) = O(log n) Schritten durchgeführt. Beispiel 4 (KONVEXE HÜLLE). Eingabe: Punkte v1 , . . . , vn in der Ebene mit paarweise verschiedenen x-Koordinaten. Ausgabe: Konvexe Hülle, d.h., das kleinste Polygon, das alle Punkte enthält. Bemerkung 2. Jede Ecke der konvexen Hülle ist einer der gegebenen Punkte. Das kann man sich leicht am Gummiband-Modell klarmachen: stellen wir uns ein elastisches Gummiband vor, das so gestreckt wird, dass es alle gegebenen Punkte enthält, und anschließend losgelassen wird. Es formt dann die konvexe Hülle. 6.5. GEOMETRISCHE ALGORITHMEN UND REELLE RAM 153 Die Ausgabe des folgenden Algorithmus ist also eine Liste mit Punkten vi (für einige i = 1, . . . , n), die die konvexe Hülle, im Uhrzeigersinn orientiert, repräsentiert. Algorithmus für die KONVEXE HÜLLE 1. Sortieren Wir sortieren die gegebenen Punkte nach ihren x-Koordinaten. Weiter nehmen wir also an, dass vi für alle i = 1, . . . , n links von vi+1 steht. 2. Berechnung der oberen Hülle Der Punkt v1 liegt links von allen anderen Punkten und der Punkt vn liegt rechts – also sind v1 und vn bestimmt in der konvexen Hülle enthalten. Die konvexe Hülle besteht aus (a) einer Liste mit Punkten von v1 zu vn , die wir die obere Hülle nennen und (b) einer Liste mit Punkten von vn zu v1 , der unteren Hülle. In dem folgenden Beispiel v8 f f •TTTTT f f fff TTTT v4 fffffffff TTTT v12 • obere Hülle •// v6 // • // v10 // v • 14 a a a a a v va1 &a• a2 a a a a• av5 a a a a a a a a a a• a a a a a • a a a && && • && v7 untere Hülle && • && v11 nnn• v13 n •XXXXXXX nnn XXXXX n n v3 XXXXX nnnn X•n v9 ist die obere Hülle v1 , v4 , v8 , v12 , v14 und die untere Hülle ist v14 , v13 , v9 , v3 , v1 . Die Berechnung der oberen Hülle verfolgt die folgende divide-and-conquer Strategie: 2a Die Punkte v1 , . . . , vn werden in zwei ungefähr gleich große Teile aufgeteilt. Nehmen wir an, dass n gerade ist, dann arbeiten wir mit der linken Hälf” te“ v1, . . . , vn/2 und der rechten Hälfte“ vn/2+1 , . . . , vn . Für beide Hälften ” bestimmen wir rekursiv die obere Hülle. 154 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN q j0 p i0 _ _ _ _ _ _jj_•L_L _ _ _ _ _ _ _ _ _ _ _ _ _ _ j_j•_LL_ _ _ _ _ _ j j LLL . LLL . . . jj jj L .. L .. . . •jjjj . . •jjjj •** •** ** ** ** ** • • p2 • q • • 2 •)) •)) • )) )) )) )) • • ) ) • • • p s q1 • v1 = p 1 qt = v n obere Hülle für v1 , . . . , vn/2 obere Hülle für vn/2+1 , . . . , vn Wir bezeichnen die obere Hülle von v1 , . . . , vn/2 mit p1 , p2 , . . . , ps und die obere Hülle für vn/2+1 , . . . , vn mit q1 , q2 , . . . , qt . 2b Wir berechnen die obere Tangente der beiden gefundenen oberen Hüllen: das ist das Segment L(pi0 , qj0 ), so dass alle Punkte p1 , . . . , ps , q1 , . . . , qt unter ihm liegen. 2c Die obere Hülle der Punkte v1 , . . . , vn ist p1 , p2 , . . . , pi0 , qj0 , qj0 +1 , . . . , qt . 3. Berechnung der unteren Hülle Dies geschieht analog zu (2). 4. Die konvexe Hülle ergibt sich aus der oberen Hülle gefolgt von der unteren Hülle. Zeitkomplexität: Schritt (1) hat die Zeitkomplexität O(n log n). Wir zeigen jetzt, dass auch Schritt (2) diese Zeitkomplexität hat; analoges gilt für Schritt (3). Da (4) in n Zeiteinheiten geschrieben werden kann, ist damit bewiesen, dass der ganze Algorithmus die Zeitkomplexität O(n log n) hat. Wir zeigen später, dass dies optimal ist. Zeitkomplexität von Schritt (2): Sie hängt von der Zeitkomplexität von (2b) ab. Wir zeigen, dass die obere Tangente in O(log n) Schritten gefunden werden kann. Dann folgt, falls Schritt (2) in t(n) Zeiteinheiten berechnet wird, dass die Schritte (2a) - (2c) die folgende Zeitkomplexität haben: (2a) (2b) (2c) 2t( n2 ) O(log n) O(n) Zeiteinheiten Zeiteinheiten Zeiteinheiten Es gibt also Konstanten n0 und K, so dass n für alle n ≥ n0 gilt t(n) ≤ 2t( ) + K. 2 6.5. GEOMETRISCHE ALGORITHMEN UND REELLE RAM 155 Da die Gleichung t(n) = 2t( n2 ) + K · n die Lösung t(n) = K · n · log n hat, ist damit bewiesen, dass Schritt 2 die Zeitkomplexität O(n log n) hat. Wie wird die obere Tangente berechnet? Wir zeigen zuerst, wie man für jeden Punkt pi (i = 1, . . . , s) in der Zeit O(log t) die obere Tangente von pi zu den Punkten q1 , . . . , qt berechnet, also wie man den Index j(i) findet, so dass alle Punkte q1 , . . . , qs unter der Linie L(pi , qj(i) ) liegen. qq q q qq q j•: qjjqjjjj ::: q j j :: j ii•QQQQQ q•jqj :: iiii Q i i q Q q : • j(i) q •,, q •(( qj+1 , q • ,, q (( q , q (( • q' \ \ \ \ \ pi •\ (( '' •\ \ \ \ \ \ \ \ \ qj (( '' ' ( • • qj−1 • • Das können wir in der Zeit O(log t) durch binäres Suchen zwischen j = 1, . . . , t berechnen, falls wir für jedes j in konstanter Zeit O(1) bestimmen, ob j(i) größer, gleich oder kleiner als j ist. In der Tat: • falls qj−1 und qj+1 unter L(pi , qj ) liegen gilt j = j(i), • falls qj−1 über L(pi , qj ) liegt gilt j > j(i), • falls qj+1 über L(pi , qj ) liegt gilt j < j(i). Analog kann man zeigen, dass in der Zeit O(log n) die globale obere Tangente L(pi0 , qj0 ) berechnet werden kann. Hier müssen wir für jedes Paar (i, j) entscheiden, welcher der 9 Fälle (i = i0 , j = j0 oder i = i0 , j < j0 usw.) zutrifft. Jetzt bestimmen wir i0 durch binäres Suchen zwischen i = 1, . . . , s: für jedes i benötigen wir die Zeit O(log t), um j(i) zu berechnen, und dann nur konstante Zeit, um zu entscheiden, ob i0 größer, gleich oder kleiner als i ist: q j0 e e e e e e R e • R e e e RRRRR e e e •// p i0 e e e e e // e e O • l O // q• q OOO lll q l j(i) / l l q l , • l q •&& • , p i+1 q • ,, q && q , pi q && • $ q • && • $ q $$ q && $$ • • • pi−1 •$ $ • • • falls pi−1 und pi+1 unter L(pi , qj(i) ) liegen, gilt i = i0 , • falls pi−1 über L(pi , qj(i) ) liegt, gilt i < i0 , • falls pi+1 über L(pi , qj(i) ) liegt, gilt i > i0 . 156 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Daraus folgt, dass wir mit binärem Suchen i0 in der Zeit O((log t)(log s)) = O(log(t + s)) = O(log n) finden können. Es gilt j0 = j(i0 ). Bemerkung 3. Der obige Algorithmus für die KONVEXE HÜLLE ist optimal. Wir können nämlich SORTIEREN auf KONVEXE HÜLLE in linearer Zeit reduzieren – deshalb kann kein Algorithmus schneller als Ω(n log n) sein. In der Tat formen wir mit gegebenen Zahlen x1 , . . . , xn in linearer Zeit die n Punkte v1 , . . . , vn der Kurve y = x2 mit den gegebenen x-Koordinaten: y = x2 x3 x1 x4 x2 Da die Kurve y = x2 konvex ist, enthält die konvexe Hülle der Punkte v1 , . . . , vn jeden dieser Punkte. Also antwortet jeder Algorithmus A, der das Problem KONVEXE HÜLLE löst, auf die Eingabe v1 , . . . , vn mit der Ausgabe vi1 , vi2 , . . . , vin , die eine Orientierung der gegebenen Punkte im Uhrzeigersinn repräsentiert. Sei k der Index, für den vik der letzte Punkt (nach rechts) ist, dann gilt xik > xik+1 > · · · > xin > xi1 > xi2 > · · · > xik−1 Wir können k in linearer Zeit O(n) bestimmen und also in der Zeit n + t(n) + n sortieren, wobei t(n) die Zeit ist, die A benötigt, um die konvexe Hülle zu berechnen. Es gilt also t(n) = Ω(n log n). Beispiel 5 (PLANARE 3-FÄRBBARKEIT). Eingabe: Ein planarer Graph (das heißt, ein Graph, dessen Knoten Punkte der Ebene sind, und dessen Kanten Linien sind, die sich nur in den Knoten schneiden). Ausgabe: Entscheidung, ob der Graph mit drei Farben gefärbt werde kann. Bemerkung 4. 1. Wir wissen, dass für Graphen im allgemeinen 2-FÄRBBARKEIT leicht“ und 3-FÄRBBARKEIT sehr schwierig“ ist, wie genau später ” ” bewiesen wird. Es folgt, dass zum Beispiel 4-FÄRBBARKEIT auch sehr ” schwierig“ sein muß: eine triviale Reduktion 3-FÄRBBARKEIT / 4-FÄRBBARKEIT 6.5. GEOMETRISCHE ALGORITHMEN UND REELLE RAM 157 erfolgt, wenn zu dem gegebenen Graphen G ein neuer Knoten a hinzugefügt und mit allen alten Knoten verbunden wird. Der neue Graph G ist genau dann a •$*7$*7 $$ **77 $$ ** 777 $$ ** 77 •2 ** 77 222** • 22** •2 22 2 G fff• 2f • ff xyz{ ~}| Graph G 4-färbbar, wenn G 3-färbbar ist (denn a muß eine andere Farbe haben als jeder Knoten x 6= a). Und die Konstruktion von G verlangt nur lineare Zeit. 2. Für planare Graphen ist 2-FÄRBBARKEIT leicht“ (denn das gilt für alle ” Graphen) und 4-FÄRBBARKEIT noch leichter: nach dem berühmten Satz ist jeder planare Graph 4-färbbar! Um so erstaunlicher ist die folgende Reduktion, die zeigt, dass PLANARE 3-FÄRBBARKEIT mindestens so schwierig ist wie allgemeine 3-FÄRBBARKEIT: Reduktion: 3-FÄRBBARKEIT / PLANARE 3-FÄRBBARKEIT Eingabe: ein beliebiger Graph G. Den können wir immer in polynomialer Zeit in der Ebene repräsentieren (ohne zu verlangen, dass die Kanten sich nicht überschneiden). Genauer: 1. für die n Knoten von G wählen wir (beliebig) n verschiedene Punkte der Ebene und 2. die Kante (u, v) von G wird durch eine Linie von Punkt u nach v repräsentiert, so dass kein Knoten außer u, v auf der Linie liegt, und falls sich zwei Linien außer einem Knoten schneiden, liegt der Schnittpunkt auf keiner weiteren Linie des Graphen. Ein Beispiel einer solchen Repräsentation ist im Bild 6.1 gezeigt. Ausgabe: ein planarer Graph G∗ , der genau dann 3-färbbar ist, wenn G 3-färbbar ist. Für die Konstruktion des Graphen G∗ benutzen wir den Hilfsgraphen H in Abbildung 6.2. Dieser Graph ist 3-färbbar, Abbildung 6.3 zeigt drei Beispiele von Färbungen mit den Farben 1, 2, 3. Lemma 1. Jede 3-Färbung von H färbt N und S mit denselben Farben, analog für O und W . Beweis. Nehmen wir an, dass N mit 1 und S mit 2 gefärbt wird. Wie wird der Mittelpunkt M gefärbt? Farbe 1: wählt man für die vertikalen Nachbarn von M die Farben 2 (oben) und 3 (unten), dann bleibt für die horizontalen Nachbarn keine Farbe übrig (Bild (6.4a)). Färbt man dagegen beide vertikalen Nachbarn mit Farbe 3, so muß der rechte horizontale Nachbar die Farbe 2 erhalten, während der Knoten zwischen S und O die Farbe 1 erhalten muß. Dies erzwingt die Farbe 2 für den Knoten O. Aber nun kann der Knoten zwischen N und O nicht mehr gefärbt werden (Bild (6.4b)). 158 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN (6.1a) Adjazenzmatrix (6.1b) Erste Repräsentation (6.1c) Zweite Repräsentation 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 •?O?OO •?? oo• ??OOO o?o?o o?o?o?oOoOOO?O?? o ? OO? o •o • • 1 1 1 0 0 0 • •?? ??? ?? • • • • Abbildung 6.1: Zwei Repräsentationen eines (nichtplanaren) Graphen N •?? ??? ?? • • ? •??? ?? ??? ?? ?? ?O ? M W •?? •?? • • • ?? ?? ?? ?? ? ?? • •?? • ?? ?? ?? • S Abbildung 6.2: Graph H 1 •??? ? 2 3 ???3 • •?? • ? ??? ??? ? 1 2 1 •?? •?? • • • ?? ??? 2 1 ?? ? •? • • 3 ??3? 2 ? • (6.3a) 1 2 •??? ? 3 1 ???3 • •?? • ? ??? ??? ? 1 2 3 •?? •?? • • • ?? ??? 2 1 ?? ? •? • • 3 ??1? 3 ? • (6.3b) 2 3 •??? ? 2 1 ???2 • •?? • ? ??? ??? ? 1 3 2 •?? •?? • • • ?? ??? 3 1 ?? ? •? • • 2 ??1? 2 ? • (6.3c) 3 Abbildung 6.3: 3-Färbungen von H Farbe 2 entfällt aus demselben Grund. Farbe 3 - hier haben die vertikalen Nachbarn von M die Farben 2, 1 (Bild (6.4b), was für die horizontalen Nachbarn keine Farbe übrigläßt. Konstruktion von Graphen G∗ Gegeben ist ein Graph G, repräsentiert durch Punkte und Linien in der Ebene. Auf jeder Kante (u, v), die durch andere Kanten geschnitten wird (Bild 6.5a) füge neue Knoten hinzu, von u aus hinter jedem Schnittpunkt, wie in Bild 6.5b angedeutet; der letzte erhält das Label O. Für die Linien 6.5. GEOMETRISCHE ALGORITHMEN UND REELLE RAM 1 •??? 2 ?? • •?? •??? ? ? ? 1 ??? ?? • ?? •?? • • • ?? ??? ? ?? ? •?? • • ?3? ? • (6.4a) 2 1 •??? 3 ?? ? • •?? •??? ? ? 1 ??? ?? • • • ?? •? • ?? ???? 2 3 ?? ? •?? • • ?3? 1 ? • (6.4b) 2 159 1 •??? 2 ?? • •?? •??? ?? ?? ? •? 3 • ??• ?• •? ?? ?? ?? ??? ? •??? • • ?1? ? • (6.4c) 2 Abbildung 6.4: Färbungsversuche des Graphen H von u0 nach v 0 , die (u, v) schneiden, wird jeweils ein Knoten mit dem Label S hinzugefügt, von u0 aus hinter dem Schnitt mit (u, v). (6.5a) u • v • v • v • u0 (6.5b) u• u0 • • • O • S v 0 • • • u0 S v 0 O • • • • S O • v0 •?? •?? •?? ??? ??? ??? ?? ?? ?? (6.5c) ? ? ? ? ? ? •? O • ?= O • O • ?= ?? W ?? W u = W ??? ?? ?? ?? ?? ?? ? • • • Abbildung 6.5: Konstruktion von G∗ Daraufhin werden die Überschneidungen durch eine Kette von Hilfsgraphen H, verbunden an den Knoten O bzw. W , ersetzt, wie in Bild 6.5c angedeutet. Konkretes Beispiel: für den Graphen in 6.1c) haben wir erst den folgenden Graphen 160 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN • • •?? ??? ?? ?? ?? ?? ?? u • • • • S v N • W und dann den planaren Graphen G∗ v 7 • • 77 77 77 77 77 77 7 u V=V O • 11 VVVV 777 • V •1 VV 7 1 q•11VVV 11 VqVq• N q 1 VV q • q 11 qqq•q qq•q11 qq•q1VqVVV 11 qq• q 1 V q •VqVVVV1V •111 S •VVVVV1 • • W Eigenschaften von G∗ 1. G∗ ist planar. In der Tat, alle Schnittpunkte von Linien wurden durch Kopien von H überbrückt und es entstehen keine neuen. 2. Falls G∗ 3-färbbar ist, ist auch G 3-färbbar. Man benutzt dieselben Farben der Knoten wie in G∗ . Falls eine Linie (u, v) von G keinen Schnittpunkt in G aufweist, dann ist (u, v) auch eine Linie von G∗ und deswegen haben u, v verschiedene Farben. Andernfalls schneidet (u, v) andere Linien, was wie in Bild 6.5 durch H eliminiert wird. Dann hat u(= W ) dieselbe Farbe wie jeder O-Knoten von 6.5b, siehe Lemma oben. Da v und der benachbarte O-Knoten von G∗ verschiedene Farben haben, sind auch die Farben von u und v verschieden. Ganz analog verfährt man mit Linien (u0 , v 0 ), die (u, v) schneiden: u0 hat dieselbe Farbe wie S, die sich von der Farbe von v 0 unterscheiden muß (dies gilt auch, wenn eine entlang der Knoten N und S verbundene Kette von Kopien von H entlang von (u0 , v 0 ) auftritt. 3. Falls G 3-färbbar ist, ist auch G∗ 3-färbbar. Wir färben in G∗ erst die alten“ ” Knoten von G mit den Farben 1, 2, 3. Danach werden für eine G-Kante (u, v) in 6.5b alle O-Knoten mit denselben Farben wie u gefärbt. Als letztes färben wir die Knoten des angeklebten Graphen H wie folgt. Die Farbe von 0 und W ist schon gegeben, zum Beispiel Farbe 1. Die anderen Farben hängen von der Färbung des Anfangsknotens u0 = N der Linie (u0 , v 0 ) ab, deren Überbrückung H präsentiert (Bild 6.6). 6.6. KOMPLEXITÄTSKLASSE N P u0 •??? 1•??? •??? u? ? ? ? ?1 •?? •? •? • 1 ?? 1 ??11 ?? • • • (6.6a) 3• • v v0 161 u0 •??? 2•??? •??? u? ? ? ? ?1 •? •?? •? • 1 ?? 1 ??21 ?? • • • (6.6b) 3• • v v0 Abbildung 6.6: Färbung einer Kopie des Graphen H (a) Falls u0 Farbe 1 hat (siehe 6.6a), benutzen wir die Färbung von Bild 6.3a. (b) Falls u0 die Farbe 2 oder 3 hat, (siehe 6.6b), benutzen wir die Färbung von Bild 6.3b bzw. 6.3c. 4. Die Konstruktion von G∗ aus G dauert O(k 2 ) Schritte, wobei k die Zahl aller Kanten von G ist (falls G schon in der Ebene repräsentiert wird, was auch in polynomialer Zeit durchgeführt wird). In der Tat müssen wir für jede Kante höchstens k Schneidungen überbrücken, und das dauert (da eine Überbrückung in konstanter Zeit O(1) durchgeführt wird) O(k) Schritte pro Kante. 6.6 Komplexitätsklasse N P Probleme, die grundsätzlich schwieriger zu lösen sind als die der Klasse P, die sich aber trotzdem in polynomialer Zeit von einer nichtdeterministischen TM lösen lassen, formen die Komplexitätsklasse N P. Intuitiv kann man N P wie folgt erklären: falls ein Entscheidungsproblem die Eigenschaft hat, dass man in polynomialer Zeit überprüfen kann, ob eine angebotene“ Lösung wirklich die Aufgabe löst, gehört ” das Problem zu N P. Bevor wir N P formal definieren, zeigen wir diese intuitive Erklärung an einem Beispiel. Beispiel 1 (ZERLEGBARKEIT). Wir sollen entscheiden, ob für eine Zahl n (Eingabe) eine Zerlegung in ein Produkt n = pq zweier kleinerer Zahlen existiert. Obwohl das ein Problem ist, dass in der Mathematik seit tausenden von Jahren behandelt wurde, gibt es keinen effizienten Algorithmus dafür. Wir wissen also nicht, ob ZERLEGBARKEIT zu P gehört. Aber dieses Problem gehört offensichtlich zu N P: falls uns jemand Zahlen p und q nennt, können wir effizient überprüfen, ob sie eine Lösung bilden, d.h., ob das Produkt pq der Eingabe gleicht. Das letzte kann mit einer nichtdeterministischen TM wie folgt gelöst werden: Band 1 ist das Eingabeband. Auf Band 2 wird nichtdeterministisch eine Zahl p geschrieben und auf Band 3 nichtdeterministisch eine Zahl q. Die NTM multipliziert p mit q und vergleicht pq mit Band 1: falls pq auf Band 1 steht, hält die NTM und akzeptiert, falls nicht, hält sie und akzeptiert nicht. Für jede Zahl n, die zerlegbar ist, gibt es eine Berechnung, die n in linearer Zeit akzeptiert. Definition. Wir sagen, dass eine nichtdeterministische Turingmaschine M die Zeitkomplexität p(n) hat, falls es für jede Eingabe der Länge n, die M akzeptiert, eine akzeptierende Berechnung gibt, die höchstens p(n) Berechnungsschritte benötigt. Mit N P bezeichnen wir die Klasse aller Sprachen (oder Entscheidungsprobleme), die von einer NTM mit polynomialer Zeitkomplexität akzeptiert (oder gelöst) werden können. Genauer: eine Sprache L gehört zu N P, falls es eine NTM und ein Polynom p(n) gibt, so dass die NTM die Zeitkomplexität p(n) hat und L akzeptiert. 162 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Beispiel 2. 1. Jedes Problem der Klasse P gehört zu N P. 2. ZERLEGBARKEIT ist ein Problem der Klasse N P; es ist nicht bekannt, ob es zur Klasse P gehört. 3. ERFÜLLBARKEIT (siehe Beispiel 5 in 6.2) ist ein Problem der Klasse N P: für jede Boolesche Formel f (x1 , . . . , xn ) und jede potentielle Lösung“, d.h. ” jede (beliebig berechnete) Belegung aller Variablen x1 , . . . , xn , können wir effizient entscheiden, ob der Wert von f true oder false ist. Es ist einfach, eine NTM mit polynomialer Zeitkomplexität zu konstruieren, die das Problem ERFÜLLBARKEIT löst: Band 1 ist ein Eingabeband, auf dem ein Code der Formel f (x1 , . . . , xn ) gespeichert wird. Auf Band 2 erzeugt die NTM nichtdeterministisch n Werte 0 oder 1. Dann berechnet sie den Wert von f mit diesen n Variablenwerten (mit 1 = true und 0 = false). 4. TRAVELING SALESMAN PROBLEM (TSP) ist ein Problem der Klasse N P mit großer praktischer Relevanz. Die Eingabe ist eine Liste S1 , . . . , Sn von Städten und eine Matrix von Zahlen d(i, j) ≥ 0 für i, j = 1, . . . , n die die Distanz von Si zu Sj repräsentieren (oder die Kosten der Reise von Si nach Sj ). Die Aufgabe ist, zu entscheiden, ob alle Städte besucht werden können, ohne dass die gesamten Kosten eine gegebene Zahl k überschreiten. Das heißt: die Eingabe besteht aus Zahlen k und dij für i, j = 1, . . . , n. Die Lösung ist eine Rundfahrt, d.h. eine Permutation (i1 , i2 , . . . , in ) der Zahlen 1, . . . , n, so dass d(i1 , i2 ) + d(i2 , i3 ) + · · · + d(in−1 , in ) + d(in , i1 ) ≤ k. (∗) Auch für dieses Problem gibt es keinen effizienten Algorithmus. Aber das Problem gehört sicher zu N P: falls eine Permutation gegeben wird, benötigt die Überprüfung der Ungleichung (∗) nur lineare Zeit. Satz 1. Jede NTM mit der Zeitkomplexität p(n) kann von einer TM mit der Zeitkomplexität O(K p(n) ) wobei K eine Konstante ist simuliert werden. Beweis. Im Beweis des Satzes 1 in 3.4 haben wir eine Simulation einer nichtdeterministischen Turingmaschine M durch eine deterministische 3-Band Turingmaschine M gezeigt. Wir beweisen, dass M die Zeitkomplexität O(r2p(n) ) für eine Konstante r hat, falls M die Zeitkomplexität p(n) hat. Danach simulieren wir M mit einer (1-Band) TM, deren Komplexität O(n2 + (r2p(n) )2 ) ist, siehe Satz 1 in 6.4. Da (r2p(n) )2 = r4p(n) , setzen wir K = r 4 : die Funktion n2 + r4p(n) gehört zu O(K p(n) ). Sei, wie im Beweis des Satzes 1 in 3.4, eine Numerierung der Übergänge (q, s) → (qi , si ) für i = 1, . . . , r gegeben. Für jede Eingabe der Länge n brauchen wir nur die ersten p(n) Berechnungsschritte der Maschine M zu simulieren. Die Maschine M erzeugt systematisch alle Listen aus Zahlen i1 i2 . . . i k mit k ≤ p(n) (und 1 ≤ is ≤ r für s = 1, . . . , k) auf Band 2 – die Anzahl dieser Listen ist r + r2 + r3 + · · · + rp(n) ∈ O(rp(n) ). Für jede Liste wird M (in k ≤ p(n) Schritten) simuliert, also dauert die ganze Simulation einer Eingabe höchstens O(p(n)r p(n) ) Schritte. Es gilt p(n)r p(n) ∈ O(r2p(n) ). 6.7. N P-VOLLSTÄNDIGKEIT 163 Korollar 1. Jedes Problem der Klasse N P kann von einem Algorithmus mit exponentieller Zeitkomplexität K p(n) K – Konstante, p(n) – Polynom gelöst werden. 6.7 N P-Vollständigkeit Wir haben oben erwähnt, dass kein effizienter Algorithmus für Probleme wie ZERLEGBARKEIT oder TSP bekannt ist. Mit anderen Worten ist es nicht bekannt, ob diese Probleme in der Klasse P liegen. Eigentlich ist auch die folgende allgemeine Frage bisher unbeantwortet: Offenes Problem: Gilt P = N P? Trotz intensiver Bemühungen vieler Wissenschaftler und trotz vieler Nebenergebnisse zu diesem Thema ist die Antwort noch nicht bekannt. Es gibt aber Probleme, die in der Klasse N P eine besondere Stellung haben: wenn man für eines dieser Probleme feststellen würde, dass es zu P gehöre, so würde jedes Problem der Klasse N P zu P gehören – also wäre die Antwort auf die obige Frage positiv. Solche Probleme (zu denen z.B. TSP gehört) heißen N P-vollständig. Erinnern wir uns an den Begriff der Reduktion in polynomialer Zeit (6.3): Definition. Eine Sprache L heißt N P-hart, falls es für jede Sprache L0 der Klasse N P eine Reduktion auf L in polynomialer Zeit gibt, oder kürzer: L0 ∈ N P =⇒ L0 / L. Eine Sprache, die N P-hart ist und zu N P gehört, heißt N P-vollständig . Satz 1. Falls eine N P-harte Sprache in P liegt, gilt P = N P. Beweis. Sei L eine N P-harte Sprache in P. Für jede Sprache L0 in N P gibt es eine Reduktion auf L in polynomialer Zeit. Aus L ∈ P folgt also L0 ∈ P (Satz 1 in 6.3). Damit ist P = N P bewiesen. Satz 2 (Cookscher Satz.). ERFÜLLBARKEIT ist N P-vollständig. Beweis. 1. ERFÜLLBARKEIT ist ein Problem der Klasse NP: siehe Beispiel 2 Nr. 3 in Abschnitt 6.6. 2. Für jede Sprache L in N P zeigen wir, dass L auf ERFÜLLBARKEIT in polynomialer Zeit reduzierbar ist. Wir haben eine Turingmaschine M mit polynomialer Zeitkomplexität p(n), die L akzeptiert. Wir können für M , ohne Beschränkung der Allgemeinheit, das folgende annehmen: (a) Die Zustände von M sind wie folgt durchnumeriert: q0 (initial), q1 (final), q2 , . . . , qm . Der finale Zustand q1 ist ein Haltezustand. def (b) Die Bandsymbole von M sind s1 , . . . , sk und s0 = #. (c) Die Zellen des Bandes sind mit ganzen Zahlen durchnumeriert. Die Eingabe steht in den Zellen 1, . . . , n. 164 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Zelle Nr.: −2 −1 ... # # 0 1 2 # s i1 s i2 n n+1 n+2 n+3 ... s in # # # ... ⇑ q0 Initialkonfiguration (d) Die Übergänge sind mit y = 1, 2, . . . , d durchnumeriert und wie folgt in eine Tabelle geschrieben: y Übergang Nr. y 1 (qi(1) , sj(1) ) → (qi0 (1) , sj 0 (1) ) 2 (qi(2) , sj(2) ) → (qi0 (2) , sj 0 (2) ) .. .. . . d (qi(d) , sj(d) ) → (qi0 (d) , sj 0 (d) ) Hier ist sj(y) ein Bandsymbol und sj 0 (y) ist entweder L, R oder ein Bandsymbol. Bemerkung 1. In der Zeit p(n) kann die TM höchstens p(n) Felder beschriften, also genügt es, die Bandzellen Nr. −p(n), −p(n) + 1, . . . , 0, 1, . . . , p(n) zu betrachten. Die Reduktion der Sprache L auf ERFÜLLBARKEIT bedeutet, dass für jedes Wort w über Σ eine Boolesche Formel φw konstruiert wird, so dass φw ist erfüllbar ⇐⇒ w ∈ L und dass die Konstruktion in polynomialer Zeit durchgeführt wird. Die Aussage w ∈ L bedeutet, dass es eine Berechnung des Wortes w durch M gibt, die im Zustand q1 hält. Eine solche Berechnung können wir durch eine Formel φw eindeutig beschreiben, wenn wir die folgenden Booleschen Variablen einführen: NAME BEDEUTUNG: ist true belegt genau dann, wenn UMFANG qit Zur Zeit t hat M den Zustand qi . t = 0, . . . , p(n) i = 0, . . . , m krt Zur Zeit t steht der Kopf im Feld r t = 0, . . . , p(n) r = −p(n), . . . , p(n) stj,r Zur Zeit t steht im Feld r das Symbol sj t = 0, . . . , p(n) j = 0, . . . , k r = −p(n), . . . , p(n) uty Zur Zeit t wird der Übergang Nr. y durchgeführt t = 0, . . . , p(n) − 1 y = 1, . . . , d Mit Hilfe dieser Variablen können wir alle Bedingungen einer akzeptierenden Berechnung von w formal darstellen: (a) Initialisierung. Zur Zeit t = 0 ist die folgende Belegung true: q00 k10 s0i1 ,1 , . . . , s0in ,n s00,b (Initialzustand q0) (initiale Kopfposition 1) (die gegebene Eingabe w = si1 . . . sin in Feldern 1, . . . , n) für alle b = −p(n), . . . , p(n) außer b = 1, . . . , n (das Symbol s0 = # in allen Zellen des Bandes außer der Eingabe) 6.7. N P-VOLLSTÄNDIGKEIT 165 Jede von diesen Variablen formt eine Klausel von φw , also ist der Anfang von φw : (1) φw = q00 ∧ k10 ∧ n ^ p(n) s0ib ,b b=1 ∧ ^ b=−p(n) b6=1,...,n s00,b ∧ . . . (b) Akzeptanz von w. Eine weitere Klausel von φw gewährleistet, dass w zum Zeitpunkt t = 1, . . . , p(n) akzeptiert wird, d.h., der Zustand ist q1 (finaler Haltezustand). Das ist die Klausel p(n) q11 ∨ q12 ∨ · · · ∨ q1 (2) (die genau dann true ist, wenn q1t für einen Zeitpunkt t true ist). (c) Randbedingungen. Wir müssen auch sicherstellen, dass zu jedem Zeitpunkt t die TM i. ii. iii. iv. genau einen Zustand hat, in jedem Feld genau ein Symbol steht, der Kopf genau eine Position hat und genau ein Übergang (falls es sich um keine Haltekonfiguration handelt) durchgeführt wird. Z.B. verlangt (i), dass φw für jeden Zeitpunkt t = 0, 1, . . . , p(n) die folgende Klausel hat: (3) m _ i=0 t qit = q0t ∨ q1t ∨ · · · ∨ qm (also: es gibt einen Zustand zum Zeitpunkt t), sowie die Klauseln (4) qit → ¬qit0 für alle i 6= i0 (also: zwei Zustände qi und qi0 können nicht gleichzeitig vorhanden sein). Analoges gilt für (ii)–(iv). (d) Übergänge. Nehmen wir an, dass die Zeile y der Übergangstabelle die Bewegung des Kopfes nach links darstellt: ZEILE y: (qi(y) , sj(y) ) → (qi0 (y) , L) (Bewegung nach rechts oder Überschreibung des Bandsymbols werden analog behandelt). Dann müssen wir zu der Konjunktion von φw Klauseln hinzufügen, die gewährleisten, dass uty die erwartete Auswirkung zum Zeitpunkt t hat: Falls der Kopf im Feld r steht, wird er als nächstes im Feld r − 1 stehen: (5) t+1 (uty ∧ krt ) → kr−1 für alle r = −p(n) + 1, . . . , p(n). Der Zustand zum Zeitpunkt t muß qi(y) sein und der zum Zeitpunkt t + 1 muß qi0 (y) sein, also hat φw zwei Klauseln (6) t uty → qi(y) und uty → qit0 (y) Falls der Kopf im Feld r steht, muß das Symbol im Feld r gleich sj(y) sein: (7) (uty ∧ krt ) → stj(y),r für alle r = -p(n), . . . , p(n) 166 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Alle Bandsymbole bleiben unverändert: (8) (uty ∧ stj,r ) → st+1 j,r für alle j = 0, . . . , k und alle r = −p(n), . . . , p(n) − 1. Wenn alle Klauseln (5)–(8) zu φw hinzugefügt worden sind, wird der Übergang Nr. y korrekt ausgeführt. Damit ist die Konstruktion von φw vollständig. Es gilt: φw ist erfüllbar ⇐⇒ M akzeptiert die Eingabe w. In der Tat ergibt jede akzeptierende Berechnung von w eine Belegung der Variablen von φw für die alle Teile der Konjunktion true sind, also w = true: wir setzen qit = true, falls die Berechnung M zur Zeit t den Zustand qi hatte, analog mit krt und stj,r ; wir setzen uty = true, falls der Übergang Nr. y im Schritt t durchgeführt wurde. Umgekehrt beschreibt jede Belegung der Variablen von φw , für die alle Teile der Konjunktion von φw true sind, eine akzeptierende Berechnung von w. Wie viel Zeit benötigen wir, um φw zu konstruieren? Der Teil (1) braucht O(p(n)) Symbole (also O(p(n)) Zeiteinheiten), dasselbe gilt für den Teil (2). Es läßt sich leicht zeigen, dass die Randbedingungen nur O(p(n)2 ) Symbole benötigen. Der letzte Teil, der die d Übergänge repräsentiert, braucht O(p(n)) O(1) O(p(n)) O(p(n)) Symbole Symbole Symbole Symbole für für für für (5) (6) (7) und (8), und da d eine Konstante ist, brauchen wir für den letzten Teil O(p(n)) Symbole. Also reichen insgesamt O(p(n)2 ) Symbole. Es folgt, dass die Konstruktion von φw höchstens O(p(n)2 ) Schritte verlangt. Bemerkung 2. Die Idee, dass eine Sprache L genau dann zu N P gehört, wenn angebotene Lösungen in polynomialer Zeit überprüft werden können, läßt sich sich durch den Begriff Zertifikat formalisieren. Z.B. ist für 3-FÄRBUNG ein Zertifikat eines ungeordneten Graphen eine Färbung (korrekt oder nicht) seiner Knoten mit drei Farben. Wir formen die Sprache Lcheck aller Wörter wz, wobei w ein Code eines Graphen ist und z ein Code seines Zertifikates, das korrekt ist. Diese Sprache gehört der Klasse P an, denn für jeden Graphen und jede Färbung ist die Korrektheit effizient überprüfbar. Wichtig ist hier, dass die angebotenen Lösungen nicht komplizierter“ zu codieren sind als die Eingaben selbst. Genauer: für die Wörter ” wz (w – Eingabe, z - Zertifikat) nehmen wir an, dass die Länge z des Wortes z durch p(w), wobei p(n) ein Polynom ist, begrenzt werden kann: Definition. Für eine Sprache L ⊆ Σ∗ heißt eine Sprache Lcheck eine Zertifikatensprache, falls 1. Lcheck in P liegt und 2. es gibt ein Polynom p(n), so dass für jedes Wort w über Σ der Länge n gilt: w ∈ L ⇐⇒ wz ∈ Lcheck für irgendein Wort z der Länge ≤ p(n). 6.7. N P-VOLLSTÄNDIGKEIT 167 Satz 3. Eine Sprache gehört genau dann zur Klasse N P, wenn sie eine Zertifikatensprache hat. Beweis. 1. Gegeben eine Zertifikatensprache Lcheck ⊆ Γ∗ für L ⊆ Σ∗ *, wir beweisen, dass L ∈ N P. Sei M eine Turingmaschine mit polynomialer Zeitkomplexität q(n), die Lcheck akzeptiert. Dann haben wir die folgende nichtdeterministische Turingmaschine M ∗ , die L akzeptiert: Band 1 Eingabeband w1 w2 ... wn Band 2 Erzeugung von z z1 z2 ... zk Band 3 Simulation von M w1 w2 ... wn z1 für k ≤ p(n) z2 ... zk Auf Band 1 steht die Eigabe w der Länge n. Auf Band 2 wird nichtdeterministisch ein Wort z über der Länge k ≤ p(n) geschrieben. Dann werden w und danach z auf Band 3 kopiert, und die Maschine M wird simuliert; falls M hält und akzeptiert, hält auch M ∗ und akzeptiert. Es folgt also, dass M ∗ genau die Wörter w akzeptiert, für die es ein Wort z der Länge ≤ p(n) mit wz ∈ Lcheck gibt – also akzeptiert M ∗ die Sprache L. Die Erzeugung von z dauert 2k ∈ O(p(n)) Schritte und die Simulation von M dauert q(n+k) ∈ O(q(p(n))) Schritte, also hat M ∗ eine polynomiale Zeitkomplexität. 2. Für jede Sprache L ⊆ Σ∗ der Klasse N P konstruieren wir eine Zertifikatensprache. Wir haben eine nichtdeterministische Turingmaschine M mit polynomialer Zeitkomplexität p(n), die L akzeptiert. Für jedes Wort w ∈ L der Länge n gibt es eine Boolesche Formel φw der Länge O(p2 (n)), die die Berechnung von w vollständig beschreibt – siehe den obigen Beweis des Cookschen Satzes. Da φw eine Formel in KNF ist, ist sie ein Wort aus den Symbolen ∨, ∧, (, ), x0, x1, x10, . . . , xi (i ≤ p(n)2 ) wobei i binär dargestellt wird, also ein Wort über Γ = {∨, ∧, (, ), x, 0, 1}. Das Wort w hat die Länge O(p2 (n)). Genauer gibt es nur eine Konstante K, so dass für jedes Wort w ∈ L der Länge n die Berechnung von w durch eine Formel φw der Länge ≤ Kp2 (n) repräsentiert wird. Nehmen wir der Einfachheit halber an, dass Γ ∩ Σ = ∅. Dann ist die folgende Sprache Lcheck über Σ ∪ Γ eine Zertifikatensprache für L: Lcheck besteht aus allen Wörtern wφ, wobei w ein Wort über Σ (der Länge n) ist und φ eine Boolesche Formel der Länge ≤ Kp2 (n), die eine akzeptierende Berechnung von w beschreibt, ist. (a) Lcheck gehört zu P. In der Tat, für jedes Wort u der Länge m über Σ ∪ Γ überprüfen wir, i. ob u = wφ für w ∈ Σ∗ und φ ∈ Γ∗ , wobei w die Länge n und φ die Länge ≤ Kp2 (n) hat und 168 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN ii. falls ja, ob φ = φw die Formel aus dem Beweis des Cookschen Satzes ist. Das kann in linearer Zeit O(m) überprüft werden. (b) w ∈ L ⇐⇒ es gibt ein Wort wφ ∈ Lcheck, so dass φ die Länge ≤ Kp2 (n) hat, wobei n die Länge von w ist. Das folgt aus der Konstruktion von Lcheck. 6.8 Weitere N P-vollständige Probleme Satz 1. Sei L eine N P-vollständige Sprache. Dann ist jede Sprache in N P, auf die L in polynomialer Zeit reduziert werden kann, auch N P-vollständig. Beweis. Sei L0 ⊆ Γ∗ eine Sprache der Klasse N P, und sei f : Σ∗ → Γ∗ eine Reduktion von L ⊆ Σ∗ auf L0 in polynomialer Zeit. Wir beweisen, dass L0 N Pvollständig ist. Für jede Sprache L0 ⊆ (Σ0 )∗ der Klasse N P gibt es eine Reduktion g : (Σ0 )∗ → Σ∗ von L0 nach L in polynomialer Zeit. Es genügt zu zeigen, dass die zusammengesetzte Abbildung f (g(x)) von (Σ0 )∗ nach Γ∗ eine Reduktion in polynomialer Zeit von L0 nach L0 ist. Damit ist die N P-Vollständigkeit von L0 bewiesen. Für jedes Wort x über Σ gilt x ∈ L0 ⇐⇒ g(x) ∈ L ⇐⇒ f (g(x)) ∈ L0 , also müssen wir nur zeigen, dass f (g(x)) eine Funktion der Klasse FP ist. Sei M eine TM, die f berechnet und die polynomiale Zeitkomplexität p(n) hat, und sei M eine TM, die g berechnet und die polynomiale Zeitkomplexität q(n) hat. Dann haben wir eine 2-Band Maschine M ∗ , die auf Band 1 die Maschine M simuliert (in q(n) Schritten) und das Ergebnis auf Band 2 kopiert, wo sie die Maschine M simuliert (in p(q(n)) Schritten). Das Ergebnis von M ∗ auf Band 2 ist das Wort f (g(x)), das in O(p(q(n))) Schritten berechnet wurde. Beispiel 1 (3-ERFÜLLBARKEIT). Wir wissen, dass 2-ERFÜLLBARKEIT zu P gehört. Trotzdem ist 3-ERFÜLLBARKEIT, d.h., das Problem der Erfüllbarkeit für Formeln, die in KNF höchstens drei Literale je Klausel enthalten, NP-vollständig: 1. 3-ERFÜLLBARKEIT gehört zu N P – klar. 2. Für ERFÜLLBARKEIT existiert eine Reduktion in polynomialer Zeit auf 3-ERFÜLLBARKEIT: In der Tat kann jede Klausel aus vier Literalen a1 ∨ a 2 ∨ a 3 ∨ a 4 mit zwei Klauseln aus je drei Literalen (a1 ∨ a2 ∨ b) ∧ (¬b ∨ a3 ∨ a4 ) ersetzt werden. Es ist klar, dass a1 ∨ a2 ∨ a3 ∨ a4 genau dann erfüllt ist, wenn die letzte Formel mit b = true oder b = false erfüllt. Analog wird a1 ∨ a 2 ∨ a 3 ∨ a 4 ∨ a 5 mit drei Klauseln ersetzt: (a1 ∨ a2 ∨ b) ∧ (¬b ∨ a3 ∨ c) ∧ (¬c ∨ a4 ∨ a5 ) usw. Diese Übersetzung dauert lineare Zeit O(n), denn für jede Klausel der Länge n benötigen wir n − 2 Klauseln der Länge 3. 6.8. WEITERE N P-VOLLSTÄNDIGE PROBLEME 169 Beispiel 2 (3-FÄRBUNG.). Dies ist das Problem, ob ein gegebener Graph mit drei Farben gefärbt werden kann. Während 2-FÄRBUNG zu P gehört (Beispiel 3 in 6.1), zeigen wir jetzt, dass 3-FÄRBUNG N P-vollständig ist. Also gilt auch hier: falls jemand einen effizienten Algorithmus für 3-FÄRBUNG findet, beweist er P = N P! 1. 3-FÄRBUNG ist in N P. Falls eine 3-Färbung der Knoten vorgeschlagen wird, können wir in linearer Zeit entscheiden, ob sie korrekt ist. 2. 3-ERFÜLLBARKEIT läßt sich in polynomialer Zeit auf 3-FÄRBUNG reduzieren. Um den zweiten Teil zu beweisen, benutzen wir den folgenden Hilfsgraphen b • a • c • •?? • ?? ?? ? • •?? • ?? ?? ?? • d Hilfsgraph Wenn seine Knoten mit drei Farben, z.B. weiß, schwarz, blau gefärbt werden gilt: (1) Falls a, b und c schwarz sind, muß d auch schwarz sein. (Das ist leicht zu überprüfen, denn falls b und c schwarz sind, ist keiner der beiden Knoten direkt unter b und c schwarz und die Spitze des rechten Dreiecks muß also schwarz sein. Dasselbe gilt dann für das linke Dreieck.) (2) Falls a oder b oder c weiß ist, darf d weiß sein. Genauer: färben wir a, b, c so mit den drei Farben, so dass mindestens einmal weiß benutzt wird, dann läßt sich der ganze Hilfsgraph so färben, dass d weiß wird. (Das ist auch leicht zu überprüfen). Wir konstruieren jetzt für jede Boolesche Formel φ mit Klauseln aus drei Literalen einen Graphen Gφ , so dass φ ist erfüllbar ⇐⇒ Gφ ist 3-färbbar. Der Graph Gφ hat drei verschiedene Typen von Knoten. Typ 1 sind drei Knoten, die mit den drei Farben markiert werden und ein Dreieck formen: •B S •OOOO OOO OOO OOO • W 170 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Typ 2: für jede Variable x der Formel φ wird ein extra Dreieck an den Knoten B angehängt. Die beiden freien Knoten dieses Dreiecks werden mit x und ¬x markiert. Z.B. erhalten wir, falls φ nur die Variablen x, y, z hat, den folgenden Graphen: x ¬x •?? • ?? y ¬y ??•7 ??77 z ¬z • ??77•- • ??77-- ?7?- •B S •OOOO OOO OOO OOO • W Typ 3: für jede Klausel α ∨ β ∨ γ der Formel φ nehmen wir den obigen Hilfsgraphen: β • α • γ • •?? • ?? ?? ? • • •?? ?? ?? ?? • W und die vier Knoten, die mit α, β, γ, W markiert sind, werden mit den gerade markierten Knoten des Typs 2 identifiziert. Beispiel: für φ = y ∨ ¬x ∨ ¬z (1 Klausel) erhalten wir den Graphen x ¬x •OOO o• o o OOO ooo OOO y ¬y ooo OOO o o o OOO •JJJ tt• oo OOO JJ tt ooooo t ¬z OOO JJJ z tt oo OOO JJ •:: • tttotooo OOOJJJ : o OOJOJ:: ttototXoo OJOJO:J: tto o • XXXXX o XXXXXX eeeeeeeeeee• O•t oB S •WWWWWWW •ee WWWWW WWWWW •SSSS j j • WWWWW SSSS jjjj j j WWWWWSSS j WWWSWSWS jjj WSWSW jjjjj • W Wir beweisen zuerst: φ erfüllbar =⇒ Gφ ist 3-färbbar. 6.8. WEITERE N P-VOLLSTÄNDIGE PROBLEME 171 Für die gegebene Belegung der Variablen mit φ = true färben wir wie folgt: 1. S, B und W wie angedeutet (schwarz, blau, weiß), 2. Knoten des Typs 2 sind weiß, falls ihr Wert true ist, und schwarz, falls der Wert false ist, 3. in jedem der Hilfsgraphen ist mindestens einer der Knoten a, b, c weiß gefärbt, deshalb können wir eine Färbung finden, die auch d weiß färbt finden, siehe (2) oben. Umgekehrt beweisen wir: Gφ 3-färbbar =⇒ φ erfüllbar. Wir können, ohne Beschränkung der Allgemeinheit, annehmen, dass die gegebene Färbung die Knoten des Typs 1 wie angedeutet färbt. Wir setzen dann x = true ⇐⇒ der x-Knoten des Typs 2 ist weiß. Wir beweisen, dass φ = true, d.h., dass in jeder Klausel α ∨ β ∨ γ von φ eines der Literale α, β, γ true ist. Da kein Knoten des Typs 2 blau gefärbt werden kann (wegen der Kante zu B), sind sie schwarz oder weiß. Aufgrund der Eigenschaft (1) des Hilfsgraphen können nicht α, β, γ gleichzeitig schwarz sein – also ist α, β oder γ true. Es ist klar, dass für eine Formel φ der Größe n = Anzahl aller Variablen + Anzahl aller Klauseln die Konstruktion des Graphen Gφ in linearer Zeit O(n) durchführbar ist. Beispiel 3. k-FÄRBUNG ist NP-vollständig für jedes k ≥ 3. Wir können z.B. 3FÄRBUNG auf 4-FÄRBUNG in polynomialer Zeit wie folgt reduzieren: ein Graph G ist genau dann 3-färbbar, wenn der folgende Graph y•'7E7ENeuer Knoten yy ''' 7E7EE y y 7 E yy ' 7 EE yy '' 777 EEE y '' y 77 EEE yy • • • •y • • G 4-färbbar ist. Bemerkung 1. Ein Graph ist planar , falls er so in der Ebene gezeichnet werden kann, dass die Kanten sich nicht überkreuzen. Das k-Färbungsproblem für planare Graphen ist 1. trivial für k ≥ 4, denn jeder planare Graph ist 4-färbbar, aber trotzdem 2. N P-vollständig für k = 3 (vergl. Bemerkung 4 in Abschnitt 6.5). Wir erinnern daran, dass ein Hamiltonscher Kreis in einem ungerichteten Graphen ein Kreis ist, der jeden Knoten genau einmal besucht. Das Problem HAMILTONSCHER KREIS hat als Eingabe einen Graphen G und wir sollen entscheiden, ob G einen Hamiltonschen Kreis hat. 172 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Beispiel 4. (ohne Beweis) HAMILTONSCHER KREIS ist ein N P-vollständiges Problem. Beispiel 5. TSP ist N P-vollständig. Wir haben in Beispiel 2 Nr. 4 in Abschnitt 6.6 bemerkt, dass TSP zur Klasse N P gehört. Es ist also genug, eine Reduktion von HAMILTONSCHER KREIS auf TSP in polynomialer Zeit zu finden. Das ist trivial: für jeden Graphen G mit Knoten 1, . . . , n setzen wir ( 1 falls (i, j) eine Kante ist dij = 2 sonst Dann hat dieses TSP genau dann eine Lösung mit Gesamtkosten n, wenn G einen Hamiltonschen Kreis hat. Schlußbemerkung: Für hunderte von Problemen (einschließlich praktisch sehr wichtiger wir z.B. TSP oder 3-FÄRBUNBG) ist heute bekannt, dass sie N P-vollständig sind. Das Problem ZERLEGBARKEIT (Beispiel 1) ist eines der wenigen Probleme, für die nicht bekannt ist, ob sie N P-vollständig sind. Es gilt aber, falls P 6= N P, dass in N P Probleme existieren, die nicht N P-vollständig sind (ohne Beweis). 6.9 Komplexitätsklasse coN P Definition. Mit coN P bezeichnen wir die Klasse aller Sprachen L, für die gilt: die komplementäre Sprache liegt in N P: L ∈ coN P ⇐⇒ L ∈ N P Beispiel 1 (PRIMZAHL). Eingabe: Zahl n Ausgabe: JA genau dann, wenn n eine Primzahl ist. Dies ist also komplemaentär zu ZERLEGBARKEIT, deswegen PRIMZAHL ∈ coN P. Beispiel 2 (GÜLTIGKEIT). Eingabe: Boolsche Formal φ in KNF. Ausgabe: JA genau dann, wenn φ gültig ist, d.h. für jede Belegung der Variablen gilt φ = true. Dies ist ein Problem in coN P, denn eine Belegung mit φ = false ist ein Zertifikat für die komplementäre Sprache! Bemerkung 1. 1. P ⊆ coN P. In der Tat, bei einer deterministischen TM genügt es, die finalen und nichtfinalen Zustände zu vertauschen. 2. coN P ist unter Reduktion abgeschlossen: L0 ∈ coN P, L / L0 =⇒ L ∈ coN P Es gilt nämlich L / L0 : wir haben doch f : Γ∗ → Σ∗ in FP, so dass w ∈ L ⇐⇒ f (w) ∈ L0 , und dies bedeutet w ∈ L ⇐⇒ f (w) ∈ L0 . 6.9. KOMPLEXITÄTSKLASSE CON P 173 Definition. Eine Sprache L0 heißt coN P-vollständig , falls sie in coN P liegt und L ∈ coN P =⇒ L / L0 . Beispiel 3. GÜLTIGKEIT ist coN P-vollständig. in der Tat, gegeben L ∈ coN P, dann gibt es weil L ∈ N P, eine Reduktion in polynomialer Zeit von L auf ERFÜLLBARKEIT. Sei f diese Reduktion: jedem Wort w wird eine Formel f (w) zugeordnet mit w ∈ L ⇐⇒ f (w) erfüllbar. Eine Formel φ ist genau dann gültig, wenn ¬φ immer false, d.h. unerfüllbar ist. Sei jetzt g die folgende Funktion: g(w) = ¬f (w) Aus f ∈ FP folgt bestimmt g ∈ FP. Und w ∈ L ⇐⇒ w ∈ /L ⇐⇒ f (w) nicht erfüllbar ⇐⇒ g(w) gültig Offenes Problem: Gilt N P = coN P ? Die Antwort ist ja, falls GÜLTIGKEIT in N P liegt: Satz 1. Falls N P 6= coN P, endhält N P keine coN P-vollständige Sprache. Beweis. Sei L0 coN P-vollständig. Wir beweisen, dass L0 ∈ N P =⇒ L ∈ N P für alle L ∈ coN P d.h., falls L0 ∈ N P, gilt coN P ⊆ N P): Es gibt Reduktion f in polynomialer Zeit von L nach L0 (da L ∈ coN P). Gegeben eine NTM M , die L0 in polynomialer Zeit akzeptiert, die Kombination Band 1 f berechnet Band 2 M simuliert ergibt eine NTM, die L in polynomialer Zeit akzeptiert, also L ∈ N P. Und L0 ∈ N P =⇒ L ∈ coN P für alle L ∈ N P (d.h., N P ⊆ coN P): hier existiert eine Reduktion f von L auf L0 , und die obige NTM akzeptiert in polynomialer Zeit die Sprache L, das beweist L ∈ N P, also L ∈ coN P. Bemerkung 2. Für PRIMZAHL gilt auch PRIMZAHL ∈ N P, aber dies ist ein nichttriviales Ergebnis, dessen Beweis hier nicht durchgeführt wird. Die Klasse N P ∩ coN P aller Probleme, die effektives Zertifikat für Antwort JA sowie für Antwort NEIN habe, enthält also interssante Probleme. Wir wissen, dass sie P enthält. Offenes Problem Gilt P = N P ∩ coN P? 174 6.10 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Komplexität von Optimierungsproblemen Viele Probleme sind weder als Entscheidungsprobleme, noch als Berechnungsprobleme zu verstehen, sondern als Probleme, die für einen maximalen (oder minimalen) Wert eines Parameters eine Konstruktion verlangen. Solche Maximierungs- oder Minimierungsprobleme heißen Optimierungsprobleme. Beispiel 1 (MINIMALE FÄRBUNG). Eingabe: Ungerichteter Graph G Ausgabe: Eine Färbung von G mit minimaler Zahl von Farben. Gibt es eine effiziente Lösung dieses Problems? Bestimmt nicht (falls P 6= N P), denn jeder Algorithmus für MINIMALE FÄRBUNG kann natürlich 3-FÄRBUNG lösen. Für jedes Minimierungsproblem M haben wir das zugrunde liegende Entscheidungsproblem, dessen Eingabe ein Paar (x, y) ist, wobei x die Eingabe von M und y eine Zahl ist. Die Entscheidung lautet: hat P eine Lösung der Eingabe x mit einem Parameter ≤ y? Es ist klar, dass ein Minimierungsproblem, das eine effiziente Lösung hat, die Eigenschaft hat, dass das zugrunde liegende Entscheidungsproblem zu P gehört. Analoges gilt für Maximierungsprobleme. Beispiel 2 (MAXIMALES MATCHING). Eingabe: Ungerichteter Graph G Ausgabe: Eine maximale Menge von Kanten, die voneinander disjunkt sind. Dies ist ein Optimierungsproblem mit vielen praktischen Anwendungen. Der Name stammt von der Anwendung, wobei eine Gruppe von Männern und Frauen die Knotenmenge von G formen und eine Kante einen Mann x mit einer Frau y genau dann verbindet, wenn sie ein potentielles Paar formen. Die Aufgabe ist dann, die größte Menge von aktuellen Paaren zu bilden, für die kein(e) Teilnehmer(in) mehrmals auftritt. Dieser Graph ist offensichtlich 2-färbbar; oft wird das MAXIMALE MATCHING Problem nur für 2-färbbare Graphen untersucht. Es gibt einen effizienten Algorithmus, der MAXIMALES MATCHING löst. Die Grundidee ist, dass jedes Matching M durch einen erweiternden Weg verbessert werden kann. Für das gegebene Matching M heißt eine Kante des Graphen G frei , falls sie nicht in M liegt, und ein Knoten heißt frei, falls er kein Endknoten einer Kante in M ist. Definition. Für ein Matching M im Graphen G heißt ein Weg in G erweiternd , falls seine Endknoten frei sind und seine Kanten abwechselnd frei und unfrei sind. Beispiel 3. Im Graphen G x1 •/OOO • // OO O O // OOO OO / O • x2 •OOO// O/OO // O OO / O OOO x3 •OOO // ooo • OOOO o //oo ooO/ ooo O/OOO x4 • oo /// O• // // x • • 5 hat das Matching M : y1 y2 y3 y4 y5 6.10. KOMPLEXITÄT VON OPTIMIERUNGSPROBLEMEN x1 • • y1 x2 • • y2 x3 • • y3 x4 • • y4 x5 • • y5 175 den folgenden erweiternden Weg: x4 , y1 , x1 , y2 , x2 , y3 , x3 , y4 . Satz 1. Falls ein Matching M einen erweiternden Weg W hat, gibt es ein größeres Matching M 0 , das aus M dadurch ensteht, dass die freien und unfreien Kanten von W ausgetauscht werden. Beweis. M 0 ist ein Matching, denn für die inneren Knoten x des Weges W gibt es genau eine Kante in M , auf der x liegt, und die wird in M 0 mit genau einer Kante von W ausgetauscht. Für die beiden Endknoten von W (die in M frei sind) gibt es auch genau eine Kante in M 0 . Da beide Endknoten des Weges W frei sind, hat W mehr freie als unfreie Kanten, also hat M 0 mehr Kanten als M . Im obigen Beispiel erhalten wir das Matching x1 •OOO • OOO OOO O OO O• x2 •OOO OOO O O OOOOO x3 •OOO • OOOO OOO OOO x4 • • y1 y2 y3 y4 • y5 x5 • Dieses Matching hat immer noch erweiternden Wege, etwa x5 , y2 , x1 , y5 , oder auch x5 , y3 , x2 , y2 , x1 , y5 . Diese liefern die neuen Matchings x1 •/ • // // / • x2 •OOO// O/OO // O OO / O OO x3 •OOO // O• O / OO O O /O/ /O/OOO x4 • // • // // x5 • • y1 y2 y3 y4 y5 bzw. x1 •/ • // // / • x2 • // // / / x3 •OOO // • OOOO// O / O/OO // OO• x4 • // // / x5 • • y1 y2 y3 y4 y5 für die es keine erweiternden Wege mehr gibt – deshalb sind sie maximal: 176 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Satz 2. Jedes Matching, für das es keinen erweiternden Weg gibt, ist maximal. Beweis. Mit anderen Worten sollen wir für jedes Matching M zeigen, dass, falls es ein größeres Matching M ∗ gibt, M einen erweiternden Weg hat. Sei G der Graph, dessen Knoten die Knoten von G sind und dessen Kanten alle Kanten in (M − M ∗ ) ∪ (M ∗ − M ) sind, d.h. alle Kanten, die in genau einem der Matchings M und M ∗ liegen. Jeder Knoten von G liegt auf höchstens zwei Kanten. Das bedeutet, dass G eine disjunkte Vereinigung von Zyklen und (maximalen) Wegen ist. Da sich in jedem Zyklus die Kanten von M und M ∗ abwechseln, gilt: in jedem Zyklus ist die Zahl von Kanten aus M gleich der Zahl der Kanten aus M ∗ . Andererseits hat G mehr Kanten aus M ∗ als aus M , da M ∗ mehr Elemente als M enthält. Es gibt also einen maximalen Weg W in G, auf dem mehr Kanten aus M ∗ als aus M liegen. Das bedeutet, dass beide Endkanten von W in M ∗ liegen. Da der Weg W maximal ist, sind seine Endknoten frei im Matching M . Also ist W ein erweiternder Weg für M. Algorithmus für MAXIMALES MATCHING Eingabe: Ungerichteter Graph G = (V, E) Ausgabe: Maximales Matching M ⊆ E 1: Initialisierung M := ∅ 2: while ein erweiternder Weg W für M existiert do 3: M := M 0 für M 0 aus Satz 1 4: od Korrektheit: folgt aus Satz 1 und 2. Am Ende des while-Zyklus (der aufgrund von Satz 1 konvergiert) hat M keinen erweiternden Weg und ist also maximal. Zeitkomplexität: hängt natürlich von der Zeitkomplexität des Suchen des erweiternden Weges in Zeile 2 ab. Es sind Algorithmen bekannt, die für Graphen mit n Knoten und k Kanten die Zeitkomplexität O(nk) haben. Dann hat der ganze Algorithmus oben Zeitkomplexität O(nk). Beispiel 4 (MAXFLOW). Das Problem MAXIMALES MATCHING ist ein Spezialfall des MAXFLOW Problems: gegeben seien ein gerichteter Graph G und zwei Knoten s (source) und t (target), wir suchen den maximalen Fluß Kanten-disjunkter Wege von s nach t. (Die Wege dürfen also gemeinsame Knoten haben, aber keine gemeinsamen Kanten.) Auch hier wird die Lösung mit Hilfe von erweiternden Wegen berechnet. Gegeben ein Fluß H mit Wegen von s nach t, eine Kante von G heißt frei , falls sie auf keinem Weg von H liegt. Ein erweiternder Weg für H ist eine Liste s = v0 , v1 , . . . , vn−1 , vn = t von Knoten von G, so dass für jedes i = 1, . . . , n gilt • entweder ist (vi−1 , vi ) eine freie Kante von G, oder • (vi , vi−1 ) ist eine unfreie Kante von G. Wir erweitern H, indem alle freien Kanten (vi−1 , vi ) unfrei werden und alle unfreien Kanten (vi , vi−1 ) frei werden. Beispiel: Sei G der Graph und H der mit dickeren Linien gekennzeichneter Fluß wie folgt: 6.10. KOMPLEXITÄT VON OPTIMIERUNGSPROBLEMEN 177 x aaaaa0B x0 •?a?? •G BB ??? 0 BBB y ??y]]]]]BB ].•> t /B s • •BB • ?? B || ?? B | ?? BB || ?]] ]]] B || ]• .| • z z0 Der folgende erweiternde Weg s, y, z 0 , z, x0 , x, y 0 , t führt zum folgenden Fluß: x x0 /C FC •?DD • D C y DDDD y 0 CCCC D!]]]]] C! ]• . /BB • s • ?? • z= t B z ?? B z ?? BBB zzz ? Bzz / • • z z0 Auch für MAXFLOW gibt es einen Algorithmus, der aufrund erweiternder Wege in der Zeit O(nk) das Problem löst. Um das Konzept eines Optimierungsproblems zu formalisieren, nehmen wir an, dass die Eingabe sowie potentielle Lösungen in demselben Alphabet Σ codiert werden. Z.B. nehmen wir für MINIMALE FÄRBUNG an, dass die Eingabe G binär (z.B. als Adjazenzmatrix) codiert wird, also über Σ = {0, 1}. Jede Färbung mit k Farben 1, 2, . . . , k kann auch über Σ codiert werden, z.B. als das Wort 0i1 10i2 1 . . . 10in 1, wobei der Knoten 1 mit der Farbe i1 gefärbt wird, der Knoten 2 mit der Farbe i2 , usw. Wir haben eine Relation L auf der Menge Σ∗ aller Wörter, wobei vLw bedeutet, dass die Instanz v des Problems durch w gelöst wird. D.h., dass v einen Graphen G codiert, w eine Färbung codiert und diese Färbung für G korrekt ist. Schließlich haben wir einen Parameter c(v, w), den wir optimieren wollen, und der von der Eingabe v und der Lösung w abhängen kann. Wir betrachten also eine Funktion c:L→ Für MINIMALE FÄRBUNG ist c(v, w) = Anzahl der in w verwendeten Farben. Allgemein: Definition. bei 1. Ein Optimierungsproblem ist ein 5-Tupel (Σ, E, A, L, c), wo- Σ ein Alphabet ist (in dem Eingaben und Lösungen codiert werden), E eine Sprache über Σ ist (aller möglichen Eingaben), A eine Sprache über Σ ist (aller möglichen Lösungen oder Ausgaben) 178 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN L ⊆ E × A ist eine Relation auf der Menge Σ∗ (insbesondere folgt aus vLw sofort v ∈ E und w ∈ A) und c eine Funktion (Kostenfunktion) ist, die jedem Paar (v, w) ∈ L die Kosten c(v, w) ∈ N der Lösung w zur Eingabe v zuordnet. 2. Eine Turingmaschine löst das Minimierungsproblem (Maximierungsproblem) (Σ, E, A, L, c), falls sie für jede Eingabe v ∈ E mit einer Ausgabe w ∈ A hält, für die gilt (a) vLw und (b) c(v, w) ≤ c(v, w 0 ) (c(v, w) ≥ c(v, w 0 )) für alle w0 ∈ A mit vLw0 . Die Relation L kann auch mit ihrer charakteristischen Funktion χL : E × A → {true, false} identifiziert werden. Beispiel: die TM, die den oberen Algorithmus für MAXIMALES MATCHING implementiert, ist eine Lösung des Problems. Wie erwähnt, hat diese TM eine polynomiale Zeitkomplexität. Deswegen gehört MAXIMALES MATCHING zur folgenden Klasse: Definition. Die Klasse PO besteht aus allen Optimierungsproblemen (das heißt, allen Minimierungs- und Maximierungsproblemen) (Σ, E, A, L, c), für die gilt: 1. E und A sind Sprachen der Klasse P (d.h., wir haben eine effiziente Prozedur, die entscheidet, ob ein Wort eine Ein- oder Ausgabe codiert) 2. es gibt ein Polynom p(x), so daß jedes Paar (u, v) ∈ L der Bedingung |v| ≤ p(|u|) genügt (d.h., zu einer Eingabe kann es nur “kurze” Lösungen geben); 3. χL : E × A → {true, false} ist eine Funktion der Klasse FP 4. c ist eine Funktion der Klasse FP und 5. es gibt eine TM mit polynomialer Zeitkomplexität, die das Optimierungsproblem löst. Beispiel 5. MINMALE FÄRBUNG gehört nicht zu PO, falls P 6= N P, denn 3-FÄRBUNG ist ein N P-vollständiges Problem. Beispiel 6. MAXIMALES MATCHING gehört zu PO. In der Tat 1. gibt es Algorithmen, die in linearer Zeit entscheiden, ob ein binäres Wort einen Graphen oder ein Matching codiert 2. ist jedes Matching als Teilmenge der Kantenmenge linear in der Eingabegröße beschränkt 3. gibt es einen Algorithmus, der in linearer Zeit entscheidet, ob eine Menge von Knoten ein Matching ist 4. kann die Bewertung der Zahl c(w, v) aller Knoten des Matching v in linearer Zeit durchgeführt werden und 5. haben wir einen effizienten Algorithmus für die Lösung von MAXIMALES MATCHING oben gezeigt. 6.11. APPROXIMATION VON OPTIMIERUNGSPROBLEMEN 179 Bemerkung 1. Für jedes Minimierungsproblem (Σ, E, A, L, c) definieren wir das zugrunde liegende Entscheidungsproblem: gegeben ein Paar (w, n) mit w ∈ E und n ∈ , gibt es eine Lösung v ∈ A, so dass (∗) vLw und c(w, v) ≤ n? Für jedes Minimierungsproblem der Klasse PO gehört das zugrunde liegende Entscheidungsproblem zur Klasse P. In der Tat können wir für jede Eingabe (w, n) in polynomialer Zeit die entsprechende minimale Lösung v finden, berechnen wir in polynomialer Zeit den Wert c(w, v) und schließlich entscheiden wir in der Zeit O(log n), ob dieser Wert kleiner gleich n ist. Analog für Maximierungsprobleme: hier wird die Ungleichung von (∗) umgedreht. Umgekehrt gilt also: falls P 6= N P, enthält PO kein Optimierungsproblem, dessen zugrunde liegendes Entscheidungsproblem N P-vollständig ist. Beispiel 7 (MINIMALES TSP). (siehe 6.6, Beispiel 2 Nr. 4) Eingabe: w = (di,j )i,j=1,...,n , wobei di,j ∈ Stadt j sind. die Kosten des Weges von Stadt i zu Ausgabe: Permutation v = (i1 , i2 , . . . , in ), die die Kosten c(w, v) = di1 ,i2 + di2 ,i3 + · · · + din−1 ,in + din ,i1 minimiert. Diese Aufgabe gehört nicht zu PO, falls P 6= N P, denn wir wissen, dass das zugrunde liegende Entscheidungsproblem N P-vollständig ist. 6.11 Approximation von Optimierungsproblemen Falls es für ein Optimierungsproblem keinen effizienten Algorithmus gibt, der die optimale Lösung findet, können wir versuchen, eine suboptimale Lösung effizient zu konstruieren. Beispiel 1. MINIMALE KNOTEN-ÜBERDECKUNG Eingabe: Ungerichteter Graph Ausgabe: Minimale Menge D an Knoten, so dass jede Kante einen Knoten aus D enthält. Es ist bekannt, dass das zugrunde liegende Entscheidungsproblem (ob eine Knotendeckung mit höchstens n Knoten existiert) N P-vollständig ist. Eine suboptimale Lösung kann wie folgt beschrieben werden: Algorithmus für KNOTEN-ÜBERDECKUNG Eingabe: Ungerichteter Graph G Ausgabe: Eine Knotenüberdeckung D 1: D := ∅ 2: V := die Menge aller Knoten von G 3: E := die Menge aller Kanten von G 4: while E eine Kante (x, y) enthält do 5: D := D ∪ {x, y} 180 6: 7: KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN E := E − {v : v eine Kante mit Endknoten x oder y} od Korrektheit: Wir konstruieren hier eine Menge D von Knoten mit der Eigenschaft, dass jede im Schritt 6 entfernte Kante einen Endknoten in D hat. Da am Ende alle Kanten entfernt worden sind, ist D eine Knotenüberdeckung. Zeitkomplexität ist linear, denn jede Kante des Graphen wird von dem Algorithmus nur einmal besucht. Beziehung zum Optimum: Bezeichnen wir für jeden Graphen G mit opt(G) die minimale Größe einer Knoten-Überdeckung und mit c(G) die Größe der Überdeckung, die unser Algorithmus konstruiert. Es gilt c(G) ≤ 2opt(G). In der Tat hat der Algorithmus die folgende Eigenschaft: D wird mittels paarweise disjunkter Kanten des Graphen G konstruiert. Jede Überdeckung D0 muß wenigsten einen Endknoten von jeder dieser Kanten enthalten, also muß D0 mindestens halbsoviele Elemente wie D haben. Definition. Sei (Σ, E, A, L, c) ein Optimierungsproblem. Ein ε-approximierender Algorithmus (ε ≥ 0 eine reelle Zahl) ist ein Algorithmus der Klasse P, der für jede Eingabe w ∈ E eine Ausgabe v ∈ A mit vLw berechnet, so dass der relative Fehler von c(w, v) im Vergleich zum optimalen Wert opt(w) kleiner gleich ε ist; d.h., es gilt kc(w, v) − opt(w)k ≤ ε. opt(w) Beispiel 2. Für MINIMALE KNOTEN-ÜBERDECKUNG haben wir einen 1approximierenden Algorithmus gefunden: es gilt c(w, v) ≤ 2opt(v), also kc(w, v) − opt(w)k ≤ 1. opt(w) Dieser Algorithmus ist nicht ε-approximierend für ε < 1, denn schon für den Graphen mit zwei Knoten und einer Kante gilt opt = 1, c(w, v) = 2. Beispiel 3 (SIT (Scheduling Independent Tasks)). Es sollen Aufgaben W1 , . . . , Wn mit gegebener zeitlicher Dauer t1 , . . . , tn durch k Maschinen bewältigt werden. Wir nehmen an, dass jede Maschine unabhängig von den anderen jede Aufgabe bearbeiten kann. Unsere Ziel ist es, einen Plan (schedule) zu erstellen, d.h. jeder Arbeit Wi (i = 1, . . . , n) eine Maschine S(i) = 1, . . . , k zuzuordnen, so dass der Zeitbedarf T zur Erledigung aller Aufgaben minimal ist. Die Laufzeit der Maschine m(= 1, . . . , k) P beträgt ti , wobei über alle i mit S(i) = m summiert wird. Der Zeitbedarf ist somit T = max{ X S(i)=1 ti , . . . , X S(i)=k ti }. Da die Zahl k der Maschinen konstant ist, bezeichnen wir das Problem als SIT(k). Wir haben also: Eingabe von SIT(k): Zahlen t1 , . . . , tn . Ausgabe von SIT(k): eine Funktion S : {1, . . . , n} → {1, . . . , k}, 6.11. APPROXIMATION VON OPTIMIERUNGSPROBLEMEN für die die Zahl T = max{ X ti , . . . , S(i)=1 X S(i)=k 181 ti } minimal ist. Ein 1/3-approximierender Algorithmus A für SIT(k) Der folgende Algorithmus erledigt erst die längsten Arbeiten und erst dann die kürzeren. Außerdem zieht er die am wenigsten benutzten Maschinen vor. Wir benutzen die Hilfsvariable Tm = die Zeit, die Maschine m bisher gearbeitet hat Eingabe: Zahlen t1 , . . . , tk Ausgabe: Funktion S : {1, . . . , n} → {1, . . . , k} 1: sortiere die gegebenen Zeiten, so dass t1 ≥ t2 ≥ · · · ≥ tn 2: for m = 1 to k do 3: Tm := 0 4: end for 5: for i = 1 to n do 6: m := ein Index mit Tm = min{T1 , . . . , Tk } 7: S(i) := m 8: Tm := Tm + ti 9: end for Korrektheit: In der zweiten Schleife ab Zeile 5 wird jede Aufgabe Wi einer Maschine S(i) zugeordnet. Zeitkomplexität: Das Sortieren in Zeile 1 dauert O(n·log n) Zeiteinheiten, die Initialisierung in Zeilen 2–4 dauert O(1) Einheiten, jeder der n Durchläufe der Schleife ab Zeile 5 dauert O(1) Zeiteinheiten (insbesondere besitzt die Menge, deren Minimum in Zeile 6 zu bestimmen ist, immer k Elemente). Insgesamt wird der Zeitbedarf des Algorithmus durch das Sortieren in Zeile 1 dominiert und betragt O(n log n). Dies ist also ein Algorithmus der Klasse P. Approximierung: Dieser Algorithmus ist 1/3-approximierend. Anstatt dies hier zu beweisen, zeigen wir (für ein beliebig kleines ε > 0) einen ε-approximierenden Algorithmus für SIT(k). Beispiel 4 (Ein ε-approximierender Algorithmus für SIT(k)). Die Idee ist einfach: wir wählen eine geeignete“ Konstante und verteilen die ersten r (längsten) Aufga” ben optimal – z.B. suchen wir aus allen k r möglichen Zuordnungen die beste aus. Den Rest berechnen wir mit dem Algorithmus aus Beispiel 3. Wir werden zeigen, dass jede Wahl (1) r> k−1 ε einen ε-approximierbaren Algorithmus ergibt. Für eine ausgewählte Konstante r beschreiben wir also den entsprechenden Algorithmus. Approximierender Algorithmus Ar für SIT(k): 1: sortiere t1 ≥ t2 ≥ · · · ≥ tn 2: finde für die Eingabe t1 , . . . , tr die optimale Planung Sopt : {1, . . . , r} → {1, . . . , k} 3: for m = 1 to k do 182 4: 5: 6: 7: 8: 9: 10: KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN P Tm := Sopt (i)=m ti end for for i = r + 1 to n do m := ein Index mit Tm = min{T1 , . . . , Tk } S(i) := m Tm := Tm + ti end for Korrektheit: klar Zeitkomplexität: Für jede Konstante r hat dieser Algorithmus dieselbe Zeitkomplexität O(n · log n) wie oben in Beispiel 3. Genauer: der Algorithmus braucht die Zeit O(n log n + k r+1 ). Für jede Konstante r ist dies einfach O(n log n). Wenn aber ε in (1) gegen Null geht, wächst r und die Zeitkomplexität steigt exponentiell. In der Tat kann die optimale Zuordnung in Zeile 2 wie folgt gefunden werden: wir durchsuchen alle k r möglichen Zurodnungen: für jede Zuordnung S berechnen wir in der Zeit O(k) die gesamte Bearbeitungszeit T (S), die die m Arbeiten unter der Planung S dauern, und dann finden wir in der Zeit O(k r ) das Minimum aller T (S). Schritt 2 dauert also O(k · k r ) Zeiteinheiten. O(k k/ε ) Zeiteinheiten und der Algorithmus hat also die Zeitkomplexität O(n · log n + k M +1 ). Approximierung: Wir beweisen, dass unser Algorithmus ε-approximierbar ist, falls (1) gilt: (2) aus r ≥ T − Topt k folgt ≤ε ε Topt Beweis. T sei der Zeitbedarf der Zuordnung, die unser Algorithmus findet. Es muß mindestens eine Aufgabe Wi geben, die genau zur Zeit T beendet wird. Falls i ≤ r, ist Wi eine der optimal zugeordneten Aufgaben W1 , . . . , Wr – also stimmt der Zeitbedarf T (zufällig) mit dem (optimalen) Zeitbedarf für die ersten r Aufgaben überein und ist folglich selber optimal, T = Topt , was (2) beweist. Wir können also (3) i>r annehmen. Also erfolgt die Zuordnung der Aufgabe Wi durch den obigen Algorithmus A. Die Aufgabe Wi beginnt zur Zeit T − ti . Daraus folgt, dass alle k Maschinen im Zeitraum [0, T − ti ) durchgängig beschäftigt sind. Falls es nämlich eine Maschine geben sollte, deren Tätigkeit zur Zeit T0 < T − ti aufhört, würde der Algorithmus A die Aufgabe Wi auf dieser Maschine zum Zeitpunkt T0 beginnen lassen (denn A bevorzugt die weniger beschäftigten Maschinen) und somit würde Wi nicht zur Zeit T enden. Die Gesamtarbeitszeit aller k Maschinen im Zeitraum [0, T − ti ), also einem Intervall der Länge T − ti , beträgt also k(T − ti ). Aber der Algorithmus A verplant nur Aufgaben Wj mit j < i in diesem Zeitraum (da Wi selbst erst zur Zeit T − ti anfängt). Im Intervall [0, T − ti ) werden also nur die Aufgaben W1 , . . . , Wi−1 bearbeitet. Die Gesamtarbeitszeit k(T − ti ) ist also höchstens so groß wie die Zeit t1 + · · · + ti−1 , die die Bearbeitung der Aufgaben W1 , . . . , Wi−1 verlangt: (4) k(T − ti ) ≤ t1 + · · · + ti−1 . Es gilt also (5) T ≤ t1 + · · · + ti−1 + ti . k 6.11. APPROXIMATION VON OPTIMIERUNGSPROBLEMEN 183 Anderseits dauern alle n Aufgaben insgesamt t1 + · · · + tn Zeiteinheiten. Die optimale Zuordnung ergibt einen Zeitbedarf von Topt Zeiteinheiten, dabei sind die k Maschinen maximal kTopt Zeiteinheiten aktiv (falls alle die ganze Zeit beschäftigt sind). Daraus folgt kTopt ≥ t1 + · · · + tn . (6) Dann gilt Topt ≥ (7) t1 + · · · + t n t1 + · · · + ti−1 ≥ . k k Die Kombination von (5) und (7) ergibt T − Topt ≤ t1 + · · · + ti−1 t1 + · · · + ti−1 + ti − = ti k k Aus (2) wissen wir, dass ti ≤ tr (denn i > r), also T − Topt ≤ tr . (8) Jetzt benutzen wir (6) nochmals: da t1 ≥ t2 · · · ≥ tn , gilt Topt ≥ t1 + · · · + t n t1 + · · · + t r r · tr ≥ ≥ k k k und kombiniert mit (8), bekommen wir T − Topt k tr ≤ r·tr = . Topt r k (9) Da r ≥ k ε ist, folgt k r ≤ ε, also ist (9) die gewünschte Ungleichung. Satz 1. Für kein ε > 0 gibt es einen ε-approximierenden Algorithmus für TSP, falls P 6= N P. Beweis. Wir wissen, dass HAMILTONSCHER KREIS ein N P-vollständiges Problem ist. Wir beweisen, dass wir einen Algorithmus A der Klasse P für HAMILTONSCHER KREIS finden können, falls ein ε-approximierender Algorithmus Aε für TSP gegeben ist – es folgt, dass P = N P. Ein ungerichteter Graph G als Eingabe wird von A wie folgt bearbeitet: Der Algorithmus Aε wird auf das TSP angewendet mit n Städten und ( 1 falls (i, j) eine Kante von G ist di,j = 2 + dεne falls nicht, wobei dεne die kleinste ganze Zahl ≥ εn ist. Bezeichnen wir mit c die Kosten der Tour, die Aε findet. Der Algorithmus A liefert die Antwort JA genau dann, wenn c ≤ (1 + ε)n. Korrektheit des Algorithmus A: wir beweisen G hat einen Hamiltonschen Kreis ⇐⇒ c ≤ (1 + ε)n. In der Tat: 184 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN 1. Jeder Hamiltonsche Kreis von G besteht aus n Kanten, also betragen die Kosten copt = n. Da Aε ε-approximierend ist, gilt also c−n ≤ε n und somit c ≤ (ε + 1)n. 2. Falls die gefundene Rundreise der Bedingung c ≤ (1 + ε)n genügt, zeigen wir, dass sie nur Kanten aus G enthält, also einen Hamiltonschen Kreis in G bildet. Dazu reicht es, c < 2 + dεne + (n − 1) zu beweisen, denn jede Rundreise, die mindestens einmal die Kanten von G verläßt, kostet mindestens 2 + dεne (= Kosten einer Kante außerhalb von G) plus n−1 (die untere Grenze der Kosten der anderen n − 1 Kanten). Wegen εn < dεne + 1 folgt c ≤ (ε + 1)n < n + dεne + 1 = 2 + dεne + (n − 1). Zeitkomplexität des Algorithmus A: für den Algorithmus Aε existiert ein Polynom p(n), so dass Aε die Rundreise in der Zeit p(n) findet. Dann dauert die Bearbeitung des Graphen G höchstens O(n2 ) Schritte für die Konstruktion von TSP und dann p(n) Schritte für Aε , insgesamt also O(n2 + p(n)) Schritte. Das bedeutet, dass A in der Klasse P liegt – im Widerspruch zur N P-Vollständigkeit von HAMILTONSCHEM KREIS. Zusammenfassung: Für Optimierungsprobleme, für die wir keinen effizienten Algorithmus finden können, können wir versuchen, approximierbare Algorithmen zu finden. Es gibt Aufgaben, die sogar für jedes ε einen ε-approximierbaren Algorithmus besitzen, z.B. SIT(k). Leider gibt es aber wichtige Optimierungsaufgaben, die keinen ε-approximierbaren Algorithmus erlauben, z.B. TSP. 6.12 Raumkomplexität Bisher haben wir einen Algorithmus als effizient betrachtet, falls er wenig Zeit braucht. Ein anderer wichtiger Gesichtspunkt ist der Speicherbedarf eines Algorithmus. Wie die Zeitkomplexität ist auch die Raumkomplexität prinzipiell von der Implementation unabhängig, falls wir nur die Frage stellen, ob polynomial großer Speicher genügt. Deswegen können wir wieder Turingmaschinen als Berechnungsmodell verwenden. Wir sagen, dass eine TM die Raumkomplexität s(n) hat, wobei s(n) eine Funktion über der Menge aller natürlichen Zahlen ist, falls für jede Eingabe w der Länge n die TM hält und der Kopf höchstens s(n) Bandfelder durchgegangen ist. Definition. Wir bezeichnen mit PSPACE die Klasse aller formalen Sprachen, die von einer TM mit polynomialer Raumkomplexität akzeptiert werden können. Genauer: eine Sprache L gehört zur Klasse PSPACE, falls es eine Turingmaschine M und ein Polynom p(n) gibt, so dass L = L(M ) und M hat die Raumkomplexität p(n). Bemerkung 1. 1. Die vorher eingeführten Klassen P und N P werden oft PT IME und N PT IME bezeichnet, um sie von PSPACE zu unterscheiden. 6.12. RAUMKOMPLEXITÄT 185 2. Es gilt PT IME ⊆ PSPACE denn in einem Schritt kann eine TM nur ein Bandfeld besuchen. Es folgt, dass Probleme wie 2-FÄRBUNG, 2-ERFÜLLBARKEIT usw. in PSPACE liegen. 3. Das Problem der UNIVERSALITÄT REGULÄRER AUSDRÜCKE (Beispiel 6 in 6.2) gehört nicht zur Klasse PSPACE. 4. Die Klasse N PSPACE “, die zu N PT IME analog wäre, brauchen wir nicht ” einzuführen: Satz 1 (Savitch-Satz). Jede nichtdeterministische Turingmaschine mit polynomialer Raumkomplexität kann durch eine (deterministische) Turingmaschine mit polynomialer Raumkomplexität simuliert werden. Beweis. Sei M eine NTM mit Raumkomplexität p(n) > n, dann konstruieren wir eine (deterministische) Turingmaschine M ∗ , mit der Raumkomplexität O(p2 (n)), die dieselbe Sprache akzeptiert. Wir können annehmen, dass M das Band löscht, bevor sie im finalen Zustand hält. Dann ist (qF , #) die einzige akzeptierende Konfiguration. Es gibt eine Konstante C, so dass die Berechnung eines Wortes der Länge n höchstens 2Cp(n) Konfigurationen durchläuft. In der Tat haben die Konfigurationen die Form (q, s1 . . . si . . . sp(n) ), wobei q ein Zustand ist, s1 . . . sp(n) ist der Inhalt des Bandes und i ist die Kopfposition. Falls die Maschine r Zustände und m Symbole in Σ ∪ {#} hat, ist die Zahl der Konfigurationen gleich r (für Zustände q) mal p(n) (für Kopfpositionen i) mal der Zahl mp(n) aller Wörter s1 . . . sp(n) über Σ ∪ {#}. Es gilt rp(n)mp(n) < rmp(n) mp(n) = rm2p(n) < 2Cp(n) für eine geeignete Konstante C. Es folgt, dass für jedes von M akzeptierte Wort s1 . . . sn sn eine akzeptierende Berechnung von höchstens 2Cp(n) Schritten existiert. In der Tat, nehmen wir die kürzeste akzeptierende Berechnung von s1 . . . sn , dann wird keine der 2C p(n) Konfigurationen wiederholt. Es gilt: M akzeptiert s1 . . . sn genau dann, wenn (q0 , s1 . . . sn ) `∗ (qF , #). Und das können wir durch die Begrenzung 2Cp(n) der Zahl der Schritte wie folgt verschärfen: Für zwei Konfigurationen K und K 0 schreiben wir REACH(K, K 0 , i) = true 186 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN falls in höchstens 2i Berechnungsschritten aus der Konfiguration K die Konfiguration K 0 erreicht werden kann. (Z.B. bedeutet REACH(K, K 0 , 0), dass die Konfiguration K 0 in höchstens einem Schritt aus Konfiguration K erreicht werden kann – d.h., entweder K = K 0 oder K 0 ist eine Folgekonfiguration von K.). Es gilt M akzeptiert s1 . . . sn genau dann, wenn REACH(K, K 0 , Cp(n)) = true für K = (q0 , s1 . . . sn ), K 0 = (qF , #) Es genügt also, einen Algorithmus zu finden, der die Antwort REACH(K, K 0 , i) mit polynomialer Raumkomplexität für alle Paare K, K 0 von Konfigurationen und alle Zahlen i = 0, . . . , Cp(n) berechnet. Die Idee ist, dass es für i = 0 nur die Überprüfung ist, ob K 0 eine der Folgekonfigurationen ist, die in O(1) Zeiteinheiten berechnet wird, und aus dem Fall REACH(−, −, i) können wir REACH(−, −, i + 1) wie folgt berechnen: Seien K, K 0 Konfigurationen, für die REACH(K, K 0 , i + 1) = true ist. Also gibt es eine Berechnung in 2i+1 = 2 · 2i Schritten; sei K die Konfiguration, die aus K in dieser Berechnung in 2i Schritten erreicht wird – dann gilt REACH(K, K, i) = true und REACH(K, K 0 , i) = true. Umgekehrt: falls es eine Konfiguration K gibt mit REACH(K, K, i) = true = REACH(K, K 0 , i), gilt bestimmt REACH(K, K 0 , i + 1). Die Antwort REACH(K, K 0 , i) kann für i = 0, . . . , Cp(n) also rekursiv durch den folgenden deterministischen Algorithmus berechnet werden: i = 0 : Antwort true genau dann, wenn K = K 0 oder K ` K 0 . i + 1 : Antwort true genau dann, wenn es eine Konfiguration K gibt mit REACH(K, K, i) ∧ REACH(K, K 0 , i) = true. Für i = 0 muß dieser Algorithmus nur die zwei Konfigurationen K, K 0 (Wörter der Länge p(n) + 1) speichern, also ist der Raumbedarf O(p(n)). Für i + 1 müssen wir, für den rekursiven Ablauf, i speichern, und neben den Eingaben K und K 0 wird die lokale Variable K gespeichert. Dann wird REACH(K, K, i) überprüft. Falls die Antwort true ist, können wir denselben Raum (!) wieder benutzen, um REACH(K, K 0 , i) zu überprüfen. Da i ≤ Cp(n) und K, K 0 , K Wörter der Länge p(n) + 1 sind, wird in einem Schritt der Rekursion Raum O(p(n)) genügen. Die Rekursion hat Cp(n) Schritte, also brauchen wir insgesamt Raum O(Cp2 (n)). Korollar 1. N PT IME ⊆ PSPACE Beweis. In der Tat sagt uns der Savitch-Satz, dass PSPACE = N PSPACE. Und N PT IME ⊆ N PSPACE ist analog zur Bemerkung 1 Nr. 2 oben. Bemerkung 2. Die Klasse PSPACE enthält also alle Probleme, für die es (Zeit-) effizient entscheidbar ist, ob eine angebotene Lösung wirklich das Problem löst. Z. B. TSP, 3-FÄRBBARKEIT usw. Es ist nicht bekannt, ob N PT IME = PSPACE gilt. Wir zeigen jetzt ein interessantes Beispiel eines Prolems, für das nicht klar ist, ob es zu N PT IME gehört, da es keinen vernünftigen Begriff von angebotener Lösung“ ” gibt, das aber zu PSPACE gehört. Beispiel 1 (QUANTIFIZIERTE BOOLESCHE FORMELN). Eingabe: Eine quantifizierte Boolesche Formel φ ohne freie Variablen. 6.12. RAUMKOMPLEXITÄT 187 Ausgabe: JA genau dann, wenn φ den Wert true hat. Bisher sprachen wir nur über Boolesche Formeln ohne Quantoren (∀x), (∃x). Die quantifizierten Booleschen Formeln, QBF, in Variablen xi (i = 1, . . . , n) können wie folgt definiert werden: 1. Jede Variable xi ist eine QBF 2. Die Konstanten true und false sind QBF 3. Falls E1 , E2 zwei QBF sind, sind auch E1 ∨ E2 , E1 ∧ E2 , E1 → E2 und ¬E2 QBF’n. 4. Falls E eine QBF ist, sind auch (∀x)E und (∃x)E (für jede Variable x) QBF’n. Das heißt: die Menge aller QBF ist die kleinste Menge, für die 1 – 4 gilt. Beispiel: E = (∀x)(∃y)(x → ((∀x)(¬y ∨ x))). Dies ist eine geschlossene QBF, dass heißt, alle Variablen werden quantifiziert (der innere Quantor (∀x) wirkt über die Formel (¬y ∨ x), der äußere über (∃y)(x → ((∀x)(¬y ∨ x))) ). Jede geschlossene Formel hat einen Wert, den wir bekommen, indem wir für jede quantifizierte Variable die Belegung mit true oder false betrachten. Zum Beispiel in E müssen wir, aufgrund des äußeren (∀x), die zwei Formeln E1 = (∃y)(true → ((∀x)(¬y ∨ x))) und E2 = (∃y)(false → ((∀x)(¬y ∨ x))) bewerten: falls beide Werte true sind, ist E true (sonst false). Also W ERT (E) = W ERT (E1) ∧ W ERT (E2) Um den Wert von E1 zu bewerten, müssen wir die Werte von E11 = true → ((∀x)(¬true ∨ x)) und E12 = true → ((∀x)(¬false ∨ x)) kennen: falls einer der Werte true ist, ist E1 true (sonst false), also W ERT (E1 ) = W ERT (E11 ) ∨ W ERT (E12 ). Der Wert von E11 ist false: betrachten wir die Belegung x = true. Aber der Wert von E12 ist true, da ¬false ∨ x = true ∨ x den Wert true hat für x = false, true. Also W ERT (E1 ) = false ∨ true = true. Analog kann man zeigen, dass W ERT (E2 ) = true, also W ERT (E) = true. 188 KAPITEL 6. KOMPLEXITÄT VON ALGORITHMEN Im allgemeinen definieren wir die Menge V ar(E) aller freien Variablen einer QBF wie folgt: V ar(xi ) = {xi } V ar(true) = V ar(false) = ∅ V ar(E1 ∨ E2 ) = V ar(E1 ) ∪ V ar(E2 ), analog mit ∧, → V ar(¬E) = V ar(E) V ar((∀x)E) = V ar((∃x)E) = V ar(E) − {x} Eine QBF heißt geschlossen, falls sie keine freien Variablen hat, falls also V ar(E) = ∅. Den Wert W ERT (E) einer geschlossenen QBF definieren wir wie folgt: W ERT (true) = true W ERT (false) = false W ERT (E1 ∨ E2 ) = W ERT (E1 ) ∨ W ERT (E2), analog mit ∧, → W ERT (¬E) = ¬W ERT (E) W ERT ((∀x)E) = W ERT (E(true/x)) ∧ W ERT (E(false/x)) W ERT ((∃x)E) = W ERT (E(true/x)) ∨ W ERT (E(false/x)) Hier ist E(true/x) die QBF, die wir aus E bekommen, indem alle freien Vorkommen der Variablen x durch true ersetzt werden, analog E(false/x). Bemerkung 3. Das Problem QBF gehört zur Klasse PSPACE. In der Tat existiert ein Algorithmus mit Raumkomplexität O(n2 ), wobei n die Länge des Wortes E ist, der entscheidet, ob E true ist. Hier bezeichnet E eine geschlossene Boolesche Formel. Den Wert W ERT (E) = true oder false berechnen wir rekursiv wie folgt • falls E = true, ist W ERT (E) = true • falls E = false, ist W ERT (E) = false • falls E = ∀xi (E 0 ) oder E = ∃xi (E 0 ), berechnen wir erst (rekursiv) den Wert von E(true/xi ) Dann speichern wir das Ergebnis (in 1 Bit) und auf demselben Raum (!) berechnen wir E(false/xi ), speichern das Ergebnis (wieder 1 Bit) und entscheiden, ohne zusätzlichen Raum, den Wert von E aufgrund dieser zwei Werte. Algorithmus für QBF Eingabe: E, eine QBF ohne freie Variablen. Ausgabe: der Wert von E, W ERT (E), rekursiv berechnet: W ERT (true) := true; W ERT (false) := false; W ERT (∀xi (E)) := W ERT (E(true/xi )) ∧ W ERT (E(false/xi )); W ERT (∃xi (E)) := W ERT (E(true/xi )) ∨ W ERT (E(false/xi )); 6.12. RAUMKOMPLEXITÄT 189 Korrektheit: Jede QBF kann in die Form mit Quantoren nach außen gebracht werden. Falls die Formel in dieser Form keine freien Variablen besitzt, muß sie eine der 4 Typen oben sein. Die Rekursion erfolgt nach der Zahl k aller Quantoren von E. Für k = 0 ist E = true oder E = false, falls k > 0 ist, gilt E = ∀xi (E) oder E = ∃xi (E), wobei für E die Zahl aller Quantoren k − 1 ist. Nach k Rekursionsschritten wird also W ERT (E) berechnet sein. Raumkomplexität: Sei E eine QBF der Länge n. Die Zahl k aller Quantoren in E erfüllt k < n. Die Rekursion hat also Tiefe n und in jedem rekursiven Schritt brauchen wir, wie oben erklärt wurde, nur Raum um 2 Bit größer als der Raum des nächsten Schrittes. Das Wort E hat Länge n, also haben die in der Rekursion gespeicherten Wörter Länge O(n), was mit n rekursiven Schritten Raum O(n2 ) verlangt. Offenes Problem: Liegt QBF in N PT IME? In der Tat scheint dies unwahrscheinlich, denn QBF ist PSPACE-vollständig , das heißt für jedes Problem der Klasse PSPACE gibt es eine Reduktion auf QBF in polynomialer Zeit (!). Falls also QBF ∈ N PT IME ist, folgt N PT IME = PSPACE.