This commit is contained in:
Never Gude 2026-05-30 20:05:41 +02:00
parent 54e6ff16b7
commit 6475d1b263
13 changed files with 402 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View file

@ -1,2 +1,24 @@
% vim: ft=tex
\section{Perfekte Matchings in bipartiten Graphen} \section{Perfekte Matchings in bipartiten Graphen}
\begin{quote}
Ein bipartiter Graph $G = \tup{A \cupdot B, E}$ mit $\abs{A} = \abs{B} = k$
und jeder Knoten hat mindestens Grad $\frac{k}{2}$ $\iff$ $G$ enthält
perfektes Matching.
\end{quote}
\begin{itemize}
\item[$\seilpmi$] Wenn $G$ ein perfektes Matching enthält, dann muss
$\abs{A} = \abs{B}$, sonst würden Knoten übrig bleiben.
Außerdem muss jeder Knoten mindestens Grad $1$ haben, da sonst Knoten
nicht gematcht werden könnten.
\item[$\implies$] Man kann jeden Knoten in $A$ einem
Knoten in $B$ zuordnen, da $\abs{A} = \abs{B}$.
Alle Knoten sind im Matching enthalten. Wenn wir eine Kante zum Matching
hinzufügen, verringert sich die Anzahl der offenen Knoten um $2$.
Insbesondere verringert sich auch der Grad von $\frac{k}{2} - 1$
Knoten um $1$ in $A$ und $B$. Da jeder Knoten mindestens Grad $\frac{k}{2}$ hat und jedes mal
ein offenes Knotenpaar entfernt wird.
$k$ mal eine Kante zum Matching hinzufügen. Also wird jeder Knoten gematcht.
\end{itemize}
\points{5} \points{5}

BIN
übung_6/agt26-blatt06.pdf Normal file

Binary file not shown.

17
übung_6/agt_übung_6.tex Normal file
View file

@ -0,0 +1,17 @@
\documentclass[parskip=half]{ngexrcs}
\usepackage{hyperref}
\setkeys{Gin}{pagebox=artbox, width=0.2\textwidth}
\subject{Algorithmische Graphentheorie}
\title{5. Übungsblatt}
\author{Jasper Gude \and Pia Röttgers}
\begin{document}
\maketitle
\points[2em]{25}
\input{aufgabe_1.tex}
\input{aufgabe_2.tex}
\input{aufgabe_3.tex}
\end{document}

82
übung_6/aufgabe_1.tex Normal file
View file

