2025-06-24 19:07:14 +02:00

9.1 KiB
Raw Blame History

1. Dynamische Datenstrukturen

Linked-List

self.address: A[i] \longleftarrow prev.address \ | \ next.address\longrightarrow

Stack

First-In; Last-Out

Binary-Tree

self.address : Value \rightarrow left.address : \rightarrow right.address

Graphen

Adjazenzmatrix

Von Zeile nach Spalte


\newcommand\T{\rlap{\text{to}}}
\begin{array}{cc}
    & \T \\
    \text{from} &
    \begin{array}{c|cccc}
        & v_0 & v_1 & v_2 & v_3 \\
        \hline
        v_0 & 0 & 1 & 1 & 0 \\
        v_1 & 0 & 0 & 0 & 0 \\
        v_2 & 0 & 1 & 0 & 0 \\
        v_3 & 0 & 0 & 1 & 1 \\
    \end{array}
\end{array}

Adjazenzliste

Von Spaltenheader zu allen elementen in der Spalte


\begin{array}
 & 1 & 2 & 3 & 4 \\
\hline
2 & 3 & 2 & 1 \\
4 \\

\end{array}

2. Skipliste, Binary-Search-Tree, Shellsort

Skipliste


\begin{array}{l}
\text{Layer 2:} \quad H \rightarrow \phantom{E_1 \rightarrow E_2 \rightarrow} E_3 \rightarrow \phantom{E_4 \rightarrow E_5 \rightarrow} \text{NIL} \\
\\
\text{Layer 1:} \quad H \rightarrow E_1 \rightarrow \phantom{E_2 \rightarrow} E_3 \rightarrow \phantom{E_4 \rightarrow} E_5 \rightarrow \text{NIL} \\
\\
\text{Layer 0:} \quad H \rightarrow E_1 \rightarrow E_2 \rightarrow E_3 \rightarrow E_4 \rightarrow E_5 \rightarrow \text{NIL}
\end{array}

Binary Search Tree

Linker Teilbaum kleiner, rechter Teilbaum größer

Tiefe = Max(\text{Anzahl Kanten})

Suchen Richtung? -> Vergleich von beiden Kinder knoten

Einfügen Gleich wie suchen

Löschen Pointer umsetzen

Shellsort

Insertionsort

Schritt-für-Schritt:

  1. Beginne mit dem zweiten Element (Index 1) im Array. Das erste Element gilt als bereits sortiert.
  2. Vergleiche das aktuelle Element mit den vorherigen Elementen.
  3. Wenn das aktuelle Element kleiner als das verglichene Element ist, verschiebe das verglichene Element um eine Position nach rechts.
  4. Wiederhole Schritt 3, bis du die richtige Position für das aktuelle Element gefunden hast.
  5. Füge das aktuelle Element an der richtigen Stelle ein.
  6. Gehe zum nächsten Element und wiederhole die Schritte 25, bis das Array sortiert ist.

Beispiel:

Angenommen, du hast das Array: [5, 2, 9, 1]

  • Beginne mit 2 (Index 1). Vergleiche mit 5. Da 2 < 5, verschiebe 5 nach rechts und setze 2 an Index 0. Jetzt: [2, 5, 9, 1]
  • Als Nächstes 9 (Index 2). Vergleiche mit 5. 9 > 5, also bleibt alles wie es ist.
  • Als Nächstes 1 (Index 3). Vergleiche mit 9, 5 und 2. 1 < 9, 1 < 5, 1 < 2. Verschiebe alle drei nach rechts und setze 1 an Index 0. Jetzt: [1, 2, 5, 9]

Shellsort

Schrittweite

Wahrscheinlich in der Aufgabe gegeben, ansonsten die hier nehmen:

s_i = 2^i -1
  • Mit Schrittweite in Sub-Arrays zerlegen.
  • Diese Schritt-Arrays mit Insertionsort sortieren.
  • Bei Schrittweite 1 Durchlauf endet die Sortierung.

3. Heaps und Heapsort

Ein heap ist ein binary tree, bei dem alle Elternknoten bei einem Max-Heap, größer Werden respektiv bei einem Min-Heap kleiner

