Programmiertechniken.tex 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. \chapter{Programmiertechniken}
  2. \section{Rekursion}
  3. \index{Rekursion|(}
  4. \begin{definition}[rekursive Funktion]\xindex{Funktion!rekursive}
  5. Eine Funktion $f: X \rightarrow X$ heißt rekursiv definiert,
  6. wenn in der Definition der Funktion die Funktion selbst wieder
  7. steht.
  8. \end{definition}
  9. \begin{beispiel}[rekursive Funktionen]
  10. \begin{bspenum}
  11. \item Fibonacci-Funktion:\xindex{Fibonacci-Funktion}
  12. \begin{align*}
  13. fib: \mdn_0 &\rightarrow \mdn_0\\
  14. fib(n) &= \begin{cases}
  15. n &\text{falls } n \leq 1\\
  16. fib(n-1) + fib(n-2) &\text{sonst}
  17. \end{cases}
  18. \end{align*}
  19. \item Fakultät:\xindex{Fakultät}
  20. \begin{align*}
  21. !: \mdn_0 &\rightarrow \mdn_0\\
  22. n! &= \begin{cases}
  23. 1 &\text{falls } n \leq 1\\
  24. n\cdot (n-1)! &\text{sonst}
  25. \end{cases}
  26. \end{align*}
  27. \item \label{bsp:binomialkoeffizient} Binomialkoeffizient:\xindex{Binomialkoeffizient}
  28. \begin{align*}
  29. \binom{\cdot}{\cdot}: \mdn_0 \times \mdn_0 &\rightarrow \mdn_0\\
  30. \binom{n}{k} &= \begin{cases}
  31. 1 &\text{falls } k=0 \lor k = n\\
  32. \binom{n-1}{k-1}+\binom{n-1}{k} &\text{sonst}
  33. \end{cases}
  34. \end{align*}
  35. \end{bspenum}
  36. \end{beispiel}
  37. Ein Problem von rekursiven Funktionen in Computerprogrammen ist der
  38. Speicherbedarf. Für jeden rekursiven Aufruf müssen alle Umgebungsvariablen
  39. der aufrufenden Funktion (\enquote{stack frame}) gespeichert bleiben,
  40. bis der rekursive Aufruf beendet ist. Im Fall der Fibonacci-Funktion
  41. sieht ist der Call-Stack in \cref{fig:fib-callstack} abgebildet.
  42. \begin{figure}[htp]
  43. \centering
  44. \includegraphics*[width=0.5\linewidth, keepaspectratio]{figures/fib-callstack.png}
  45. \caption{Call-Stack der Fibonacci-Funktion}
  46. \label{fig:fib-callstack}
  47. \end{figure}
  48. \begin{bemerkung}
  49. Die Anzahl der rekursiven Aufrufe der Fibonacci-Funktion $f_C$ ist:
  50. \[f_C(n) = \begin{cases}
  51. 1 &\text{falls } n=0\\
  52. 2 \cdot fib(n) - 1 &\text{falls } n \geq 1
  53. \end{cases}\]
  54. \end{bemerkung}
  55. \begin{beweis}\leavevmode
  56. \begin{itemize}
  57. \item Offensichtlich gilt $f_C(0) = 1$
  58. \item Offensichtlich gilt $f_C(1) = 1 = 2 \cdot fib(1) - 1$
  59. \item Offensichtlich gilt $f_C(2) = 3 = 2 \cdot fib(2) - 1$
  60. \item Für $n \geq 3$:
  61. \begin{align*}
  62. f_C(n) &= 1 + f_C(n-1) + f_C(n-2)\\
  63. &= 1 + (2\cdot fib(n-1)-1) + (2 \cdot fib(n-2)-1)\\
  64. &=2\cdot (fib(n-1) + fib(n-2)) - 1\\
  65. &=2 \cdot fib(n) - 1
  66. \end{align*}
  67. \end{itemize}
  68. \end{beweis}
  69. Mit Hilfe der Formel von Moivre-Binet folgt:
  70. \[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\]
  71. Dabei ist der Speicherbedarf $\mathcal{O}(n)$. Dieser kann durch
  72. das Benutzen eines Akkumulators signifikant reduziert werden.\todo{TODO}
  73. \begin{definition}[linear rekursive Funktion]\xindex{Funktion!linear rekursive}
  74. Eine Funktion heißt linear rekursiv, wenn in jedem Definitionszweig
  75. der Funktion höchstens ein rekursiver Aufruf vorkommt.
  76. \end{definition}
  77. \begin{definition}[endrekursive Funktion]\xindex{Funktion!endrekursive}\xindex{tail recursive}
  78. Eine Funktion heißt endrekursiv, wenn in jedem Definitionszweig
  79. der Rekursive aufruf am Ende des Ausdrucks steht. Der rekursive
  80. Aufruf darf also insbesondere nicht in einen anderen Ausdruck
  81. eingebettet sein.
  82. \end{definition}
  83. \todo[inline]{Beispiele für linear rekusrive, endrekursive Funktionen (alle Kombinationen+gegenbeispiele}
  84. \index{Rekursion|(}
  85. \section{Backtracking}