• Keine Ergebnisse gefunden

Studientbrief 4: Endliche Automaten

4.4 Nichtdeterministische endliche Automaten

Wir haben schon in Kapitel 3 gesehen, dass es für schwierige (NP-vollständige) Probleme sehr elegante und schnelle nichtdeterministische Algorithmen geben kann. Wir wollen hier untersuchen, ob wir mit nichtdeterministischen endlichen Automaten mehr Sprachen erkennen können als mit deterministischen endlichen Automaten.

Eine zweite Frage ist, ob uns der Nichtdeterminismus hilft, reguläre Sprachen kürzer und damit effizienter zu beschreiben. Ein nichtdeterministischer endlicher Automat NFA, den wir auch nur für Entscheidungsprobleme untersuchen wollen, unterscheidet sich von einem DFA genauso, wie sich eine NTM von einer DTM unterscheidet. Die Überführungsfunktion wird durch eine Relation auf (Q x E) x Q ersetzt, die wir auch mit δ bezeichnen. Wir können δ auch als Abbildung von Q x in in die Potenzmenge von Q auffassen. Dann ist δδ(q, a) die Menge der Zustände q', so dass (q, a, q') in eS ist. Wie schon für DFAs wollen wir eS auf Q x E* fortsetzen. Es ist δ(q,E) = {q}. Für Wörter w mit |w| ≥ 2 soll δ(q,w) die Menge der Zustände sein, die nach dem Lesen von w erreicht werden können.

Damit ist für w = w'a mit a in E: δ(q, w) = Uq' in δ(q,w') δ(q', a).

Ein NFA A akzeptiert ein Wort w, wenn er nach dem Lesen von w in einem akzeptierenden Zustand sein kann, also wenn δ(q0, w) ∩ F ≠ {} ist.

An zwei Beispielen soll deutlich werden, dass es einfacher sein kann, für ein Problem einen NFA zu entwerfen als einen DFA zu konstruieren. Damit einhergehend ist eine exponentielle

Kompaktifizierung möglich.

Beispiel. Wir betrachten das stark eingeschränkte Rucksackproblem KP**. Wenn wir eine Zahl ai lesen, können wir nun nichtdeterministisch raten, ob wir ai brauchen, um A darzustellen. Der NFA sei definiert durch

Q = {0, 1, ... , A}, Σ = {1, ... , A}, q0 = 0, F = {A} und δ (q, a) = {q, q + a} ∩ Q.

Sei nun a = a1 ... an eine Eingabe aus KP** mit der Lösungsmenge I aus {1, ... ,n}.

Der NFA akzeptiert a auf folgende Weise. Wenn ai mit i nicht aus I gelesen wird, bleiben wir in dem erreichten Zustand q. Wird a_i mit i in I gelesen, wechseln wir in den Zustand q + ai. Am Ende sind

wir im Zustand A und akzeptieren a. Wenn wir andererseits die Eingabe a akzeptieren, erhalten wir eine Lösung für das KP**, wenn wir I als Menge aller i wählen, so dass wir nach dem Lesen von ai den Zustand gewechselt haben. Dieser NFA hat nur A+ 1 Zustände, während der DFA aus dem Beispiel 2A Zustände hatte.

Beispiel. Das einfachste Problem aus der Mustererkennung ist das String Matching Problem. Für einen festen String s = s1 ... sk in Σ* soll für ein Muster m = m1 ... mn in Σ* entschieden werden, ob m den String s enthält. Ein NFA mit nur k + 1 Zuständen lässt sich leicht angeben.

Eine Kante mit der Markierung Σ bedeutet, dass dieser Übergang für jedes a in Σ möglich ist. Der NFA rät also, wo der String s beginnt, verifiziert dann, dass s tatsächlich in m enthalten ist, und wartet dann das Ende des Wortes ab. Knuth, Morris und Pratt (1977) haben diesen NFA als Ausgangspunkt gewählt, um einen effizienten, deterministischen Algorithmus für das String Matching Problem zu entwerfen.

Satz. Sei Ln die Menge aller Wörter über {0, 1}, bei denen der n-letzte Buchstabe eine 1 ist. Dann gilt:

i) Es gibt einen NFA für Ln mit n+ 1 Zuständen.

ii) Jeder DFA für Ln hat mindestens 2n Zustände.

Beweis.

i) Die Konstruktion dieses NFA ist ähnlich zu der Konstruktion im obigen Beispiel. Es ist einfach zu sehen, dass dieser NFA genau die Sprache L_n akzeptiert.

ii) Es genügt nach dem Satz von Nerode zu zeigen, dass alle Wörter aus {0,1}n nicht Nerode-äquivalent sind. Seien x, y in {0,1}n mit x ≠ y. Dann gibt es ein xi ≠ yi, O. B. d. A. xi = 0 und yi = 1.