Min-Heap = Oben das kleinste Max-Heap = Oben das größte

Tiefe:

floor(\log_2(n))+1

Index von Kindern und Parent:


\text{Children}: 
\begin{cases}
  2i & \text{Child 1} \\

  2i+1  & \text{Child 2 }
\end{cases}
Parent: floor\left(\frac{2i}{2}\right)

Max/Min-Heap-Reparieren:

Man itereriert durch alle Element, ausgeschlossen die Blätter. Folgendes Schema:

Breadth-First: Man startet dem Letzten Element (Visuell unten rechts), das Kinder hat. Dann nach Links bis ende der Ebene und dann nach oben.

Das ist nur das Iterieren! Noch Reparieren!

for e in Elements:
	...

Schicht 1 \longleftarrow\longleftarrow Root \longleftarrow \longleftarrow\Lsh Schicht 2 \longleftarrow\longleftarrow e_1 \longleftarrow e_2 \longleftarrow\Lsh Schicht 3 \leftarrow e_3 \leftarrow e_4 \leftarrow e_5 \leftarrow e_6 \leftarrow \text{START} ... Blätter ..................................................

Jedes Element das man anschaut wird dann down-geshifted. Im grunde Rekursives Max/Min im Dreieck.

  1. Man vergleicht aktuelles Element mit den Kindern. (Wie so ein Dreieck)
\begin{document}
\begin{tikzpicture}[level distance=1.5cm,
  level 1/.style={sibling distance=3cm},
  level 2/.style={sibling distance=1.5cm}]
  \node {element}
    child {node {child 1}}
    child {node {child 2}};
\end{tikzpicture}
\end{document}
  1. (Abbruchbedingung), Gehe zum nächsten Element ...
    1. Max-Heap: Wenn element ist das größte von den drei: max([e, c1, c2]) = e
    2. Min-Heap: Wenn element ist das kleinste von den drei: min([e, c1, c2]) = e
  2. Wenn nicht, dann tausche mit dem größten (Max-Heap) / kleinsten (Min-Heap) der drei.
  3. Wiederhole, bis Abbruchbedingung erreicht, oder ende vom Baum, bzw. ganz unten.

Heap-Sort

  1. Unten Rechts (Letztes Element im Heap-Array, ist ein Blatt btw.), mit dem ersten (Root) Tauschen.
  2. Heap Reparieren indem man das neue Root element down-shifted, bis es wieder am richtigen platz ist, siehe vorherige erklärung.

4. Balancierte Bäume

Binärer Suchbaum

Max. Tiefe: log_2(n)

Jeder Knoten bekommt einen Balancefaktor, dieser Entspricht der Tiefe vom rechten, minus der Tiefe des linken Teilbaumes.

Tiefe von einem (Teil)Baum, ist einfach die maximale Anzahl Kanten nach unten.

BAL(N) = T(u_2) - T(u_1)

Dieser sollte -1 \leq BAL(N)\leq 1

5. Reelwertige Optimierung in einer Dimension

Bisektion mit Sampling. I.e. man macht Bisektion mehrere Male, mit anderen Intervallen. Also z.B. komplettes intervall ist I=[1, 10], und dort sind vielleicht 4 lokale Minima. Dann macht man halt I_1=[1, 4], I_2=[4,7], I_3=[7, 10] Und führt auf den Intervallen Bisektion aus und nimmt das beste Ergebnis.

Ganz Normal Newton Verfahren mit Schrittweitensteuerung.

Straf- (Penalty-) Funktionen

Grundidee
Mit einer Straffunktion p(x) wird ein restringiertes Problem


\text{Min } f(x), \qquad A \le x \le B

auf ein unrestringiertes Problem


\text{Min } \Phi(x) \;=\; f(x) + p(x)

abgebildet. Die Strafe p(x) ist null im gültigen Bereich und wächst quadratisch, sobald eine Schranke verletzt wird.


