mirror of
https://github.com/MartinThoma/LaTeX-examples.git
synced 2025-04-25 14:28:05 +02:00
Backtracking
This commit is contained in:
parent
1e9968f7db
commit
682d2a6f21
6 changed files with 62 additions and 7 deletions
|
@ -173,7 +173,7 @@ erzeugt werden:
|
||||||
|
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/data-example.hs}
|
\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.
|
Haskell wertet Ausdrücke nur aus, wenn es nötig ist.
|
||||||
|
|
||||||
\begin{beispiel}[Lazy Evaluation]
|
\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}
|
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=lazy-evaluation.hs]{haskell}{scripts/haskell/lazy-evaluation.hs}
|
||||||
\end{beispiel}
|
\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}
|
\section{Beispiele}
|
||||||
\subsection{Quicksort}
|
\subsection{Quicksort}
|
||||||
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=qsort.hs]{haskell}{scripts/haskell/qsort.hs}
|
\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}
|
\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.hs]{haskell}{scripts/haskell/fibonacci.hs}
|
||||||
\inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-akk.hs]{haskell}{scripts/haskell/fibonacci-akk.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-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}
|
\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}
|
\subsection{Standard Prelude}
|
||||||
Hier sind die Definitionen eininger wichtiger Funktionen:
|
Hier sind die Definitionen eininger wichtiger Funktionen:
|
||||||
|
\xindex{zipWith}\xindex{zip}
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/standard-definitions.hs}
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/standard-definitions.hs}
|
||||||
|
|
||||||
\section{Weitere Informationen}
|
\section{Weitere Informationen}
|
||||||
|
|
|
@ -102,7 +102,9 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also:
|
||||||
|
|
||||||
Die Call-By-Name Auswertung wird in Funktionen verwendet.
|
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?}
|
\todo[inline]{Was ist sharing?}
|
||||||
|
|
||||||
\begin{definition}[Call-By-Value]\xindex{Call-By-Value}%
|
\begin{definition}[Call-By-Value]\xindex{Call-By-Value}%
|
||||||
|
|
|
@ -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.
|
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}
|
\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}
|
\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:
|
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:
|
||||||
|
|
Binary file not shown.
|
@ -113,7 +113,18 @@ Wenn eine rekursive Funktion nicht terminiert oder wenn
|
||||||
\index{Rekursion|)}
|
\index{Rekursion|)}
|
||||||
\section{Backtracking}
|
\section{Backtracking}
|
||||||
\index{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|)}
|
\index{Backtracking|)}
|
||||||
|
|
||||||
\section{Funktionen höherer Ordnung}
|
\section{Funktionen höherer Ordnung}
|
||||||
|
|
44
documents/Programmierparadigmen/scripts/python/n-damen.py
Normal file
44
documents/Programmierparadigmen/scripts/python/n-damen.py
Normal 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)))
|
Loading…
Add table
Add a link
Reference in a new issue