Es gilt x0i - 1 nicht in L, da x_i der n-letzte Buchstabe von x0i - 1 ist, und y0i - 1 in L. Damit sind x und y nicht äquivalent bezüglich RL_n. Es folgt ind(RL_n) ≤ 2n .

Wir haben gesehen, dass nicht deterministische endliche Automaten mächtige Hilfsmittel sind.

Vielleicht sind sie jedoch zu mächtig und können mehr als deterministische endliche Automaten.

Dies ist nicht der Fall. Die Sprachen L_n bilden im Wesentlichen worst case Beispiele.

Algorithmus (Potenzmengenkonstruktion)

Eingabe: NFA A, beschrieben durch Q,Σ,q0, δ und F.

Ausgabe: DFA A', der die gleiche Sprache L wie A akzeptiert.

Der DFA A' enthält als Zustandsmenge Q' die Potenzmenge von Q, also ist |Q'| = 2^|Q|. Nach dem Lesen von w soll A' in dem Zustand δ(q_0, w) sein, der für A eine Menge von Zuständen darstellt.

Daher setzen wir Σ' = Σ, q'0 = {q0} und F' = {q' in Q' | q' geschnittten F ≠ {}}. Schließlich sei δ'(q', a) = U_q in q' δ(q, a).

Um zu zeigen, dass A' ebenfalls die Sprache L akzeptiert, genügt es, δ'(q'0, w) = δ(q0, w) für w in Σ*

nachzuweisen. Diesen Beweis führen wir mit Induktion über |w|.

Für |w| = 0 ist w = ε und δ'(q'0,ε) = q'0 = {q0} = δ(q0,ε).

Für w = w'a gilt mit Hilfe der Induktionsvoraussetzung

δ'(δ'(q_h, w'), a) = δ'(δ(q0, w'), a) = Uq in δ(q_0,w') δ(q, a) = δ(q0, w).

Satz. Zu jedem NFA mit n Zuständen gibt es einen äquivalenten DFA mit 2n Zuständen.

Der Algorithmus ist effizient, wenn wir die Laufzeit auf die Größe der Ausgabe 2|Q| |Σ| beziehen. Zur Berechnung jedes der 2|Q| |Σ| Funktionswerte von δ' genügt es nämlich, höchstens |Q| viele höchstens

|Q|-elementige Mengen zu vereinigen. Um aus einem NFA einen äquivalenten, minimalen DFA zu konstruieren, genügt es, die drei folgenden Schritte auszuführen.

1.) Potenzmengenkonstruktion.

2.) Eliminierung der überflüssigen Zustände.

3.) Minimierung

Jeder der drei Schritte ist effizient durchführbar, wenn wir die Rechenzeit auf die jeweilige Ein- und Ausgabegröße beziehen. In der Praxis kommen NFAs mit Hunderten oder sogar mehr als tausend Zuständen vor, zum Beispiel bei Fluglinien zur Identifikation von Passagiernamen. In diesem Fall ist die Potenzmengenkonstruktion aus Ressourcengründen schlicht undurchführbar. Dies gilt auch dann, wenn ein minimaler äquivalenter DFA vertretbare Größe hat. Wir suchen also nach effizienten Algorithmen, die möglicherweise die drei Schritte, die wir oben beschrieben haben, integrieren. Für alle drei Schritte gelingt dies nicht, wohl aber für die ersten beiden Schritte. Wir konstruieren den gleichen DFA wie in der Potenzmengenkonstruktion, nur vermeiden wir die Betrachtung der überflüssigen Zustände.

Algorithmus (Potenzmengenkonstruktion unter Vermeidung überflüssiger Zustände)

Wir benutzen eine Queue Q* zur Speicherung der erzeugten, aber nicht verarbeiteten Zustände und ein Dictionary D (zum Beispiel einen 2-3-Baum) als Nachschlagewerk für die bereits erzeugten Zustände. Q* und D werden mit qh = {q0} initialisiert.