@ -0,0 +1,82 @@
\newcommand{\OPT}{\mathrm{OPT}}
\section{Paarungen (Matchings) in Bäumen}
\begin{tasks}
\item
\label{1a}
Ein Baum ist ein kreisfreier, zusammenhängender Graph. Ein Baum besitzt ein
perfektes Matching genau dann, wenn die Anzahl der Knoten gerade ist und
jedes Blatt keine Geschwisterknoten hat.
Die Anzahl der Knoten muss gerade sein, da in einem perfekten Match\-ing jeder
Knoten mit einem anderen gematcht wird.
Jedes Blatt muss Einzelblatt sein, da der Elternknoten nur mit einem Blatt
gematcht werden kann.
Also ist ein perfektes Matching im Baum eindeutig, da jedes Blatt mit seinem
Elternknoten gematcht werden muss. Diese Kante $uv$ ist sicher im Matching enthalten und alle zu $u$ oder $v$ inzidenten Kanten können aus dem Baum gelöscht werden. So entsteht ein neues Blatt, für das
die selbe Regel gilt.
\points{3}
\item
Der \autoref{alg:treematching} berechnet ein größtes Matching.
Der Algorithmus ist korrekt, da der Baum $T$ entweder ein perfektes Matching
enthält und somit ein perfektes Matching berechnet (Siehe \autoref{1a}),
oder I dont fucking know.
Die Laufzeit für \algt{Initialize} liegt in $\Oh(V)$, da sich der Baum in linearer Zeit augmentieren lässt und es $\abs{V} - 1$ viele Kanten gibt.
Die Laufzeit für \algt{MatchaTeeRec} liegt in $\Oh(V)$. Der Algorithmus wird genau
einmal für jeden Knoten aufgerufen. Wenn eine Kante zum
Match\-ing hinzugefügt wird, werden die Knoten und Kanten aus dem Baum gelöscht
die nicht mehr zum Matching hinzugefügt werden können und somit
nicht mehr bearbeitet werden.
Also liegt auch \algt{MatchaTee} in $\Oh(V)$.
\begin{algorithm}
\centering
\caption{Größtes Matching in Bäumen}
\label{alg:treematching}
\begin{algorithmic}
\alg{MatchaTee}{$T = \tup{V, E}$} \+ \\
\com{Den ungerichten Baum zu einem gerichteten Baum mit $parent$ und} \\
\com{$children$ pro Knoten und einer Wurzel $root$ augmentieren.} \\
\alg{Initialize}{$T$} \\
return \alg{MatchaTeeRec}{$T$, $T.root$} \- \\
\\
\alg{MatchaTeeRec}{$T$, $r$} \+ \\
\com{Rekursiv für die Kinder aufrufen} \\
$m \gets \emptyset$ \\
foreach $v \in r.children$ do \+ \\
$m \gets m \cup \text{\alg{MatchaTeeRec}{T, v}}$ \- \\
\com{Wenn Knoten Blatt ist, dann die Kante zum Elternknoten hinzufügen.} \\
if $r \neq nil$ and $deg(r) = 1$ then \+ \\
\com{Die Knoten und inzidente Kanten aus dem Baum entfernen.} \\
$T \gets T \setminus \set{r.parent, r.parent.children}$ \\
$m \gets m \cup \set{\set{r, r.parent}}$ \- \\
return $m$
\end{algorithmic}
\end{algorithm}
\points{5}
\item
Wenn eine Kante $rv$ zu einem Matching hinzugefügt wird, kann keine zu $v$
inzidente Kante hinzugefügt werden. Das müssen wir auch bei unserem dynamischen
Programm beachten.
\[
\OPT(r) = \max_{v \in r.children}
\begin{cases}
rv + \sum_{i \in v.children} \OPT(i) + \sum_{j \in r.children \setminus v} \OPT(j) \\
\sum_{k \in r.children} \OPT(k)
\end{cases}
\]
Der Algorithmus hält sich an die Eigenschaften eines Matchings, also ist
er korrekt.
Der Algorithmus probiert alle Kindknoten von $r$ aus. Geht man mit $r$ im Baum von
unten nach oben sind das also höchstens so viele Iterationen wie, Knoten im Baum
existieren (ohne die Blätter). Also läuft das Dynamische Programm in $\Oh(V)$.
\points{5}
\end{tasks}

24
übung_6/aufgabe_2.tex Normal file
View file

@ -0,0 +1,24 @@
\section{Hamiltonkreise}
\begin{tasks}
\item
Ein Kreis hat im allgemeinen mindestens die Länge 3. Da der Turniergraph mindestens
3 Knoten enthält und stark zusammenhängend ist, liegt jeder Knoten auf einem Kreis
mit Länge $\geq 3$.
\points{1}
\item
Gegeben ist ein Kreis $K$ mit Länge $\geq 3$.
Um $K$ zu verkleinern wählen wir uns drei aufeinanderfolgende Knoten $a, b, c$ aus.
Nach Definition gibt es für jedes Knotenpaar eine gerichtete Kante. Wir ersetzen
jetzt einen Weg der Länge 2 durch eine Kante die nach Annahme existieren muss. Das
machen wir solange, bis der Kreis die Länge 3 hat.
\points{2}
\item
\points{1}
\item
\points{1}
\item
\points{1}
\item
\points{1}
\end{tasks}

24
übung_6/aufgabe_3.tex Normal file
View file

@ -0,0 +1,24 @@
% vim: ft=tex
\section{Perfekte Matchings in bipartiten Graphen}
\begin{quote}
Ein bipartiter Graph $G = \tup{A \cupdot B, E}$ mit $\abs{A} = \abs{B} = k$
und jeder Knoten hat mindestens Grad $\frac{k}{2}$ $\iff$ $G$ enthält
perfektes Matching.
\end{quote}
\begin{itemize}
\item[$\seilpmi$] Wenn $G$ ein perfektes Matching enthält, dann muss
$\abs{A} = \abs{B}$, sonst würden Knoten übrig bleiben.
Außerdem muss jeder Knoten mindestens Grad $1$ haben, da sonst Knoten
nicht gematcht werden könnten.
\item[$\implies$] Man kann jeden Knoten in $A$ einem
Knoten in $B$ zuordnen, da $\abs{A} = \abs{B}$.
Alle Knoten sind im Matching enthalten. Wenn wir eine Kante zum Matching
hinzufügen, verringert sich die Anzahl der offenen Knoten um $2$.
Insbesondere verringert sich auch der Grad von $\frac{k}{2} - 1$
Knoten um $1$ in $A$ und $B$. Da jeder Knoten mindestens Grad $\frac{k}{2}$ hat und jedes mal
ein offenes Knotenpaar entfernt wird.
$k$ mal eine Kante zum Matching hinzufügen. Also wird jeder Knoten gematcht.
\end{itemize}
\points{5}

