mirror of
https://github.com/MartinThoma/LaTeX-examples.git
synced 2025-04-25 14:28:05 +02:00
Abschnitt über Rekursion hinzugefügt
This commit is contained in:
parent
156a09095a
commit
7e99fea83a
7 changed files with 115 additions and 8 deletions
|
@ -7,3 +7,4 @@ in dem Erstellen dieses Skripts steckt:
|
||||||
|01.02.2014 | 14:00 - 14:45 | Thoma | ASCII-Tabelle in C angefangen; Kapitel "Programmiersprachen" hinzugefügt; erste Definitionen
|
|01.02.2014 | 14:00 - 14:45 | Thoma | ASCII-Tabelle in C angefangen; Kapitel "Programmiersprachen" hinzugefügt; erste Definitionen
|
||||||
|01.02.2014 | 14:45 - 15:30 | Thoma | Haskell angefangen
|
|01.02.2014 | 14:45 - 15:30 | Thoma | Haskell angefangen
|
||||||
|01.02.2014 | 11:15 - 11:45 | Thoma | Haskell Class Hierachy
|
|01.02.2014 | 11:15 - 11:45 | Thoma | Haskell Class Hierachy
|
||||||
|
|01.02.2014 | 16:00 - 17:00 | Thoma | Abschnitt über Rekursion hinzugefügt
|
||||||
|
|
|
@ -40,12 +40,7 @@ definiert:
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/einfaches-beispiel-klammern.hs}
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/einfaches-beispiel-klammern.hs}
|
||||||
|
|
||||||
\subsection{if / else}
|
\subsection{if / else}
|
||||||
Das folgende Beispiel definiert den Binomialkoeffizienten
|
Das folgende Beispiel definiert den Binomialkoeffizienten (vgl. \cref{bsp:binomialkoeffizient})
|
||||||
\[\binom{n}{k} := \begin{cases}
|
|
||||||
1 &\text{falls } k=0 \lor k = n\\
|
|
||||||
\binom{n-1}{k-1}+\binom{n-1}{k} &\text{sonst}
|
|
||||||
\end{cases}\]
|
|
||||||
für $n,k \geq 0$:
|
|
||||||
|
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/binomialkoeffizient.hs}
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/binomialkoeffizient.hs}
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{bash}{scripts/haskell/compile-binom.sh}
|
\inputminted[numbersep=5pt, tabsize=4]{bash}{scripts/haskell/compile-binom.sh}
|
||||||
|
@ -65,6 +60,9 @@ hat einen Speicherverbrauch von $\mathcal{O}(n)$. Durch einen
|
||||||
\textbf{Akkumulator}\xindex{Akkumulator} kann dies verhindert werden:
|
\textbf{Akkumulator}\xindex{Akkumulator} kann dies verhindert werden:
|
||||||
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/fakultaet-akkumulator.hs}
|
\inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/fakultaet-akkumulator.hs}
|
||||||
|
|
||||||
|
\subsection{Listen}
|
||||||
|
\todo[inline]{Cons-Operator, Unendliche Listen}
|
||||||
|
|
||||||
\section{Beispiele}
|
\section{Beispiele}
|
||||||
\subsection{Hello World}
|
\subsection{Hello World}
|
||||||
Speichere folgenden Quelltext als \texttt{hello-world.hs}:
|
Speichere folgenden Quelltext als \texttt{hello-world.hs}:
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,98 @@
|
||||||
\chapter{Programmiertechniken}
|
\chapter{Programmiertechniken}
|
||||||
\section{Rekursion}
|
\section{Rekursion}
|
||||||
\todo[inline]{Tail-Recursion}
|
\index{Rekursion|(}
|
||||||
|
|
||||||
|
\begin{definition}[rekursive Funktion]\xindex{Funktion!rekursive}
|
||||||
|
Eine Funktion $f: X \rightarrow X$ heißt rekursiv definiert,
|
||||||
|
wenn in der Definition der Funktion die Funktion selbst wieder
|
||||||
|
steht.
|
||||||
|
\end{definition}
|
||||||
|
|
||||||
|
\begin{beispiel}[rekursive Funktionen]
|
||||||
|
\begin{bspenum}
|
||||||
|
\item Fibonacci-Funktion:\xindex{Fibonacci-Funktion}
|
||||||
|
\begin{align*}
|
||||||
|
fib: \mdn_0 &\rightarrow \mdn_0\\
|
||||||
|
fib(n) &= \begin{cases}
|
||||||
|
n &\text{falls } n \leq 1\\
|
||||||
|
fib(n-1) + fib(n-2) &\text{sonst}
|
||||||
|
\end{cases}
|
||||||
|
\end{align*}
|
||||||
|
\item Fakultät:\xindex{Fakultät}
|
||||||
|
\begin{align*}
|
||||||
|
!: \mdn_0 &\rightarrow \mdn_0\\
|
||||||
|
n! &= \begin{cases}
|
||||||
|
1 &\text{falls } n \leq 1\\
|
||||||
|
n\cdot (n-1)! &\text{sonst}
|
||||||
|
\end{cases}
|
||||||
|
\end{align*}
|
||||||
|
\item \label{bsp:binomialkoeffizient} Binomialkoeffizient:\xindex{Binomialkoeffizient}
|
||||||
|
\begin{align*}
|
||||||
|
\binom{\cdot}{\cdot}: \mdn_0 \times \mdn_0 &\rightarrow \mdn_0\\
|
||||||
|
\binom{n}{k} &= \begin{cases}
|
||||||
|
1 &\text{falls } k=0 \lor k = n\\
|
||||||
|
\binom{n-1}{k-1}+\binom{n-1}{k} &\text{sonst}
|
||||||
|
\end{cases}
|
||||||
|
\end{align*}
|
||||||
|
\end{bspenum}
|
||||||
|
\end{beispiel}
|
||||||
|
|
||||||
|
Ein Problem von rekursiven Funktionen in Computerprogrammen ist der
|
||||||
|
Speicherbedarf. Für jeden rekursiven Aufruf müssen alle Umgebungsvariablen
|
||||||
|
der aufrufenden Funktion (\enquote{stack frame}) gespeichert bleiben,
|
||||||
|
bis der rekursive Aufruf beendet ist. Im Fall der Fibonacci-Funktion
|
||||||
|
sieht ist der Call-Stack in \cref{fig:fib-callstack} abgebildet.
|
||||||
|
|
||||||
|
\begin{figure}[htp]
|
||||||
|
\centering
|
||||||
|
\includegraphics*[width=0.5\linewidth, keepaspectratio]{figures/fib-callstack.png}
|
||||||
|
\caption{Call-Stack der Fibonacci-Funktion}
|
||||||
|
\label{fig:fib-callstack}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{bemerkung}
|
||||||
|
Die Anzahl der rekursiven Aufrufe der Fibonacci-Funktion $f_C$ ist:
|
||||||
|
\[f_C(n) = \begin{cases}
|
||||||
|
1 &\text{falls } n=0\\
|
||||||
|
2 \cdot fib(n) - 1 &\text{falls } n \geq 1
|
||||||
|
\end{cases}\]
|
||||||
|
\end{bemerkung}
|
||||||
|
\begin{beweis}\leavevmode
|
||||||
|
\begin{itemize}
|
||||||
|
\item Offensichtlich gilt $f_C(0) = 1$
|
||||||
|
\item Offensichtlich gilt $f_C(1) = 1 = 2 \cdot fib(1) - 1$
|
||||||
|
\item Offensichtlich gilt $f_C(2) = 3 = 2 \cdot fib(2) - 1$
|
||||||
|
\item Für $n \geq 3$:
|
||||||
|
\begin{align*}
|
||||||
|
f_C(n) &= 1 + f_C(n-1) + f_C(n-2)\\
|
||||||
|
&= 1 + (2\cdot fib(n-1)-1) + (2 \cdot fib(n-2)-1)\\
|
||||||
|
&=2\cdot (fib(n-1) + fib(n-2)) - 1\\
|
||||||
|
&=2 \cdot fib(n) - 1
|
||||||
|
\end{align*}
|
||||||
|
\end{itemize}
|
||||||
|
\end{beweis}
|
||||||
|
|
||||||
|
Mit Hilfe der Formel von Moivre-Binet folgt:
|
||||||
|
|
||||||
|
\[f_C \in \mathcal{O} \left (\frac{\varphi^n- \psi^n}{\varphi - \psi} \right) \text{ mit } \varphi := \frac{1+ \sqrt{5}}{2} \text{ und }\psi := 1 - \varphi\]
|
||||||
|
|
||||||
|
Dabei ist der Speicherbedarf $\mathcal{O}(n)$. Dieser kann durch
|
||||||
|
das Benutzen eines Akkumulators signifikant reduziert werden.\todo{TODO}
|
||||||
|
|
||||||
|
\begin{definition}[linear rekursive Funktion]\xindex{Funktion!linear rekursive}
|
||||||
|
Eine Funktion heißt linear rekursiv, wenn in jedem Definitionszweig
|
||||||
|
der Funktion höchstens ein rekursiver Aufruf vorkommt.
|
||||||
|
\end{definition}
|
||||||
|
|
||||||
|
\begin{definition}[endrekursive Funktion]\xindex{Funktion!endrekursive}\xindex{tail recursive}
|
||||||
|
Eine Funktion heißt endrekursiv, wenn in jedem Definitionszweig
|
||||||
|
der Rekursive aufruf am Ende des Ausdrucks steht. Der rekursive
|
||||||
|
Aufruf darf also insbesondere nicht in einen anderen Ausdruck
|
||||||
|
eingebettet sein.
|
||||||
|
\end{definition}
|
||||||
|
|
||||||
|
\todo[inline]{Beispiele für linear rekusrive, endrekursive Funktionen (alle Kombinationen+gegenbeispiele}
|
||||||
|
|
||||||
|
\index{Rekursion|(}
|
||||||
\section{Backtracking}
|
\section{Backtracking}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ TODO
|
||||||
\section*{Erforderliche Vorkenntnisse}
|
\section*{Erforderliche Vorkenntnisse}
|
||||||
Grundlegende Kenntnisse vom Programmieren, insbesondere mit Java,
|
Grundlegende Kenntnisse vom Programmieren, insbesondere mit Java,
|
||||||
wie sie am KIT in \enquote{Programmieren} vermittelt werden, werden
|
wie sie am KIT in \enquote{Programmieren} vermittelt werden, werden
|
||||||
vorausgesetzt.
|
vorausgesetzt. Außerdem könnte ein grundlegendes Verständnis für
|
||||||
|
das O-Kalkül aus \enquote{Grundbegriffe der Informatik} hilfreich sein.
|
||||||
|
|
||||||
Die Unifikation wird wohl auch in \enquote{Formale Systeme}
|
Die Unifikation wird wohl auch in \enquote{Formale Systeme}
|
||||||
erklärt; das könnte also hier von Vorteil sein.
|
erklärt; das könnte also hier von Vorteil sein.
|
||||||
|
|
BIN
documents/Programmierparadigmen/figures/fib-callstack.png
Normal file
BIN
documents/Programmierparadigmen/figures/fib-callstack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
|
@ -0,0 +1,14 @@
|
||||||
|
fib(3)
|
||||||
|
├ call(fib(2))
|
||||||
|
│ ├─ call(fib(1))
|
||||||
|
│ │ └─ return 1
|
||||||
|
│ ├─ call(fib(0))
|
||||||
|
│ │ └─ return 1
|
||||||
|
│ └ return fib(1)+fib(0)=1+1
|
||||||
|
├ call(fib(1))
|
||||||
|
│ ├─ call(fib(1))
|
||||||
|
│ │ └─ return 1
|
||||||
|
│ ├─ call(fib(0))
|
||||||
|
│ │ └─ return 1
|
||||||
|
│ └ return fib(1)+fib(0)=1+1
|
||||||
|
└ return fib(2)+fib(1)=2+2
|
Loading…
Add table
Add a link
Reference in a new issue