Browse Source

Backtracking

Martin Thoma 11 years ago
parent
commit
682d2a6f21

+ 3 - 5
documents/Programmierparadigmen/Haskell.tex

@@ -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}

+ 3 - 1
documents/Programmierparadigmen/Lambda.tex

@@ -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}%

File diff suppressed because it is too large
+ 1 - 1
documents/Programmierparadigmen/Logik.tex


BIN
documents/Programmierparadigmen/Programmierparadigmen.pdf


+ 11 - 0
documents/Programmierparadigmen/Programmiertechniken.tex

@@ -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}

+ 44 - 0
documents/Programmierparadigmen/scripts/python/n-damen.py

@@ -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)))