Dienstag, 24. Februar 2009Datenbanks-MeinungsupdateMeine Erfahrungen mit Datenbanken beschränken sich auf die für Informatiker üblichen: Ein gutes dutzend privater Projekte, wo man mal eine Datenbank benutzt (Django, Rails etc). Intensive Nutzung diverser Programme, die Datenbanken benutzen (Amarok, mythtv). Und natürlich die unvermeidliche Datenbank-Vorlesung. In der echten Welt, da wo man tatsächlich professionelle Anwendungen baut, hatte ich bisher keine Erfahrungen. In meinem aktuellen Job musste ich mich in den letzten Wochen intensiv mit gleich fünf verschiedenen Produkten auseinandersetzen. Dabei handelt es sich um Views und Select-Statements mit einer zweistelligen Anzahl von Substatements und Zeilen, eine durchaus anspruchsvolle Aufgabe für die Programme also. Ohne ins Details zu gehen, hier ist was ich gelernt habe:
Ab jetzt Postgre für private Projekte, Oracle für professionelle.
Datenbanks-Meinungsupdate Geschrieben von Turing
in Informatik um
15:56
Kommentare (0) Trackbacks (0) Freitag, 31. Oktober 2008Multitouch at workÄußerst cool: Mein Bruder und sein Kollege Ali benutzen ihr selbstentwickeltes Multitouch um Spiele zu spielen. Wenn das mal kein René-würdiges Gadget ist.
Multitouch at work Geschrieben von Turing
in Games, Informatik um
08:31
Kommentare (0) Trackbacks (0) Freitag, 24. Oktober 2008Mal ein bisschen SpieltheorieDieses Blog braucht dringend mehr Input. Das meiste was ich zu erzählen hätte, bräuchte leider eine längere Vorbereitung, scheitert aus Zeitgründen oder interessiert schlicht kein Schwein. Einen kleinen (für mich) interessanten Fakt aus der Spieltheorie habe ich aber doch loszuwerden. Wenn wir von einem nicht kooperativem Zwei-Personen-Spiel mit perfekter Information reden, ist ein Spiel gemeint, wo zwei Spieler jeweils alle Züge des Spielers sehen können. Schach ist zum Beispiel ein Spiel mit perfekter Information, Poker dafür nicht. Bei kooperativen Spielen können sich Spieler untereinander absprechen, um vielleicht einen Vorteil für beide Spieler zu erwirken. Eine weitere Eigenschaft von Zwei-Personen-Spielen ist, dass der Gewinn von Spieler A direkt der Verlust des Spielers B ist. Deshalb spricht man von einer "Auszahlung" am Ende eines Spiel, die positiv oder negativ sein kann. Eine Auszahlung von "10" würde bedeuten, Spieler A gewinnt 10, B verliert dafür 10. Umgekehrt gewinnt B bei Auszahlung "-10" und A verliert. Nehmen wir mal ein Spiel an, das aus Anschaulichkeitsgründen so einfach wie möglich ist. Spieler A wählt einmal, Spieler B wählt danach und dann ist A noch einmal dran. Am Ende wartet irgendein Auszahlungsschema, das nicht besonders viel Sinn macht, aber ich bin ja auch kein Spieleerfinder. Konkret sieht das Spiel so aus, als Baum dargestellt:
Ein Beispiel: Sagen wir A wählt im ersten Zug die 2, B wählt 1 und A wählt noch einmal 1. Damit hätte A "2" gewonnen. Ganz offensichtlich gibt es begrenzt viele Aktionen, die die Spieler überhaupt ausführen können. Jeden "gesamten Spielablauf" aus der Sicht eines einzelnen Spielers bezeichnet man als "Strategie", zum Beispiel könnten wir es (2,2) nennen, wenn A im ersten und dritten Zug die "2" wählt. Zählen wir mal durch, wie viele Strategien A hat: A1: Wähle (1,1) unabhängig von B's Zug Außerdem gibt es natürlich weitere 4 Strategien, wenn A im ersten Zug 2 wählt. B hat weniger Strategien:
Wenn man das alles jetzt "normalisiert" darstellt, schreibt man die Strategien an eine Matrix und schreibt an die Schnittstellen die Auszahlung. Ungefähr so:
Als Beispiel: Sagen wir A wählt Strategie 3, B wählt 4. Damit zieht A "1", B wählt das Gegenteil (wegen seiner Strategie), also 2. Die Strategie für A wiederum sagt, dass A jetzt 2 zieht. Damit ist die Auszahlung -1, was man in der Matrix bei A3xB4 wieder findet. Kleine Bemerkung am Rande: Dass die Matrix in diesem Fall so symmetrisch aussieht hat damit zu tun, dass das Spiel so extrem simpel ist. Schon wenn man für jeden Zug drei Wahlmöglichkeiten zulässt, sieht die Matrix schon deutlich anders aus. Allerdings steigt die Anzahl der Strategien dann auch deutlich und es wird schnell unübersichtlich. Jetzt lassen sich ein paar interessante Beobachtungen anstellen. Zum Beispiel kann B nicht gewinnen, wenn A keinen groben Fehler macht. Egal, was B macht, immer kann A im letzten Zug zumindest ein Unentschieden sichern. Deshalb wäre die rationale Entscheidung für B, die Strategie B2 zu wählen. Denn wenn A 1 wählt, kommt B mit einer "0" raus, wann A am Anfang 2 zeiht, verliert B wenigstens nur mit einer 1. Es ist spät geworden, und der Punkt auf den ich hinaus will, ist nicht mehr wahnsinnig weit entfernt, aber doch weit genug als bis zum Wochenende warten zu müssen. Immer unterschätze ich die Zeit, die ich dafür brauche, Bilder zu malen und Beispiele zu erfinden.
Mal ein bisschen Spieltheorie Geschrieben von Turing
in Informatik um
21:35
Kommentare (0) Trackbacks (0) Sonntag, 20. Juli 2008Kantenerkennung mit SobelEine beliebte Anwendung in der Bildverarbeitung ist die Kantenerkennung. Das kann man benutzen um automatisiert Dinge zu erkennen, zum Beispiel in Maschinen. Ein beliebtes Verfahren zur Kantenerkennung ist der Sobel-Operator. (Den ich letztens mal aus anderen Gründen implementieren musste, deshalb wird das hier jetzt auch verwurstet.) Zu Demonstrationszwecken nehme ich mir einfach mal ein Bild von Flickr von "Linda&Larry", das unter der CC Lizenz steht. Das Bild wird jetzt mit einer Matrix gefaltet, allerdings nicht ganz traditionell. Vielmehr wird die Matrix zentriert "auf das Bild gelegt". Es geht konkret um diese beiden Matrizen: Diese werden jetzt wie gesagt auf die Bilder "gelegt". Nehmen wir mal der Einfachheit halber an, dass wir ein Schwarz-Weiß Bild haben, das bedeutet, dass jeder Pixel mit einem Grautonwert von 0-255 darstellbar ist. Nehmen wir weiter an, dass die Pixel oben links im Bild etwa so aussehen:
Das ganze kann natürlich Werte >255 produzieren, aber auch, wie hier, negative Werte. Deshalb muss das ganze normalisiert werden. Dazu müssen wir die maximalen und minimalen Werte des Bildes berechnen und den Pixel Die beiden resultierenden Bilder sehen dann so aus: Wie man sieht, haben die beiden Bilder so eine Art "Richtung". Um daraus jetzt ein einziges Kantenbild zu machen, kombiniert man diese beiden Bilder mit der Formel Und dann kommt dieses Kantenbild heraus:
Kantenerkennung mit Sobel Geschrieben von Turing
in Informatik um
09:49
Kommentare (2) Trackbacks (0) Dienstag, 18. Dezember 2007Das HalteproblemMit frischer Motivation wegen des neuen Servers ausgestattet kommt heute die Serie über Entscheidbarkeitstheorie zu Ende. Viel ist es jetzt nicht mehr, keine Sorge. Bis jetzt haben wir gesehen, dass die Diagonalsprache Daraus lässt sich jetzt trivial etwas über das Komplement der Diagonalsprache Und jetzt können wir endlich das Halteproblem bearbeiten. Die Definition ist folgende: Die Eingabe ist also eine beliebige Gödelnummer kombiniert mit einer beliebigen Eingabe. Die TM für H soll entscheiden, ob die Gödelnummer auf der angegebenen Eingabe hält. Die Beweistechnik ist die selbe wie vorher. Wir erfinden einen Algorithmus, der - Finde i mit - Erstelle - Die TM - Lasse das H-Orakel <M>w entscheiden. Wenn das H-Orakel "<M>w hält" entscheidet, lassen wir die TM für
Donnerstag, 22. November 2007Die Diagonalsprache
Obwohl ich im Moment echt durch den Wind bin, fühle ich irgendwie die Verpflichtung, hier auch mal wieder etwas substantielles zu schreiben, auch wenn es wahrscheinlich weniger umfangreich wird als sonst. Es geht mal wieder um das Halteproblem, heute machen wir einen weiteren (und letzten) Zwischenschritt, um danach endlich das Halteproblem anzugehen. Zunächst brauchen wir dafür die so genannte kanonische Ordnung. Das ist eine spezielle Sortierung von Bitstrings (also eine Ordnung auf {0,1}*). Dabei steht ein Wort w vor einem anderen Wort w', wenn: Anders gesagt wird zuerst nach Länge des Wortes, dann erst nach lexikographisch Ordnung sortiert. Kürzeste Worte kommen also zuerst, inklusive dem leeren Wort: Jetzt überlegen wir uns eine Matrix, wobei die Zeilen mit Turingmaschinen Die Matrix ist natürlich unendlich, denn sowohl die Anzahl der Wörter als auch die Menge der Gödelnummern hört nie auf. Jetzt kommt an eine Schnittstelle von Turingmaschine und Wort jeweils eine 0 oder eine 1, je nachdem ob die Turingmaschine das Wort akzeptiert oder nicht.
In diesem Fall würde die Turingmaschine So weit so gut, aber was soll all der Blödsinn? Stellen wir uns vor, wir hätten eine Sprache, die immer falsch rechnet. Diese wäre mal ganz sicher nicht rekursiv, wir bräuchten uns nicht einmal Gedanken machen, wann sie unendlich läuft oder nicht definiert ist. So eine Sprache ist die so genannte Diagonalsprache: Informell gesagt ist das die Sprache, die alle Wörter enthält, die die zugehörige Turingmaschine nicht akzeptiert. Die zugehörige Turingmaschine ist natürlich die, die in der korrespondierenden Zeile steht. Und damit ist D die Sprache, die alle Nullen auf der Diagonale dieser Matrix enthält. Das führt zu einem ziemlich üblen Widerspruch. Die Annahme ist, dass die Sprache rekursiv ist. Das heißt, dass es eine TM gibt, die auf allen Eingaben hält und genau D akzeptiert. Nennen wir diese TM einfach Das bedeutet, dass das zu 2)
Wie man sieht führen beide Fälle zum Widerspruch, keine Turingmaschine kann damit D akzeptieren und rechnet dabei immer richtig. Die Sprache ist damit definitiv nicht rekursiv. Das kann man benutzen um die nichtrekursivität des Halteproblems zu beweisen, das wird aber erst im nächsten Beitrag passieren. Mittwoch, 31. Oktober 2007Turing-berechenbare Funktionen und die Churchsche TheseEs fällt auf, dass Turingmaschinen, die ein Entscheidungsproblem berechnen am Ende immer entweder eine Null oder eine Eins auf dem Band stehen haben. Man könnte sagen, die Turingmaschine "entscheidet eine Sprache" in dem Sinne, dass sie für jedes Wort, das man auf das Band schreibt, entweder true (Wort gehört zur Sprache) oder false (Gehört nicht zur Sprache) ausgibt. Ein einfaches Beispiel hilft vielleicht.
Das sind alle Zustandsübergänge für Bleibt der letzte Zustandsübergang, nämlich wenn ein B im Zustand Die Turingmaschine verwirft also alle Worte, die ein "b" enthalten und akzeptiert alle, die nur aus "a" bestehen. (Bonusfrage: Was ist mit dem leeren Wort? Antwort: Wird auch akzeptiert.) Als Sprache ausgedrückt hieße das übrigens L={ a* }, wobei * den kleenschen Abschluss darstellt, was im Grunde nur "beliebige Anzahl" bedeutet. Und das ist in der Tat eine starke Verbindung zwischen zwei unterschiedlichen Feldern. Eine TM im Entscheidungsmodus und eine Sprache sind ein und dasselbe. Man kann eine Sprache definieren und eine Turingmaschine bauen, die für jedes Wort der Eingabe "1" ausgibt. Umgekehrt gilt das natürlich auch, denn wenn uns jemand eine Turingmaschine gibt, können wir gucken was die für Wörter akzeptiert und uns eine entsprechende Sprache überlegen. Es sind zwei Seiten einer Medaille: Sprachen sind mehr der konstruktive Teil, man will *aktiv* eine Menge von Wörtern generieren und überlegt sich, wie das geht. Die Turingmaschine generiert nichts, sie entscheidet lediglich, ob ein Wort zur Sprache gehört oder nicht. Wir nähern uns unaufhaltsam dem eigentlichen Thema, denn jetzt kann man sich natürlich überlegen, ob es wirklich für jede Sprache eine entsprechend richtig entscheidende Turingmaschine gibt. Dafür definiere ich das ganze nochmal etwas mathematischer. Zu einer beliebigen Sprache L gibt es eine so genannte charakteristische Funktion Eine Funktion f heißt Turing-berechenbar, falls sie überall definiert ist und falls f von einer TM berechnet werden kann. Dabei muss die TM bei allen Eingaben halten und am Ende wie gefordert 0 oder 1 auf dem Band stehen haben. Eine Sprache L wird Turing-berechenbar genannt, falls die zugehörige Funktion Rekursiv ist eine Funktion übrigens auch, wenn die entscheidende Turingmaschine nur dann rechnet, wenn die Eingabe aus dem Definitionsbereich ist. Zum Beispiel macht ein Sortieralgorithmus für Ganzzahlen nur für ganzzahlige Eingaben Sinn. Wenn man da einfach ein paar Strings eingeben würde, dürfte die TM formell unendlich weiter rechnen (weil Turingmaschinen keine Exceptions kennen). Trotzdem wäre dieses Verhalten rekursiv. Dann gibt es noch eine letzte wichtige Klasse von Sprachen, die man "rekursiv aufzählbar" nennt. Ich verzichte mal auf eine formale Definition, denn der Unterschied ist auch so leicht zu verstehen. Die TM akzeptiert jedes Wort der Sprache nach wie vor in endlicher Zeit, wenn das Eingabewort aber nicht zur Sprache gehört, rechnet die TM unendlich. Man, das war lang und langweilig. Damit sind die Vorbereitungen aber endlich abgeschlossen und wir können bald endlich über das Halteproblem sprechen. Bleibt nur noch ein Wort über die Church-Turing-These zu verlieren. Diese geht nämlich so: "Die Klasse der Turing-berechenbaren Funktionen ist genau die Klasse der intuitiv berechenbaren Funktionen." Was eine Turing-berechenbare Funktion ist, wissen wir ja jetzt. "Intuitiv berechenbare Funktionen" können dagegen nicht so schön definiert werden, man versteht darunter mehr oder weniger alle Funktionen die wir Menschen uns so ausdenken können. Alles was wir Menschen im Prinzip ausrechnen könnten. Sind das nicht *alle* Funktionen, die es gibt? Vermutlich ja, zumindest ist es schwer sich vorzustellen, was es für Funktionen geben könnte, die wir uns nicht ausdenken können. Das liegt aber irgendwie in der Natur der Sache, denn wie sollten wir uns diese Funktionen wohl ausdenken können, wenn es gerade deren Eigenschaft ist, nicht von uns erdacht werden können? Die These besagt also, dass Computer keine Lücken in ihrer Rechenkraft haben. Alle Dinge die wir entscheiden können, können auch Computer entscheiden. Aber sind alle Computer gleich mächtig? Das sagt uns zumindest die (ebenfalls nicht beweisbare) erweiterte Chruchsche These: "Für je zwei Rechnermodelle R1 und R2 gibt es ein Polynom p, so dass t Rechenschritte auf Modell R1 bei Eingabe der Länge n durch p(t,n) Rechenschritte auf Modell R2 simuliert werden können." Die Umrechnung von einem auf den anderen Computer soll also maximal in Polynomialzeit machbar sein, was uns Theoretikern zur Zufriedenheit reicht.
Turing-berechenbare Funktionen und ... Geschrieben von Turing
in Informatik um
20:49
Kommentare (0) Trackbacks (0) Mittwoch, 24. Oktober 2007Wolframs 2,3 TM ist universell!Ich glaubs ja kaum. Stephen Wolfram hat 2004 eine Turingmaschine entworfen und 25000$ für einen Beweis ausgelobt, der die Universalität entscheidet. Heute, am gleichen Tag an dem ich zufällig meinen Beitrag über Universelle Turingmaschinen geschrieben habe kommt das rein: Wolfram's 2,3 Turing Machine Is Universal! (Beweis) Damit ist es die kleinste bekannte universelle Turingmaschine. Hier gibts technische Details.
Wolframs 2,3 TM ist universell! Geschrieben von Turing
in Informatik um
18:25
Kommentare (0) Trackbacks (0) Tags für diesen Artikel: entscheidbarkeitstheorie, informatik, tm, turing-maschine, universelle turingmaschinen, utm
Mittwoch, 24. Oktober 2007Universelle TuringmaschinenVielleicht erinnert sich noch jemand, dass ich in grauer Vorzeit mal eine Serie über Automatentheorie gestartet habe, mit dem Ziel, irgendwann zur Entscheidbarkeitstheorie zu gelangen. Der Grund, warum ich das nie weitergeführt habe ist, dass ich Automatentheorie nicht besonders spannend finde. Also überspringe ich den langweiligen Teil, komme direkt wieder zu Turingmaschinen und schreibe vielleicht später einen Beitrag über Automatentheorie mit einem eher zusammenfassenderen Charakter. Entscheidbarkeitstheorie also. Die meisten Probleme sind ja irgendwie durch eine konkrete Fragestellung motiviert. Hier ist diese Frage, welche Funktionen entschieden werden können und welche nicht. Ich werde noch darauf kommen was das im Detail bedeutet. Erstmal führen wir eine neue Art Turingmaschine ein, die wir später brauchen. Eine Turingmaschine, nennen wir sie M, ist ja folgendermaßen definiert: Dabei ist Q die Menge der Zustände und q0 identifiziert den Startzustand. So eine gewöhnliche Turingmaschine hat einen gewaltigen Nachteil. Sie ist mit der formalen Definition bereits vollständig programmiert. Und zwar endgültig. Viel schöner und vertrauter wäre es doch, wenn eine Turingmaschine nur die "Hardware" zur Verfügung stellen würde und wir das Programm auf das Band schreiben könnten, genau wie wir das bei normalen Computern tun. Da schreiben wir das Programm auf die Festplatte (genauer gesagt in den Bootsektor) und von da aus guckt unser Computer nur, welches Programm an der richtigen Stelle der Festplatte zur Ausführung bereit liegt. Man stelle sich vor, wir würden für jeden auszuführenden Algorithmus einen neuen Prozessor kaufen und dem nur die Instanzen füttern. Ein Sortierprozessor zum Beispiel, dem wir nur Ganzzahlen zum Sortieren geben könnten, oder ein "Fülle-den-Cache-mit-Daten-Prozessor". Im echten Leben mutet das absurd an, aber so machen es klassische Turingmaschinen und für die Theorie kann man das auch tun. Aber es geht eben auch anders, und das nennt man eine "universelle Turingmaschine", kurz UTM, noch kürzer U. Diese kann ein beliebiges Programm (bzw. eine andere, normale Turingmaschine M) ausführen. Die Eingabe besteht jetzt nicht mehr aus einem Wort w, sondern aus (<M>w). Dabei ist w nach wie vor das zu bearbeitende Wort, neu ist <M>, die so genannte Gödelnummer der zu simulierenden Turingmaschine M. Man kann jede normale TM in eine lange Zahl codieren, die dann wiederum eindeutig ist. Zu jeder Gödelnummer gehört genau eine Turingmaschine. Diese Nummer wiederum gibt man dann als Eingabe an die UTM, die dann die zur Gödelnummer zugehörige TM simuliert. Diese Codierung funktioniert so:
Keine Erklärung nötig soweit? Doch? Na gut. Zuerst transferieren wir das Bandalphabet (hier oBdA {0,1,B}) in Und das ist ja schließlich unser Ziel gewesen. Nun, die universelle TM hat allerdings auch nur ein {0,1} Alphabet, deshalb notiert man einen einzelnen Zustandsübergang so: Jetzt dienen die Einsen als "Trenner" für eine Anzahl von Nullen, die mit dem ursprünglichen Zustandsübergang korrespondiert. Ein alter Übergang Wo wir uns jetzt diese ganze Arbeit gemacht haben, können wir damit endlich wieder auf die Gödelnummer zurück kommen. Die sieht jetzt nämlich so aus: 111 code(1) 11 code(2) 11 ... 11 code(n-1) 11 code(n) 111 Drei Einsen markieren also Start und Ende der Gödelnummer, zwei Einsen trennen zwei Codierungen für die Übergänge. Das Ziel ist erreicht, die Turingmaschine wird in einer langen, langen Nummer notiert, die offensichtlich auch wieder in die entsprechende Maschine zurück rechnen lässt. Wenn wir jetzt eine solche Gödelnummer, zusammen mit dem zu entscheidenden Wort an die UTM übergeben, kann diese Schritt für Schritt die Gödelnummer lesen, den neuen Zustand (und damit die neue Position in der Gödelnummer) berechnen und am Ende entscheiden, ob das Wort akzeptiert wird oder nicht. Wie das genau funktioniert wollt ihr nicht wissen, die Gödelnummerkonstruktion war ja schon etwas unheimlich. Nur so viel: Man kann Turingmaschinen auch mit mehreren Speicherbändern definieren. Davon nehmen wir uns in diesem Fall drei, schreiben die zu simulierende Gödelnummer auf das erste, das Wort auf das zweite und auf das dritte kommt der aktuelle Zustand der zu simulierenden TM. Dann wird die Programmierung der UTM zwar weniger hässlich, aber nicht viel. Bleibt die Frage nach der Rechenzeit. Wenn man sich die Rechenoperationen der UTM allerdings genau anschaut, wird schnell klar, dass die aufwändigste Operation die Suche nach der neuen Position in der Gödelnummer ist. Die UTM ist damit nur konstant langsamer als die ursprüngliche TM, hier droht also keine exponentielle Gefahr, außer die ursprüngliche TM war eh schon exponentiell langsam. So weit, so gut. Wir haben gesehen, dass man eine TM auch als lange Nummer schreiben kann. Außerdem gibt es offensichtliche eine universelle Turingmaschine, die mit dieser Nummer und dem zu entscheidenden Wort diese TM simulieren kann. Benutzen kann man das für... ääh... eigentlich kann man das nicht benutzen. Man braucht es lediglich später für einen wichtigen Beweis. Ist theoretische Informatik nicht schön? Wer hier aber dringend eine "Auflösung" braucht, der kann sich ja damit behelfen, dass die UTM offenbar eine praxisnähere Version von Turingmaschinen darstellt, denn man kann sie (auf aufwändige Art und weise) programmieren und muss sich nicht für jeden Algorithmus eine neue Turingmaschine kaufen. Gott sei dank. Update: Übrigens..
Universelle Turingmaschinen Geschrieben von Turing
in Informatik um
07:49
Kommentare (0) Trackbacks (0) Tags für diesen Artikel: entscheidbarkeitstheorie, halteproblem, informatik, tm, turing-maschine, universelle turingmaschinen, utm
Montag, 15. Oktober 2007Ach was solls..Ich bin eher der Typ, der einmal liegengelassene Sachen nie, nie, NIE wieder anpackt. Deshalb habe ich den Comic vom letzten Beitrag wenigstens soweit fertig gemalt, dass man wenigstens etwas erkennen kann. Ich kann es wirklich besser, aber irgendwie habe ich den Ehrgeiz gerade nicht. (Creative Commons by-nc)
Ach was solls.. Geschrieben von Turing
in Informatik, Sonstiges um
23:18
Kommentare (0) Trackbacks (0) Dienstag, 21. August 2007Die größten Informatiker aller ZeitenIch kam gestern von einer Party wieder, wo ich mich zugegebenermaßen etwas betrunken habe. Zum Glück habe ich da einen Physiker gefunden, mit dem ich diskutieren konnte ohne als Fachidiot zu gelten. Dieser Physiker hielt Einstein für komplett überschätzt und nominierte den Erfinder der M-Theorie als Nummer eins. (Ich habe den Namen gerade vergessen, was die M-Theorie ist, bleibt dem interessierten Leser nachzuschlagen. Möglicherweise unter dem Thema "Stringtheorie"). Ich bin in Physik nicht gebildet genug um so etwas entschieden zu können. Was ich aber beurteilen kann, ist die Informatik-Szene. Ich habe den gesamten Heimweg über die Frage nachgedacht, wer der größte Informatiker sein könnte und bin bei folgender Liste angekommen: 1. Alan Turing 2. Kurt Gödel (nicht im strengen Sinne Informatiker, aber irgendwie einflussreich) 3. John von Neumann 4. Donald Knuth 5. Dijkstra Auf den Plätzen folgen für mich Karp, Wirth, Hoare, Cook und Cocke. Gibt es andere Meinungen?
Die größten Informatiker aller Zeiten Geschrieben von Turing
in Informatik um
08:49
Kommentare (2) Trackbacks (0) Donnerstag, 16. August 2007Kontextfreie Sprachen und die BNFEin spezieller Typ formaler Sprachen sind die so genannten kontextfreien Sprachen. Sie sind auch die praxisrelevantesten und deren Konstruktion sieht irgendwie am natürlichsten aus, deshalb fange ich mit ihnen an. Um kontextfreie Sprachen zu beschreiben benutzt man oft die Backus-Naur Form. Das ist im Grunde nur eine spezielle Syntax um die Produktionsregeln übersichtlich hinzuschreiben. Es gibt allerdings auch ein paar neue Begriffe. Da sind zum einen die Terminale. Das sind "finale" Buchstaben, wenn ein Terminal in einer Regel generiert wurde, kann es nicht mehr verändert werden. Nichtterminale hingegen sind die "Variablen" aus dem letzten Beitrag. Das sind Hilfssymbole, die wiederum als Ausgangspunkt für weitere Produktionen verwendet werden. Beispiel-Time! Z ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" Der vertikale Strich ist als "oder" zu verstehen. Ein "Z" kann nachher in den Regeln mit einer dieser Terminale ersetzt werden. Dann fehlt da formal noch folgendes: (G steht für Grammatik, T für Terminale, N für Nichtterminale, S für Startsymbol und P für Produktionsregeln) T= {Z} N= {A} P= { S->ASA, S-> G = {S,P,N,T} Damit hätten wir eine Grammatik definiert, die eine Sprache generieren kann. Diese Sprache kann ein leeres Wort generieren, denn wir starten bei S und kommen von da aus direkt zum epsilon. Das epsilon ist ein Terminal, von hier aus ginge es also nicht weiter. Schön, aber noch nicht perfekt, denn ich könnte damit Zahlen mit führenden Nullen generieren. Wenn ich das nicht wollte, müsste ich ein paar Regeln umschreiben: Z::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" Y::= Z | "0" N= {A,B,C} P= { S-> Es wird also etwas komplizierter, aber nicht viel. Wir füren ein paar mehr Regeln und Nichtterminale ein und stellen so sicher, dass gleich nach dem S eine nicht-Null generiert wird. Danach verlassen wir das S und generieren in C weiter. 141592 generiert sich so: S->ACB->ZCY->ZBCBY->ZYBCBYY->ZYY Das ist also eine kontextreie Sprache, und jetzt kann ich auch erklären, woher das "kontextfrei" kommt. Die Produktionsregeln sind unabhängig davon, welches Terminal vor oder hinter einem Nichtterminal steht. Grundsätzlich kann für ein Nichtterminal jede entsprechende Produktionsregel verwendet werden, ganz unabhängig vom Kontext in dem es steht. Ich habe noch nicht erklärt, was "entscheidbar" bedeutet, deshalb kann ich im Moment auch noch nicht erklären, welches Automatenmodell kontextfreie Sprachen entschieden kann. Im nächsten Beitrag geht es um deterministische finite Automaten und welche Art Sprache davon entschieden werden können. Das mag etwas seltsam anmuten, aber diese Reihenfolge macht schon Sinn. Sowohl Automaten als auch Sprachen fühlen sich zu Anfang etwas weit hergeholt an. Dennoch besteht ein so starker Zusammenhang zwischen den beiden, dass es meiner Meinung nach Sinn macht, erst einfache Sprachen zu beschreiben, dann einfache Automaten einzuführen und dann den Zusammenhang herzustellen.
Kontextfreie Sprachen und die BNF Geschrieben von Turing
in Informatik um
21:28
Kommentare (0) Trackbacks (0) Mittwoch, 15. August 2007Formale Sprachen und ein paar BegriffsklärungenDies ist der Eröffnungsbeitrag zur nächsten Serie in diesem Blog. Es wird um formale Sprachen und dem Zusammenhang zwischen Automatenmodellen und diesen Sprachen gehen. Leider gibt es hier kein "Ziel" in dem Sinne wie es eines bei P vs. NP gab, aber der lose Plan ist, früher oder später in die Entscheidbarkeitstheorie abzuschweifen. Da steht dann das Halteproblem an, was ich jetzt einfach mal als vorläufiges Ziel definiere. Aber keine Angst, diese Serie wird etwas praxisrelevanter sein als die P vs. NP-Serie. Und wie immer versuche ich natürlich, möglichst plastische Beispiele zu benutzen. Schauen wir uns zu diesem Zweck erstmal natürliche Sprachen an. Nehmen wir den Satz "Ich esse Pizza". Wir erinnern uns an die Regel "Subjekt Prädikat Objekt" aus der Schulzeit. So könnte man diesen Satz formal konstruieren. Das Subjekt wäre "Ich", also substituiere ich "Ich" mit "Subjekt". Dann steht da "Ich Prädikat Objekt". Dann substituiere ich noch Prädikat mit "esse" und Objekt mit "Pizza" und schon steht da "Ich esse Pizza". Natürlich macht unsere menschliche Intuition das ganze automatisch und viel schneller. Aber ich würde einfach mal ohne Beweis behaupten, dass das Gehirn diese Prozedur trotzdem durchläuft, wenn auch fast unmerklich. Gut, wir haben also gesehen dass natürliche Sprachen nach gewissen Regeln generiert werden, das ganze kann man natürlich auch formalisieren. Es sei aber vorher erwähnt, dass natürliche Sprachen in der Regel weitaus komplizierter als formale Sprachen sind. Es gibt so viele Sonderregeln und Abweichungen, dass die entsprechende formale Sprache riesig groß und kompliziert wäre. Das ändert aber nichts an der Tatsache, dass natürliche Sprachen im Grunde nur ein Spezialfall einer formalen Sprache ist. Wie definiert man aber eine Sprache formal? Nun, zunächst brauchen wir ein Alphabet. In Deutsch wäre das vielleicht so etwas wie A = {a,b,...,y,z,A,B,...,Y,Z,ä,ü,ö,Ä,Ü,Ö,ß}. Es gehören außerdem Satzzeichen dazu, denn alles was so allgemein in einem Satz vorkommen kann, muss auch im Alphabet auftauchen. Machen wir es uns aber etwas einfacher, ohne dabei an Bedeutung zu verlieren. Unser Alphabet ist {A,B,C}. Dann ist ein "Wort" eine Aneinanderreihung von validen Buchstaben, zum Beispiel ABBAC. Der nächste Begriff den wir benötigen ist "Sprache". Das ist eine Menge von Wörtern, z.B. {AB, AABB,CCC}. Auch das ist analog zu natürlichen Sprachen. Wir könnten auch im deutschen Alphabet z.B. "hudZ8,," generieren, aber das würde nicht zu unserer Sprache gehören. Genauso könnten wir in der formalen Sprache "ABCCA" generieren, aber das gehört ebenfalls nicht zur Sprache. Sprachen bezeichnet man in der Regel mit L = {..}, man könnte aber auch unendlich große Sprachen definieren, zum Beispiel als L2={w| w beginnt mit A und endet mit C}. Da steht in Worten: "L2 besteht aus allen Wörtern w, die der Bedingung hinter dem vertikalen Strich genügen". Diese Sprache wäre also {AC, AAC, ABC ACC, AABC,...} Das letzte was ich noch ansprechen möchte sind die so genannten Produktionsregeln. Diese sind ein bischen abhängig vom Typ der Sprache, allgemein kann man aber sagen, dass wir formale Sprachen immer irgendwie generieren wollen. Bisher haben wir das intuitiv gemacht, aber das funktioniert nur begrenzt oft. Nehmen wir L2 und defineren ein paar Hilfssymbole. Zum Beispiel brauchen wir ein Startsymbol, das nicht zur Sprache gehören darf. In der Regel nennt man das "S". Wenn wir jetzt ein Wort aus der Sprache generieren wollen, fangen wir beim Startsymbol an und schreiben das auf ein Blatt Papier. Und jetzt kommen die Produktionsregeln ist Spiel. Wir müssen uns ein paar einfach Regeln ausdenken, wie jedes Wort aus L2 zu erzielen ist. Wir wissen schon einmal, dass jedes Wort ein A am Anfang und ein C am Ende haben muss. Was läge also näher als S-> AYC? Wenn man das S auf dem Blatt stehen hat, kann man mit dieser Regel das S in AYC umwandeln. Dabei ist wichtig zu beachten, dass A und C Buchstaben aus dem Alpabet sind und das Y eine Variable. Für diese Variable definieren wir weitere Regeln, denn in der Mitte des Wortes ist es uns egal was da steht. Nehmen wir also Y->AY, Y->BY, Y->CY und Fassen wir also zusammen: A= {A,B,C}, L2={w| w beginnt mit A und endet mit C} Produktionsregeln P= { S-> AYC, Y->AY, Y->BY, Y->CY, Man kann leicht sehen dass die Produktionregeln die Sprache erzeugen, aber hier noch ein Beispiel: Generieren wir mal ABAC. S-> AYC ->ABYC -> ABAYC -> ABAC. Man beachte, dass bei der letzten Regel das Epsilon einfach wegfällt. Es ist das leere Wort, das taucht nur symbolisch in den Regeln auf, aber nicht im Wort. Ein Beispiel habe ich noch, diesmal etwas "praxisnäheres". Das Alphabet A ist A={0,1, Jetzt wo wir also wissen wie man formale Sprachen definiert und generiert, schauen wir uns in einem späteren Posting mal an, was es bedeutet wenn eine Sprache entscheidbar ist und welche Sprachen von Turingmaschinen entscheidbar sind. Später beschäftigen wir uns dann mit anderen Automatenmodellen, Chomsky-Hierachien und vielleicht noch mit Beweismethoden wie dem Pumping-Lemma.
Formale Sprachen und ein paar ... Geschrieben von Turing
in Informatik um
01:08
Kommentare (2) Trackbacks (0) |
KategorienFeedsGetaggte Artikelööh.. informatik?
algorithmus china determinismus entscheidbarkeitstheorie fehlerwahrscheinlichkeit fernsehen filme formale sprachen games geek-zeug informatik komplexitã¤t komplexitã¤tsklasse laufzeit linux medien millenium-probleme monty hall nichtdeterminismus nicht eingã¤ngig nintendo ds np o-notation p poker p vs. np randomisierung rffc RP sco sonstiges sonstiges mathematisches spieltheorie statik technische mechanik tm turing turing-maschine universelle turingmaschinen utm videospiele wachstum wahrscheinlichkeit xkcd zpp SonstigesBlogrollSuche |
Powered by s9y - Design by Lordcoffee