38
übung_6/aufgabe_4.tex Normal file
View file

@ -0,0 +1,38 @@
\section{Längste Wege}
\begin{tasks}
\item
Da $s, t$ in $G'$ adjazent zu jedem Knoten in $G$ ist, können wir
einen einfachen $s$-$t$-Weg der Länge $k+2$ erzeugen, indem wir
einen einfachen Weg der Länge $k$ in $G$ nehmen, $s$ an das eine Ende und $t$ an das andere Ende hängen.
Umgekehrt kann man aus einem einfachen $s$-$t$-Weg der Länge $k$
in $G'$ einen einfachen Weg der Länge $k-2$ in $G$ konstruieren,
indem wir $s$ und $t$ entfernen.
\points{2}
\item
Ein Hamiltonweg ist ein Weg der alle Knoten in $G$ beinhaltet
und somit Länge $n-1$ besitzt.
Wie wir oben gezeigt haben, kann ein $s$-$t$-Weg der Länge $n+1$
in $G'$ leicht in einen Weg der Länge $n-1$ in $G$ umgewandelt
werden. Das heißt, dass wir einen Hamiltonweg in $G$ finden,
wenn wir einen $s$-$t$-Weg finden.
Umgekehrt können wir einen Hamiltonweg leicht in einen $s$-$t$-Weg
umwandeln, also finden wir einen $s$-$t$-Weg wenn wir einen
Hamiltonweg finden.
Also finden wir einen Hamiltonweg genau dann, wenn wir einen
$s$-$t$-Weg finden.
\points{1}
\item
Da wir Hamiltonweg auf \algt{Längster $s$-$t$-Weg} reduziert
haben, muss also \algt{Längster $s$-$t$-Weg} $\NPe$-schwer sein, denn
wenn es in $\Pe$ liegen würde, könnten wir auch Hamiltonweg in
polynomieller Zeit lösen. Da wir nicht von $\Pe = \NPe$ ausgehen,
ist das nicht möglich.
\points{2}
\end{tasks}

BIN
übung_6/figures.pdf Normal file

Binary file not shown.

71
übung_6/ngexrcs.cls Normal file
View file

