2
0
Fork 0
mirror of https://github.com/MartinThoma/LaTeX-examples.git synced 2025-04-25 06:18:05 +02:00

Backtracking

This commit is contained in:
Martin Thoma 2014-03-18 15:45:40 +01:00
parent 1e9968f7db
commit 682d2a6f21
6 changed files with 62 additions and 7 deletions

View file

@ -173,7 +173,7 @@ erzeugt werden:
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/data-example.hs}
\section{Lazy Evaluation}\xindex{Lazy Evaluation}
\section{Lazy Evaluation}\xindex{Lazy Evaluation}%
Haskell wertet Ausdrücke nur aus, wenn es nötig ist.
\begin{beispiel}[Lazy Evaluation]
@ -182,9 +182,6 @@ Haskell wertet Ausdrücke nur aus, wenn es nötig ist.
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=lazy-evaluation.hs]{haskell}{scripts/haskell/lazy-evaluation.hs}
\end{beispiel}
Ein spezialfall der Lazy-Evaluation ist die sog. \textit{Kurzschlussauswertung}.\xindex{Kurzschlussauswertung}\xindex{Short-circuit evaluation}
Das bezeichnet die Lazy-Evaluation von booleschen Ausdrücken.
\section{Beispiele}
\subsection{Quicksort}
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=qsort.hs]{haskell}{scripts/haskell/qsort.hs}
@ -205,6 +202,7 @@ sich das ganze sogar noch kürzer schreiben:
\subsection{Fibonacci}\xindex{Fibonacci}
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci.hs]{haskell}{scripts/haskell/fibonacci.hs}
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-akk.hs]{haskell}{scripts/haskell/fibonacci-akk.hs}
\xindex{zipWith}
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-zip.hs]{haskell}{scripts/haskell/fibonacci-zip.hs}
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-pattern-matching.hs]{haskell}{scripts/haskell/fibonacci-pattern-matching.hs}
@ -219,7 +217,7 @@ TODO
\subsection{Standard Prelude}
Hier sind die Definitionen eininger wichtiger Funktionen:
\xindex{zipWith}\xindex{zip}
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/standard-definitions.hs}
\section{Weitere Informationen}

View file

@ -102,7 +102,9 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also:
Die Call-By-Name Auswertung wird in Funktionen verwendet.
Haskell verwendet die Call-By-Name Auswertungsreihenfolge zusammen mit \enquote{sharing}. Dies nennt man Lazy Evaluation.
Haskell verwendet die Call-By-Name Auswertungsreihenfolge zusammen mit \enquote{sharing}. Dies nennt man \textit{Lazy Evaluation}. Ein spezialfall der Lazy-Evaluation ist die sog. \textit{Kurzschlussauswertung}.\xindex{Kurzschlussauswertung}\xindex{Short-circuit evaluation}
Das bezeichnet die Lazy-Evaluation von booleschen Ausdrücken.
\todo[inline]{Was ist sharing?}
\begin{definition}[Call-By-Value]\xindex{Call-By-Value}%

View file

