Programmiertechniken.tex 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. %!TEX root = Programmierparadigmen.tex
  2. \chapter{Programmiertechniken}
  3. \section{Rekursion}
  4. \index{Rekursion|(}
  5. \begin{definition}[rekursive Funktion]\xindex{Funktion!rekursive}%
  6. Eine Funktion $f: X \rightarrow X$ heißt rekursiv definiert,
  7. wenn in der Definition der Funktion die Funktion selbst wieder
  8. steht.
  9. \end{definition}
  10. \begin{beispiel}[rekursive Funktionen]
  11. \begin{bspenum}
  12. \item Fibonacci-Funktion:\xindex{Fibonacci-Funktion}
  13. \begin{align*}
  14. fib: \mdn_0 &\rightarrow \mdn_0\\
  15. fib(n) &= \begin{cases}
  16. n &\text{falls } n \leq 1\\
  17. fib(n-1) + fib(n-2) &\text{sonst}
  18. \end{cases}
  19. \end{align*}
  20. Erzeugt die Zahlen $0, 1, 1, 2, 3, 5, 8, 13, \dots$
  21. \item Fakultät:\xindex{Fakultät}
  22. \begin{align*}
  23. ! &: \mdn_0 \rightarrow \mdn_0\\
  24. n! &= \begin{cases}
  25. 1 &\text{falls } n \leq 1\\
  26. n\cdot (n-1)! &\text{sonst}
  27. \end{cases}
  28. \end{align*}
  29. \item \label{bsp:binomialkoeffizient} Binomialkoeffizient:\xindex{Binomialkoeffizient}
  30. \begin{align*}
  31. \binom{\cdot}{\cdot} &: \mdn_0 \times \mdn_0 \rightarrow \mdn_0\\
  32. \binom{n}{k} &= \begin{cases}
  33. 1 &\text{falls } k=0 \lor k = n\\
  34. \binom{n-1}{k-1}+\binom{n-1}{k} &\text{sonst}
  35. \end{cases}
  36. \end{align*}
  37. \end{bspenum}
  38. \end{beispiel}
  39. Ein Problem von rekursiven Funktionen in Computerprogrammen ist der
  40. Speicherbedarf. Für jeden rekursiven Aufruf müssen alle lokalen Variablen
  41. der aufrufenden Funktion (\enquote{stack frame}) gespeichert bleiben,
  42. bis der rekursive Aufruf beendet ist. Im Fall der Fibonacci-Funktion
  43. sieht ist der Call-Stack in \cref{fig:fib-callstack} abgebildet.
  44. \begin{figure}[htp]
  45. \centering
  46. \includegraphics*[width=0.5\linewidth, keepaspectratio]{figures/fib-callstack.png}
  47. \caption{Call-Stack der Fibonacci-Funktion}
  48. \label{fig:fib-callstack}
  49. \end{figure}
  50. \begin{bemerkung}
  51. Die Anzahl der rekursiven Aufrufe der Fibonacci-Funktion $f_C$ ist:
  52. \[f_C(n) = \begin{cases}
  53. 1 &\text{falls } n=0\\
  54. 2 \cdot fib(n) - 1 &\text{falls } n \geq 1
  55. \end{cases}\]
  56. \end{bemerkung}
  57. \begin{beweis}\leavevmode
  58. \begin{itemize}
  59. \item Offensichtlich gilt $f_C(0) = 1$
  60. \item Offensichtlich gilt $f_C(1) = 1 = 2 \cdot fib(1) - 1$
  61. \item Offensichtlich gilt $f_C(2) = 3 = 2 \cdot fib(2) - 1$
  62. \item Für $n \geq 3$:
  63. \begin{align*}
  64. f_C(n) &= 1 + f_C(n-1) + f_C(n-2)\\
  65. &= 1 + (2\cdot fib(n-1)-1) + (2 \cdot fib(n-2)-1)\\
  66. &=2\cdot (fib(n-1) + fib(n-2)) - 1\\
  67. &=2 \cdot fib(n) - 1
  68. \end{align*}
  69. \end{itemize}
  70. \end{beweis}
  71. Mit Hilfe der Formel von Moivre-Binet folgt:
  72. \[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\]
  73. Dabei ist der Speicherbedarf $\mathcal{O}(n)$. Dieser kann durch
  74. das Benutzen eines Akkumulators signifikant reduziert werden.\todo{TODO}
  75. \begin{definition}[linear rekursive Funktion]\xindex{Funktion!linear rekursive}%
  76. Eine Funktion heißt linear rekursiv, wenn in jedem Definitionszweig
  77. der Funktion höchstens ein rekursiver Aufruf vorkommt.
  78. \end{definition}
  79. \begin{definition}[endrekursive Funktion]\xindex{Funktion!endrekursive}\xindex{tail recursive}%
  80. Eine Funktion heißt endrekursiv, wenn in jedem Definitionszweig
  81. der Rekursive aufruf am Ende des Ausdrucks steht. Der rekursive
  82. Aufruf darf also insbesondere nicht in einen anderen Ausdruck
  83. eingebettet sein.
  84. \end{definition}
  85. Auf Englisch heißen endrekursive Funktionen \textit{tail recursive}.
  86. \begin{beispiel}[Linear- und endrekursive Funktionen]
  87. \begin{bspenum}
  88. \item \texttt{fak n = if (n==0) then 1 else (n * fak (n-1))}\\
  89. ist eine linear rekursive Funkion, aber nicht endrekursiv,
  90. da nach der Rückgabe von \texttt{fak (n-1)} noch die Multiplikation
  91. ausgewertet werden muss.
  92. \item \texttt{fakAcc n acc = if (n==0) then acc else fakAcc (n-1) (n*acc)}\\
  93. ist eine endrekursive Funktion.
  94. \item \texttt{fib n = n <= 1 ? n : fib(n-1) + fib (n-2)}\\
  95. ist weder linear- noch endrekursiv.
  96. \end{bspenum}
  97. \end{beispiel}
  98. Wenn eine rekursive Funktion nicht terminiert oder wenn
  99. \index{Rekursion|)}
  100. \section{Backtracking}
  101. \index{Backtracking|(}
  102. Unter \textit{Backtracking} versteht man eine Programmiertechnik, die
  103. (eventuell implizit) auf einem Suchbaum arbeitet und mittels Tiefensuche versucht
  104. eine Lösung zu finden.
  105. \begin{beispiel}[Backtracking]
  106. Probleme, bei deren (vollständigen) Lösung Backtracking verwendet wird, sind:
  107. \begin{bspenum}
  108. \item Damenproblem
  109. \item Springerproblem
  110. \item Rucksackproblem
  111. \end{bspenum}
  112. \end{beispiel}
  113. \index{Backtracking|)}
  114. \section{Funktionen höherer Ordnung}
  115. Funktionen höherer Ordnung sind Funktionen, die auf Funktionen arbeiten.
  116. Bekannte Beispiele sind:
  117. \begin{itemize}
  118. \item \texttt{map(function, list)}\xindex{map}\\
  119. \texttt{map} wendet \texttt{function} auf jedes einzelne
  120. Element aus \texttt{list} an.
  121. \item \texttt{filter(function, list)}\xindex{filter}\\
  122. \texttt{filter} gibt eine Liste aus Elementen zurück, für
  123. die \texttt{function} mit \texttt{true} evaluiert.
  124. \item \texttt{reduce(function, list)}\xindex{reduce}\\
  125. \texttt{function} ist für zwei Elemente aus \texttt{list}
  126. definiert und gibt ein Element des gleichen Typs zurück.
  127. Nun steckt \texttt{reduce} zuerst zwei Elemente aus \texttt{list}
  128. in \texttt{function}, merkt sich dann das Ergebnis und nimmt
  129. so lange weitere Elemente aus \texttt{list}, bis jedes
  130. Element genommen wurde.\\
  131. Bei \texttt{reduce} ist die Assoziativität wichtig (vgl. \cpageref{bsp:foldl-und-foldr})
  132. \end{itemize}