@ -0,0 +1,71 @@
% vim: set filetype:tex
% Identification %
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{ngexrcs}[2021/12/21 ADS Exercise class]
% Handle options %
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{scrartcl}}
\ProcessOptions\relax
% More declarations %
\LoadClass{scrartcl}
\KOMAoptions{mpinclude=true}
\recalctypearea
\RequirePackage{ngutils}
% define fonts
\RequirePackage{fontspec}
\RequirePackage[math-style=upright]{unicode-math}
\setmainfont{TeX Gyre Pagella}
\setsansfont{TeX Gyre Heros}
\setmonofont{TeX Gyre Cursor}
\setmathfont{Euler Math}
\setlength{\marginparwidth}{1.5\marginparwidth}
\setlength{\fboxrule}{\heavyrulewidth}
% Use sansfont for all title elements
\addtokomafont{titlehead}{\sffamily}
\addtokomafont{subject}{\sffamily}
\addtokomafont{title}{\sffamily}
\addtokomafont{subtitle}{\sffamily}
\addtokomafont{author}{\sffamily}
\addtokomafont{date}{\sffamily}
\addtokomafont{publishers}{\sffamily}
% Use serif font for headings
\addtokomafont{disposition}{\rmfamily}
% Let sections be formated as in: Aufgabe 1 -- Section title
\renewcommand*{\sectionformat}{Aufgabe \thesection\autodot\enskip--\enskip}
% Let points of an exercise be printed as in: [__ / 2]
\newkomafont{points}{\sffamily}
\newcommand\points[2][1em]{\marginline{\framebox{{\usekomafont{points}\hspace{#1} \textbf{/} #2}}}}
\newcounter{task}
\renewcommand{\thetask}{\@alph\c@task)}
\newenvironment{tasks}
{
\begin{list}{\thetask}
{
\usecounter{task}
\setlength{\leftmargin}{1.6em}
}
}{%
\end{list}
}
\DeclareNewTOC
[
type=algorithm,
types=algorithms,
float,
floattype=4,
name=Algorithmus,
listname={Algorithmenverzeichnis}
]
{loa}

124
übung_6/ngutils.sty Normal file
View file

@ -0,0 +1,124 @@
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ngutils}[2025/12/24 Never's LaTeX utils]
\RequirePackage[ngerman]{babel}
\RequirePackage{graphicx}
\RequirePackage{tabularx}
\RequirePackage{booktabs}
\RequirePackage{listings}
\lstnewenvironment{pseudocode}[1][] %defines the algorithm listing environment
{
\renewcommand{\lstlistingname}{Algorithmus}
\lstset{ %this is the stype
mathescape=true,
columns=fullflexible,
basicstyle=\normalfont,
identifierstyle=\scshape,
keywordstyle=\bfseries,
keywords={, new, if, then, else, while, for, in, to, up, down, foreach, do, return},
commentstyle=\itshape,
comment=[l]//,
delim=[is][\normalfont]{|}{|},
tabsize=3,
frame=tb,
framerule=1pt,
#1 % this is to add specific settings to an usage of this environment (for instnce, the caption and referable label)
}
}
{}
\newcommand{\seilpmi}{\Longleftarrow}
\newcommand{\NN}{\mathbb{N}}
\newcommand{\ZZ}{\mathbb{Z}}
\newcommand{\QQ}{\mathbb{Q}}
\newcommand{\RR}{\mathbb{R}}
\newcommand{\CC}{\mathbb{C}}
\newcommand{\PP}{\mathbb{P}}
\newcommand{\Pe}{\mathrm{P}}
\newcommand{\NPe}{\mathrm{NP}}
\newcommand{\Oh}{\mathcal{O}}
\newcommand{\oh}{\scriptstyle{\mathcal{O}}}
\newcommand{\Eh}{\mathop{\mathrm{E}}}
\newcommand{\Var}{\mathop{\mathrm{Var}}}
\newcommand{\pot}{\mathop{\mathcal{P}}}
\newcommand{\argmax}{\mathop{\mathrm{arg\,max}}}
\newcommand{\argmin}{\mathop{\mathrm{arg\,min}}}
\newcommand{\parens}[1]{\left(#1\right)}
\newcommand{\brackets}[1]{\left[#1\right]}
\newcommand{\braces}[1]{\left\{#1\right\}}
\newcommand{\angled}[1]{\left\langle#1\right\rangle}
\newcommand{\tup}[1]{\parens{#1}}
\newcommand{\ivl}[1]{\brackets{#1}}
\newcommand{\set}[1]{\braces{#1}}
\newcommand{\arr}[1]{\angled{#1}}
\newcommand{\abs}[1]{\lvert#1\rvert}
\newcommand{\norm}[1]{\lVert#1\rVert}
\newcommand{\ceil}[1]{\lceil#1\rceil}
\newcommand{\floor}[1]{\lfloor#1\rfloor}
\newcommand{\alg}[2]{{\normalfont\scshape#1}{\normalfont(#2)}}
\newcommand{\algt}[1]{{\normalfont\scshape#1}}
\newcommand{\com}[1]{{\normalfont\itshape/\!\!/ #1}}
\newenvironment{algorithmic}[1][1em]{
\begin{minipage}[t]{\textwidth}
\bfseries
\begin{tabbing}
\hspace{#1}\=\hspace{#1}\=\hspace{#1}\=\hspace{#1}\=\hspace{#1}\=\hspace{#1}\=\hspace{#1}\=\hspace{#1}\=\kill
}{%
\end{tabbing}
\end{minipage}
}
\newlength{\theoremskip}
\setlength{\theoremskip}{6em}
\newcommand{\theoremfont}{\normalfont\bfseries}
\newcommand{\definitionfont}{\normalfont\bfseries}
\newenvironment{theoremic}[2][\theoremfont]{
{#1 #2}
\hfill
\begin{minipage}[t]{\the\dimexpr\linewidth-\theoremskip\relax}
}{
\end{minipage}
}
\newenvironment{theorem}{
\begin{theoremic}{Satz.}
}{
\end{theoremic}
}
\newenvironment{lemma}{
\begin{theoremic}{Lemma.}
}{
\end{theoremic}
}
\newenvironment{proof}{
\begin{theoremic}{Beweis.}
}{
\end{theoremic}
}
\newenvironment{definition}{
\begin{theoremic}[\definitionfont]{Definition.}
}{
\end{theoremic}
}
\newenvironment{example}{
\begin{theoremic}[\definitionfont]{Beispiel.}
}{
\end{theoremic}
}