@ -82,7 +82,7 @@ Damit sind alle Ausdrücke unserer Sprache festgelegt. Ist zum Beispiel $f$ ein
ein Ausdruck, da er sich durch Anwendung obiger Regeln aufbauen lässt. Es sei noch einmal darauf hingewiesen, dass wir die Ausdrücke mittels der genannten Regeln rein mechanisch erstellen, ohne dass die Ausdrücke zwangsläufig irgendetwas bezeichnen müssten.
\subsection{1. Stufe}
Unterschiedliche Sprachen erster Stufe unterscheiden sich lediglich in den Mengen $\mathcal C$, $\mathcal F$ und $\mathcal R$, die man üblicherweise zur Symbolmenge $S$ zusammenfasst und auch die \textit{Signatur} der Sprache nennt. Man spricht dann auch genauer von $S$-Termen bzw. $S$-Ausdrücken. Die Sprache, das heißt die Gesamtheit aller nach obigen Regeln gebildeten Ausdrücke, wird mit $L(S)$, $L^S$ oder $L_I^S$ bezeichnet. Bei letzterem steht die römische $I$ für die 1-te Stufe. Dies bezieht sich auf den Umstand, dass gemäß letzter Erzeugungsregel nur über Variable quantifiziert werden kann. $L_I^S$ sieht nicht vor, über alle Teilmengen einer Menge oder über alle Funktionen zu quantifizieren. So lassen sich die üblichen [[Peano-Axiome]] nicht in $L_I^S$ ausdrücken, da das Induktionsaxiom eine Aussage über alle Teilmengen der natürlichen Zahlen macht. Das kann als Schwäche dieser Sprache angesehen werden, allerdings sind die Axiome der [[Zermelo-Fraenkel-Mengenlehre]] sämtlich in der ersten Stufe mit dem einzigen Symbol $\in$ formulierbar, so dass die erste Stufe prinzipiell für die Mathematik ausreicht.
Unterschiedliche Sprachen erster Stufe unterscheiden sich lediglich in den Mengen $\mathcal C$, $\mathcal F$ und $\mathcal R$, die man üblicherweise zur Symbolmenge $S$ zusammenfasst und auch die \textit{Signatur} der Sprache nennt. Man spricht dann auch genauer von $S$-Termen bzw. $S$-Ausdrücken. Die Sprache, das heißt die Gesamtheit aller nach obigen Regeln gebildeten Ausdrücke, wird mit $L(S)$, $L^S$ oder $L_I^S$ bezeichnet. Bei letzterem steht die römische $I$ für die 1-te Stufe. Dies bezieht sich auf den Umstand, dass gemäß letzter Erzeugungsregel nur über Variable quantifiziert werden kann. $L_I^S$ sieht nicht vor, über alle Teilmengen einer Menge oder über alle Funktionen zu quantifizieren. So lassen sich die üblichen [[Peano-Axiome]] nicht in $L_I^S$ ausdrücken, da das Induktionsaxiom eine Aussage über alle Teilmengen der natürlichen Zahlen macht. Das kann als Schwäche dieser Sprache angesehen werden, allerdings sind die Axiome der Zermelo-Fraenkel-Mengenlehre sämtlich in der ersten Stufe mit dem einzigen Symbol $\in$ formulierbar, so dass die erste Stufe prinzipiell für die Mathematik ausreicht.
\subsection{Freie Variablen}
Weitere Eigenschaften von Ausdrücken der Sprache $L_I^S$ lassen sich ebenfalls rein syntaktisch definieren. Gemäß dem oben beschriebenen Aufbau durch Bildungsregeln definieren wir die Menge $\mathrm{frei}(\varphi)$ der im Ausdruck $\varphi$ frei vorkommenden Variablen wie folgt:

View file

@ -113,7 +113,18 @@ Wenn eine rekursive Funktion nicht terminiert oder wenn
\index{Rekursion|)}
\section{Backtracking}
\index{Backtracking|(}
Unter \textit{Backtracking} versteht man eine Programmiertechnik, die
(eventuell implizit) auf einem Suchbaum arbeitet und mittels Tiefensuche versucht
eine Lösung zu finden.
\begin{beispiel}[Backtracking]
Probleme, bei deren (vollständigen) Lösung Backtracking verwendet wird, sind:
\begin{bspenum}
\item Damenproblem
\item Springerproblem
\item Rucksackproblem
\end{bspenum}
\end{beispiel}
\index{Backtracking|)}
\section{Funktionen höherer Ordnung}

View file

@ -0,0 +1,44 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def get_next(n, i, damen_pos):
for i in range(n):
candidates = set(list(range(n)))
candidates -= set(damen_pos)
candidates -= set(list(range(damen_pos[i]+1)))
candidates = list(candidates)
if len(candidates) > 0:
damen_pos[i] = candidates[0]
return i, damen_pos
else:
damen_pos = damen_pos[0:i] + [0]*(n-i)
i -= 1
def is_attacked(damen, x, y):
""" Wird das Feld (x,y) von einer der Damen angegriffen? """
for dy, dx in enumerate(damen[:y]):
if dx == x or dy == y or abs(x-dx) == abs(y-dy):
return True
return False
def finde_loesung(n):
""" Platziere n Damen so auf einem n×n Feld,
sodass sich keine Damen schlagen.
"""
# damen[i] ist die x-position von Dame i in Zeile i
damen = [0]*n
i = 1
solutions = []
while 0 <= i < n:
while not is_attacked(damen, damen[i], i):
if i == n-1:
yield damen
break
i += 1
i, damen = get_next(n, i, damen)
def alle_loesungen(n):
generator = finde_loesung(n)
return list(generator)
print(len(alle_loesungen(11)))