Kathrin Bujna, 6399514 Dominik Leibenger, 6399272 Martin Wistuba, 6396819 Paderborn, den 23. Januar 2009 Komplexitätstheorie WS 08/09 Blatt 5 AUFGABE 1: zu zeigen: k − Clique ∈ L Folgende DTM M (Eingabe w) entscheidet die Sprache k − Clique: 1. Prüfe, ob w korrekte Codierung von hG = (V, E)i. Falls nicht, lehne ab 2. Initialisiere k Zähler mit Wert 0 3. Wiederhole 4. Erhöhe letzten Zähler um 1. Falls dieser größer als |V | − 1 wird, setze diesen auf 0 und erhöhe den Zähler davor. Falls dieser Zähler größer |V | − 1 wird, verfahre analog mit den weiteren Zählern. Erreicht dabei der erste Zähler den Wert |V |, lehne ab 5. Prüfe, ob alle k Zähler unterschiedliche Werte haben, falls nicht, gehe zu Schritt 4. 6. Prüfe, ob zwischen allen Knoten, die durch die k Zähler repräsentiert werden, Kanten existieren. Ist dies der Fall, akzeptiere. Für die Prüfung, ob w eine korrekte Codierung ist, ist O(log n) Speicher nötig, da im Wesentlichen nur die Anzahl der Knoten gemerkt und die Korrektheit der Kanten geprüft werden muss. Da k konstant ist und jeder der k Zähler nur Werte 0 bis |V | annehmen kann, ist hierzu ebenfalls nur Speicherplatz O(log |V |) = O(log n) nötig. Für die Prüfung, ob zwischen allen Knoten Kanten existieren, könnte man alle O(k 2 ) Kanten aufzählen und vergleichen, ob diese im Graph existieren. Jede Kante benötigt O(log n) Platz, also benötigen alle ≤ k 2 Kanten nur O(log n) Platz. Insgesamt benötigt M auf dem Arbeitsband folglich nur O(log n) Platz. Es bleibt zu zeigen, dass M korrekt arbeitet. Angenommen, w ∈ k −Clique. Dann ist w eine korrekte Kodierung und es gibt k Knoten in G, die eine Clique bilden. M zählt nun in Zeilen 3-6 alle möglichen Teilmengen von k verschiedenen Knoten aus G auf und prüft, ob diese eine Clique bilden. Damit zählt M auch irgendwann die k Knoten auf, die tatsächlich eine Clique bilden und akzeptiert korrekterweise in Zeile 6. Ist w nicht in k − Clique, so kann es keine Teilmenge von k verschiedenen Knoten aus G geben, die eine Clique bilden. Nachdem M alle Kombinationen von k Knoten aus G aufgezählt hat, wird in Zeile 4 korrekterweise abgebrochen. M entscheidet folglich in O(log n) Platz die Sprache k − Clique. Damit ist gezeigt, dass k − Clique ∈ L. AUFGABE 2: a) zu zeigen: G ist bipartit ⇔ G enthält keinen Kreis ungerader Länge zu zeigen: G ist bipartit ⇒ G enthält keinen Kreis ungerader Länge Angenommen, G würde einen Kreis ungerader Länge enthalten. Sei v ein beliebiger Knoten aus diesem Kreis. O.B.d.A. sei nun v ∈ V1 . Da G bipartit ist, muss nun jeder Nachbar von v in V2 liegen und jeder Nachbar der Nachbarn von v in V1 . Wenn wir die Knoten des betrachteten Kreises (v, . . . , w) durchnummerieren, beginnend bei 1 für v, bis k für w, muss offensichtlich jeder Knoten mit ungerader Nummer in V1 liegen. Da der Kreis ungerade Länge hat, muss damit auch der k-te Knoten, nämlich w in V1 liegen. Zusätzlich existiert aber eine Kante zwischen w und v, d.h. sowohl v als auch w liegen in V1 , was im Widerspruch dazu steht, dass der Graph bipartit ist. Somit kann ein bipartiter Graph keinen Kreis ungerader Länge enthalten. zu zeigen: G ist nicht bipartit ⇒ G enthält einen Kreis ungerader Länge Angenommen, wir teilen die Knoten aus V beginnend bei einem beliebigen Knoten s in die Mengen V1 bzw. V2 ein. (O.B.d.A. betrachten wir hier nur einen zusammenhängenden Teilgraphen, der nicht bipartit ist, und teilen den Startknoten in V1 ein.) Dann müssen wir irgendwann einen Knoten v betrachten, der aufgrund seiner Nachbarknoten weder in V1 noch in V2 eingeteilt werden kann (würde dies nicht passieren, wäre G offensichtlich bipartit). Wir betrachten nun diesen Knoten v. Da wir die Einteilung ausgehend von einem festen Knoten durchgeführt haben, sind alle bisher betrachteten Knoten zusammenhängend. Da s ∈ V1 , muss von s zu dem Nachbarknoten von v, der in V1 liegt, ein Weg ungerader Länge, und von s zu dem Nachbarknoten von v, der in V2 liegt, ein Weg gerade Länge existieren. Da beide Wege beim Knoten s starten, existiert zwischen den beiden Nachbarknoten nun ein Weg gerade Länge. v schließt diesen Weg gerader Länge nun zu einem Kreis ungerader Länge. Folglich ist gezeigt, dass, wenn G nicht bipartit ist, G einen Kreis ungerader Länge enthält. Damit ist gezeigt, dass ein Graph genau dann bipartit ist, wenn er keinen Kreis ungerader Länge enthält. b) zu zeigen: NonBipartite ∈ N L Folgende NTM N (Eingabe w entscheidet) NonBipartite: 1. Falls w keine korrekte Codierung von hGi, akzeptiere 2. Rate ungerade Zahl k zwischen 1 und |V |. 3. Rate Startknoten s. Merke Startknoten zusätzlich als aktuellen Knoten v. 4. Wiederhole k-mal: 5. Rate Nachbarknoten u von v. Merke u als aktuellen Knoten v. Falls kein Nachbarknoten existiert, lehne ab 6. Falls s = v, akzeptiere 7. Sonst lehne ab Die NTM muss nur zwei Zahlen (k und Zähler) ≤ |V | sowie 3 Knoten speichern. Dazu ist offensichtlich nur O(log n) Platz nötig. Es bleibt zu zeigen, dass N die Sprache Bipartite entscheidet. Die NTM rät eine ungerade Zahl k, einen Startknoten und k weitere Knoten, zwischen denen Kanten existieren. Ist der letzte geratene Knoten der Startknoten, so wurde ein Kreis der Länge k gefunden. Nur, wenn dies der Fall ist, akzeptiert N . Damit akzeptiert N genau dann, wenn in G ein Kreis ungerader Länge existiert. Nach a) ist das genau dann der Fall, wenn der Graph nicht bipartit ist. Somit entscheidet N die Sprache NonBipartite. Anmerkung: Falls in dem gefundenen Kreis ungerader Länge ein Knoten k mehrfach vorkommt, existiert auch ein Kreis ungerader Länge, der keinen Knoten mehrfach enthält. Um dies zu zeigen, nehmen wir o.B.d.A. an, dass ein Kreis ungerader Länge (u, . . . , k, . . . , k, . . . , v, u) den Knoten k exakt zweimal enthält. Dann gibt es zwei Fälle: Hat (k, . . . , k) ungerade Länge, so haben wir einen Kreis ungerader Länge, der keinen Knoten doppelt enthält. Hat (k, . . . , k) hingegen gerade Länge, so können wir uns überlegen, dass (u, . . . , k, . . . , v, u), d.h. der gefundene Kreis, gekürzt um den Zyklus gerader Länge, nun eine gerade Anzahl weniger Kanten hat, und damit wieder ungerade Länge hat. Da N die Sprache NonBipartite entscheidet und dazu nur Platz O(log n) benötigt, ist gezeigt, dass NonBipartite ∈ N L. c) zu zeigen: Path ≤L NonBipartite Idee: Wir ersetzen jede Kante (u, v) des Graphen durch zwei Knoten x(u,v0 ) und x(u0 ,v) , die mit einer Kante untereinander verbunden sind. Außerdem erzeugen wir zwischen Knoten x(u0 ,v) und x(v,w0 ) jeweils eine Kante. Zuletzt erzeugen wir einen Knoten x und Kanten von x zu allen Knoten x(u0 ,t) und zu allen Knoten x(s,v0 ) . Dies führt dazu, sodass jeder im Graph ggf. existierende Zyklus nun gerade Länge hat, und nur ein Zyklus, der x(s,u0 ) , x und x(v0 ,t) enthält, ungerade Länge hat. Folgende DTM leistet dies bei Eingabe w: 1. Falls w keine korrekte Codierung von hG, s, ti, schreibe 0 aufs Ausgabeband und akzeptiere 2. Schreibe Knoten x(u,uv) , x(uv,u0 v0 ) und x(u0 v0 ,v) für alle Kanten (u, v) ∈ E sowie Knoten x aufs Ausgabeband. 3. Für je zwei Kanten (u, v), (v, w) ∈ E, schreibe Kante {x(u0 v0 ,v) , x(v,vw) } aufs Ausgabeband. 4. Für jede Kante (s, u) ∈ E, schreibe Kante {x, x(s,su) } aufs Ausgabeband. 5. Für jede Kante (v, t) ∈ E, schreibe Kante {x, x(v0 t0 ,t) } aufs Ausgabeband. Die DTM muss im Wesentlichen nur die Knoten und Kanten sowie s und t vom Eingabeband lesen und die entsprechenden Knoten und Kanten erzeugen. Bei geeigneter Kodierung müssen dazu nur konstant viele einzelne Knoten oder Kanten aufs Arbeitsband geschrieben werden, sodass dazu nur Platz O(log n) nötig ist. Sei f die von der DTM berechnete Funktion und f (hG = (V, E), s, ti) = G0 = (V 0 , E 0 ). Korrektheit: w ∈ Path ⇒ f (w) ∈ NonBipartite: Da w in Path liegt, ist w eine korrekte Codierung von hG, s, ti und es existiert in G ein Weg von s nach t. Nach Konstruktion existiert damit in G0 ein Weg von x(s,su) nach x(v0 t0 ,t) (mit geeignetem su, v 0 t0 , der - ausgehend von x(s,su) - für jede Kante aus G zwei Knoten in G0 nutzt, also gerade Länge hat. Da eine Kante zwischen x(s,su) und x sowie zwischen x und x(v0 t0 ,t) in G0 existiert, existiert somit ein ungerader Kreis, d.h. G0 ist nicht bipartit und f (w) ∈ NonBipartite. w∈ / Path ⇒ f (w) ∈ / NonBipartite: Da w nicht in Path liegt, ist w keine korrekte Codierung von hG, s, ti oder es existiert in G kein Weg von s nach t. Im ersten Fall ist f (w) = 0 ∈ / NonBipartite. Im zweiten Fall ist f (w) = hG0 i. Nach Konstruktion ist aber jeder Kreis, der in G existierte, nun genau doppelt so groß wie zuvor und hat daher eine gerade Anzahl an Knoten. Ein Kreis ungerader Größe könnte nur existieren, wenn der Knoten x in G0 genutzt würde - dieser kann aber keinen Kreis schließen, da nach Voraussetzung zwischen x(s,su) und x(v0 t0 ,t) kein weiterer Weg existiert. Also ist f (w) ∈ / NonBipartite Damit ist gezeigt, dass Path ≤L NonBipartite. AUFGABE 3: Rekursive Formulierung: k0 (w) = 0 kj (w) = kj−1 (w)+ # Konfigurationen, die direkte Nachfolgerkonfigurationen der kj−1 (w) zugrundeliegenden Konfigurationen sind und nicht in der Anzahl kj−1 (w) berücksichtigt wurden. Zunächst sei N0 eine NTM, die nur 1 zurückgibt (aus der Startkonfiguration känn in 0 Schritten nur die Startkonfiguration selbst erreicht werden). Wir konstruieren nun Nj bei Eingabe w wie folgt: 1. Setze kj = 1 2. Für alle korrekt kodierten Konfigurationen K ohne Startkonfiguration 3. Setze kj−1 = 0 4. Für alle korrekt kodierten Konfigurationen K 0 5. Rate b ∈ {0, 1} 6. Falls b = 0, gehe zu 4. mit nächstem K 0 7. Falls b = 1 und KonfigErreichbar(K 0 , j − 1) 8. kj−1 = kj−1 + 1 9. Falls K direkte Nachfolgekonfiguration von K 0 oder K = K 0 10. kj = kj + 1 11. Gehe zu 2. mit nächstem K 0 12. Simuliere Nj−1 auf w und merke Ergebnis in kj−1 0 13. Falls kj−1 6= kj−1 , lehne ab 14. Gebe kj zurück Die von Nj verwendete NTM KonfigErreichbar lässt sich dabei bei Eingabe (w = K, j) wie folgt beschreiben: 1. Prüfe, ob w korrekt kodiert, falls nicht, lehne ab 2. Merke Startkonfiguration von N als K 0 3. Wiederhole j mal: Rate Nachfolgekonfiguration von K 0 , speichere diese als K 0 4. Falls K 0 = K, akzeptiere, sonst lehne ab Lässt sich K in j Schritten ausgehend von der Startkonfiguration in N erreichen, so akzeptiert KonfigErreichbar offensichtlich, ansonsten lehnt diese ab. Der Speicherbedarf dieser NTM ist dabei O(s(n)), da lediglich zu jedem Zeitpunkt maximal 3 Konfigurationen der Länge O(s(n)) gespeichert werden müssen. Nj prüft für jede mögliche Konfiguration von N , ob diese bei Eingabe w nach maximal j Schritten erreicht werden kann: Akzeptiert Nj die Eingabe w, so wurden in Zeilen 4-11 immer alle kj−1 (w) Konfigurationen korrekt geraten, die von N bei Eingabe w nach max. j − 1 Schritten erreicht werden können. Die NTM zählt dabei alle Konfigurationen, die nach maximal j − 1 Schritten aus der Startkonfiguration erreicht werden können oder eine direkte Nachfolgekonfiguration einer dieser Konfigurationen sind. Nach Konstruktion ist die in Zeile 13 zurückgegebene Zahl damit genau der Wert kj (w). Platzbedarf: Die NTM Nj muss im Wesentlichen die Zähler kj , kj−1 , die Eingabe w und die Konfigurationen K und K 0 speichern. Da N O(s(n))-platzbeschränkt ist, können Konfigurationen von N maximal O(s(n)) lang sein. Insgesamt kann es damit maximal 2O(s(n)) Konfigurationen geben, d.h. die verwendeten Zähler können maximal einen Wert 2O(s(n)) , für den log(2O(s(n)) ) = O(s(n)) Platz notwendig ist, darstellen. Die Simulation von KonfigErreichbar in Zeile 7 benötigt nur O(s(n)) Platz, da nur konstant viele Konfigurationen zur gleichen Zeit auf dem Band stehen. Die NTM arbeitet in Zeile 11 wie Nj−1 . Diese benötigt, wenn man die quasi-rekursiven Aufrufe in Zeile 11 außer Acht lässt, genauso viel Platz wie Nj . Insgesamt gibt es zu einem Zeitpunkt maximal j rekursive Aufrufe in Zeile 11, d.h. insgesamt genötigt Nj Platz j · O(s(n)). Da j konstant ist, folgt ein Platzbedarf von O(s(n)). Laufzeit: Es gibt insgesamt 2O(s(N )) Konfigurationen von N . Damit wird die Schleife in Zeile 2 2O(s(n)) mal und die Schleife in Zeile 4 (2O(s(n)) )2 mal durchlaufen. In jedem der Durchläufe der inneren Schleife ist im Wesentlichen Zeit O(s(n)) nötig. Damit ergibt sich für Zeilen 1-11 eine Laufzeit von O(s(n) · 2O(s(n)) . Durch die rekursiven Aufrufe in Zeile 12 ergibt sich damit eine Laufzeit von O((O(s(n) · 2O(s(n)) ))j ) = O(s(n) · 2O(s(n)) ). AUFGABE 4: zu zeigen: N L = co − N L ⇔ Path ≤L Path zu zeigen: N L = co − N L ⇒ Path ≤L Path Sei L ∈ N L beliebig. Da Path N L-vollständig, gilt L ≤L Path. Sei M die DTM, die f mit w ∈ L ⇔ f (w) ∈ Path berechnet. Offensichtlich gilt dann auch L ≤L Path. Da N L = co − N L lässt sich damit aber jede Sprache aus N L auf Path L-reduzieren, d.h. es gilt insbesondere auch Path ≤L Path, was zu zeigen war. zu zeigen: N L = co − N L ⇐ Path ≤L Path Da Path N L-vollständig ist und Path ≤L Path, ist auch Path N L-vollständig. Da dann für jede Sprache L ∈ N L auch L ≤L Path gilt, muss N L ⊆ co − N L gelten. Damit ist dann aber auch für jede Sprache L ∈ N L die Sprache L ∈ N L, woraus direkt N L = co − N L folgt. Damit ist gezeigt, dass N L = co − N L ⇔ Path ≤L Path. AUFGABE 5: a) Seien f, g : N → N mit f (n), g(n) ≥ n log n zeitkonstruierbar. Seien M1 , M2 O(f (n))- bzw. O(g(n))-zeitbeschränkte DTMen, die bei Eingabe 1n die Binärdarstellung von f (n) bzw. g(n) berechnen. i) zu zeigen: f + g ist zeitkonstruierbar Sei M eine 1-Band-DTM mit 2 Spuren, die wie folgt arbeitet: 1. Ersetze 1en der Eingabe durch Tupel [1,1] (d.h. 1 auf jeder Spur) 2. Simuliere M1 so, dass nur Spur 1, d.h. die ersten Werte der Tupel der Zeichen, genutzt wird 3. Simuliere M2 so, dass nur Spur 2, d.h. die zweiten Werte der Tupel der Zeichen, genutzt wird 4. Verschiebe kürzere der beiden Zahlen nach hinten und ergänze führende 0en, sodass beide Zahlen gleiche Länge haben 5. Addiere beide Zahlen und Schreibe Ergebnis anstelle der Tupel aufs Band 6. Akzeptiere M ist nach Konstruktion eine DTM, die bei Eingabe 1n die Binärdarstellung von f (n) + g(n) berechnet. Für die Berechnung von f (n) ist Zeit O(f (n)) nötig, für die Berechnung von g(n) Zeit O(g(n)). Da beide Zahlen Länge log(f (n)) bzw. log(g(n)) haben, können die führenden 0en in Zeit O(log(f (n)) · log(g(n)) ergänzt werden. Die Addition benötigt dann Zeit O(f (n)+g(n)). Da O(log(f (n))· log(g(n))) = O(f (n) + g(n)) benötigt M insgesamt Zeit O(f (n) + g(n)), d.h. f + g ist zeitkonstruierbar. ii) zu zeigen: f · g ist zeitkonstruierbar Sei M eine 1-Band-DTM mit 3 Spuren, die wie folgt arbeitet: 1. Ersetze 1en der Eingabe durch Tupel [1,1,1] (d.h. 1 auf jeder Spur) 2. Simuliere M1 so, dass Spur 1 den Wert 0 und Spur 2 jeweils den Wert erhält, der von M1 in die Zelle geschrieben würde 3. Simuliere M2 so, dass nur Spur 3, d.h. die dritten Werte der Tupel der Zeichen, genutzt wird 4. Wiederhole: Addiere binär Spur 1 und Spur 2, schreibe Ergebnis auf Spur 1, reduziere den Zähler auf Spur 3 um 1, bis Zähler auf Spur 3 Wert 0 erreicht. 5. Ersetze jede Zelle durch den ersten Wert des in der Zelle gespeicherten Tupels 6. Akzeptiere Die DTM addiert, beginnend bei 0, g(n) mal den Wert f (n), berechnet also offensichtlich f (n) · g(n). Schritt 1 benötigt dabei Zeit O(n). Die Simulation in Zeile 2 benötigt O(f (n)) Zeit. Die Simulation in Zeile 3 benötigt O(g(n)) Zeit. In Zeile 4 wird dann g(n) mal f (n) zur bisher berechneten Zahl addiert und ein Zähler der Länge O(log(g(n))) dekrementiert. Da insgesamt O(log(f (n)) + log(g(n))) Zellen für die Addition benutzt werden und jede Zelle in jedem Durchlauf nur einmal betrachtet wird, ist für Zeile 4 somit O(g(n) · (log(f (n)) + log(g(n)))) nötig. Zeile 5 benötigt schließlich Zeit O(log(f (n)) + log(g(n))). Insgesamt ist damit Laufzeit O(f (n) + g(n) · (log(f (n)) + log(g(n)))) = O(f (n) · g(n)) nötig. iii) zu zeigen: 2f ist zeitkonstruierbar Sei M eine 1-Band-DTM, die wie folgt arbeitet: 1. Simuliere M1 2. Schreibe 1# an den Anfang des Bandes und verschiebe restlichen Bandinhalt nach rechts 3. Wiederhole, solange Zähler hinter # größer als 0 ist: Ersetze # durch 0#, verschiebe restlichen Bandinhalt nach rechts, dekrementiere Zähler hinter # Die DTM berechnet zunächst die Binärdarstellung von f und schreibt dann 10f auf das Band. Dies ist offensichtlich die Binärdarstellung von 2f . Die Berechnung von f benötigt nach Voraussetzung Zeit O(f (n)). Anschließend wird f (n)-mal der Zähler mit log(f (n)) Stellen dekrementiert und um 1 Zelle nach rechts verschoben. Insgesamt ist dazu Zeit O(f (n) · log(f (n))) = O(2f (n) ) nötig, 2f also zeitkonstruierbar. iv) zu zeigen: g ◦ f ist zeitkonstruierbar Sei M eine 1-Band-DTM, die wie folgt arbeitet: 1. Simuliere M1 2. Bewege Kopf zum Anfang, schreibe eine # aufs Band und verschiebe den Rest um 1 Stelle nach rechts 3. Schreibe jeweils eine 1 an die Stelle der #, eine # rechts daneben, verschiebe den Rest rechts davon um 1 nach rechts und verringere diese Zahl um 1, bis 0 erreicht 4. Lösche die # 5. Gehe zum Anfang und simuliere M2 6. Akzeptiere Die DTM berechnet zunächst die Binärdarstellung von f (n) und ersetzt diese durch f (n) 1en. Anschließend wird die Binärdarstellung von g(f (n)) berechnet. Für die Simulation in Zeile 1 ist Zeit O(f (n)) nötig. Die Umwandlung der Binärzahl in eine unäre Zahl benötigt Zeit O(f (n) · log(f (n))). Die Simulation von M2 benötigt schließlich Zeit O(g(f (n))). Insgesamt ergibt sich damit eine Laufzeit von O(g(f (n)) + f (n) · log(f (n))). Da g(f (n)) ≥ f (n) log f (n) ist die Laufzeit damit O(g(f (n))), g ◦ f somit zeitkonstruierbar. b) Sei f eine beliebige zeitkonstruierbare Funktion. Dann benötigt die DTM M , die f berechnet, nur O(f (n)) Zeit. In jedem Schritt kann M aber nur eine Zelle des Bandes benutzen, also ist M insbesondere O(f (n))-platzbeschränkt. Da das Kopieren der Zahl n vom Eingabeband aufs Arbeitsband nur Platz O(n) = O(f (n)) und das Kopieren der Ausgabe aufs Ausgabeband keinen zusätzlichen Platz benötigt, ist f damit auch platzkonstruierbar.