Solange Q* nicht leer ist, wird der erste Zustand q' aus Q* verarbeitet. Wie beschrieben, werden für a in Σ die Zustände δ'(q', a) berechnet. Jeder Zustand δ'(q', a) wird darauf getestet, ob er bereits in D enthalten ist. Wenn dies nicht der Fall ist, wird er in Q* und D eingefügt.

Nach Konstruktion ist unmittelbar klar, dass wir die Breitensuche so mit der

Potenzmengenkonstruktion verbunden haben, dass wir nur die nicht überflüssigen Zustände erzeugen. Da D nicht mehr als 2^|Q| Zustände enthalten kann, ist die Suche in D in Zeit O(|Q|) ebenso möglich wie das Einfügen. Insgesamt ist die Rechenzeit um nicht mehr als den Faktor O(|Q|

^2) größer als die Beschreibung des berechneten DFA. Es kann gehofft werden, dass dieser DFA wesentlich kleiner als der bei der Potenzmengenkonstruktion entstehende DFA ist. Der einzige für uns schlechte Fall ist der, dass wir aus einem kleinen NFA immer noch einen großen DFA erzeugen und der äquivalente minimale DFA wieder klein ist. Wenn der äquivalente minimale DFA selbst sehr groß ist, ist die Rechenzeit bezogen auf die notwendige Größe der Ausgabe in jedem Fall klein.

Für einen NFA mit 200 Zuständen brauchen wir mit der Potenzmengenkonstruktion gar nicht erst anzufangen, während wir mit neuen Algorithmus zumindest die Hoffnung verbinden können, in vernünftiger Zeit zu einem äquivalenten DFA zu kommen.

Das Ergebnis lässt sich auch so interpretieren, dass die Ausdruckskraft von endlichen Automaten recht robust gegen Modifikationen des Automatenmodells ist. Diese These wollen wir weitere Automatenmodelle untermauern.

Bisher können NFAs beim Lesen eines Buchstabens einen von eventuell mehreren möglichen Übergängen raten. Wir wollen nun auch Übergänge, ohne dass ein Buchstabe gelesen wird, ermöglichen. Formal können wir uns vorstellen, dass wir in das Eingabewort w beliebig viele ε-Einträge einfügen dürfen. Bei der Abarbeitung rät der Automat die Zahl der "ε-Buchstaben" und behandelt dann in wie einen normalen Buchstaben.

Definition. Bei einem NFA A mit ε-Übergängen ist die Übergangsfunktion eine Funktion δ von Q x (Σ {ε}) in die Potenzmenge von Q. Der Automat A akzeptiert eine Eingabe w genau dann, wenn ∪ es einen akzeptierenden Rechenweg gibt, wobei q' in δ(q, ε) bedeutet, dass A, ohne einen

Buchstaben zu lesen, vom Zustand q in den Zustand q' wechseln darf.

Die Option, ε-Übergänge benutzen zu dürfen, kann den Entwurf von NFAs erleichtern. Andererseits ist die Erweiterung um E- Übergänge nicht so gravierend, dass uns der folgende Satz überraschen könnte.

Satz. Zu jedem NFA A mit ε-Übergängen gibt es einen äquivalenten NFA A' ohne ε-Übergänge, der nicht mehr Zustände als A hat. Dabei kann A' in Zeit O(|Q| |δ|) konstruiert werden, wobei |δ| die Summe aller |δ(q,a)|, a in Σ {ε} und q in Q, ist.∪

Beweis. A' übernimmt von A die Zustandsmenge und den Anfangszustand. Die Übergangsfunktion wird folgendermaßen definiert. Es soll δ'(q, a) für a in Σ genau die Zustände enthalten, in die A aus q mit i ε-Übergängen und dem anschließenden Lesen von a gelangen kann. Für Wörter w in Σ* - {ε} gilt dann offensichtlich für die Fortsetzung von δ' auf Σ* -{ε}, dass δ(q, w) genau die Zustände enthält, die in A auf folgende Weise erreicht werden können: einige ε-Übergänge, ein Übergang, in dem w1 gelesen wird, einige ε-Übergänge, ... , ein Übergang, in dem der letzte Buchstabe wn von w gelesen wird. Darüber hinaus ist δ' (q, ε) = {q}, da A' keine ε-Übergänge gestattet.

Mit δ' haben wir das Verhalten von A nachgeahmt. Der Automat A darf nach dem Lesen des letzten Buchstabens von W noch weitere ε-Übergänge durchführen. Daher definieren wir F', die Menge akzeptierender Zustände von A', als Menge aller Zustände q, von denen aus A mit ε-Übergängen in einen akzeptierenden Zustand q' in F gelangen kann. Damit sollte klar sein, dass A' die gleiche Sprache wie A akzeptiert.

Wir kommen nun zur Rechenzeit für die Konstruktion von A'. Dazu betrachten wir den gerichteten Graphen G, der die Zustände von A als Knoten und die ε-Übergänge als Kanten enthält. Für jeden Zustand berechnen wir mit einer Depth First Suche die Menge der durch ε-Übergänge erreichbaren Zustände. Hierbei erhalten wir als Nebenprodukt die Menge F' akzeptierender Zustände. Die Rechenzeit für die Depth First Suchen können wir durch O(|Q| |δ|) abschätzen. Verbesserungen an dieser Stelle, zum Beispiel durch die Berechnung starker Zusammenhangskomponenten, wirken sich nicht auf die Gesamtrechenzeit aus, da wir für den zweiten Teil des Algorithmus eine

Rechenzeit von Theta(|Q| |δ|) verbrauchen. Für die O(|δ|) Tripel (q', q", a) mit a in Σ und q' in δ(q", a) und alle Zustände q in Q überprüfen wir, ob q" von q aus mit ε-Übergängen erreichbar ist. Im positiven Fall wird q' in δ(q, a) eingefügt.

4.5 Effiziente Algorithmen für die Konstruktion endlicher