Quadratische Strafterme (2-mal diff'bar)


p_1(x) \;=\; \beta (x-A)^2 \quad \text{für } x \ge A,\;\text{sonst }0,

p_2(x) \;=\; \beta (x-B)^2 \quad \text{für } x \le B,\;\text{sonst }0,

p(x) \;=\; p_1(x) + p_2(x), \qquad \beta>0.

Je größer \beta, desto stärker die Strafe ⇒ höhere Genauigkeit am Rand, aber auch instabilere Newton-Schritte.


Beispiel


\text{Min } e^x, \qquad 0 \le x \le 1.

Strafterme


p_1(x)=\beta x^2, \qquad p_2(x)=\beta (x-1)^2,

Gesamtfunktion


\Phi(x)=e^x + p_1(x) + p_2(x).

Ableitungen einsetzen → Newton-Iteration mit \Phi anstelle von f.

Merke: Die Wahl von \beta ist ein Kompromiss zwischen Genauigkeit und numerischer Stabilität.

6. Bivariate Lineare Programmierung

  1. Nebenbedingungen Aufbauen (Ungleichungen)
  2. Nach y auflösen und einzeichnen (Aufpassen)
  3. Lösung finden

Werden beide Seiten einer Ungleichung mit einer negativen Zahl multipliziert oder durch eine negative Zahl dividiert, muss das Ungleichheitszeichen umgekehrt werden (z.B. aus < wird >)

7. Reelwertige Optimierung in N Dimensionen

f(x_1, x_2,..., x_n) f'(x) \longrightarrow \nabla f(x) f''(x) \longrightarrow H

7.2 Downhill-Simplex

Besteht aus n+1 Punkten

Vorgehen:

  1. Berechne alle f(x_0), f(x_1), \ ...
  2. Berechne Schwerpunkt (Durchschnitt von allen x)
  3. Eine Operation ausführen

Reflection

Spiegelung des schlechtesten Punktes am Schwerpunkt

x_r = x_{n+1} + (x_{n+1}-\bar{x})

Expansion

Spiegelung aber skaliert

Contraction

Shrinkage

Zieht die schlechten Punkten zum besten Punkt. I.e. halbiert die Entfernung zum besten Punkt.

Abbruch

f_{worst} - f_{best} < tol \sqrt{mean((f_{x_i} -f_S)^2)} < tol mean((f_{x_i} - mean([...f_x]))^2)

7.3 Newton

Für 1 Parameter:

x_{n+1} = x_n - \frac{f'(x)}{f''(x)}

Für 1< Parameter:

x_{x+1} = x_n - H^{-1}_n * \nabla f_n

Mit Schrittweitensteuerung:

x_{x+1} = x_n - c_i * H^{-1}_n * \nabla f_n

1. Partielle Ableitungen f_{xx} ist f(x, y), zweimal partiell nach x abgeleitet. f_{xy} wäre einmal nach x und ein zweites mal nach y abgeleitet.


f_{xx} = \frac{\partial^{2} f}{\partial x^{2}},\qquad
f_{xy} = \frac{\partial^{2} f}{\partial x\,\partial y},\qquad
f_{yx} = \frac{\partial^{2} f}{\partial y\,\partial x},\qquad
f_{yy} = \frac{\partial^{2} f}{\partial y^{2}}.

2. Gradient Vektor mit \text{1. Partieller Ableitung nach x} in der x Komponente, respektive part. diff. y in y .


\nabla f(x,y)=
\begin{pmatrix}
\displaystyle\frac{\partial f}{\partial x}\\[6pt]
\displaystyle\frac{\partial f}{\partial y}
\end{pmatrix}.

3. Hesse Matrix und Determinante


H=
\begin{pmatrix}
f_{xx} & f_{xy}\\
f_{yx} & f_{yy}
\end{pmatrix},
\qquad
\det H = f_{xx}\cdot f_{yy}-(f_{xy})^2.

4. Inverse Hesse-Matrix bestimmen


H^{-1}=\frac{1}{\det H}
\begin{pmatrix}
f_{yy} & -f_{xy}\\
-f_{xy} & f_{xx}
\end{pmatrix}.

7.4 Steepest-Descent

Newton aber mit H^{-1} \approx 1. Btw. das c ist wichtig, weil der Gradient nur ne Richtung ist.

x_{x+1} = x_n - c_i * \nabla f_n