Fix GraphAlgorithm (hopefully)

This commit is contained in:
joachimschmidt557 2019-03-25 19:07:35 +01:00
parent d071187c79
commit c331208620
3 changed files with 98 additions and 17 deletions

View file

@ -79,13 +79,15 @@ public abstract class GraphAlgorithm<T> {
}
Iterator<Node<T>> iter = availableNodes.iterator();
AlgorithmNode<T> MinElem;
Iterator<Node<T>> minElemIter = availableNodes.iterator();
AlgorithmNode<T> minElem;
AlgorithmNode<T> tempElem;
if (iter.hasNext()) {
// Set minimum to first elements
MinElem = algorithmNodes.get(iter.next());
// Set minimum to first element
minElem = algorithmNodes.get(iter.next());
minElemIter.next();
while (iter.hasNext()) {
@ -99,15 +101,18 @@ public abstract class GraphAlgorithm<T> {
tempElem = algorithmNodes.get(iter.next());
if (tempElem.value > 0) {
if (tempElem.value < MinElem.value) {
MinElem = tempElem;
if (tempElem.value < minElem.value) {
// New minimum
minElem = tempElem;
minElemIter = iter;
}
}
}
iter.remove();
minElemIter.remove();
return MinElem;
return minElem;
}
@ -192,7 +197,7 @@ public abstract class GraphAlgorithm<T> {
if (prevNode == null)
return null;
while (!prevNode.node.equals(destination)) {
while (!(prevNode.value == 0)) {
AlgorithmNode<T> prevPrevNode = prevNode.previous;

View file

@ -15,7 +15,7 @@ public class GraphAlgoComplexityTest {
@Test
public void test() {
for (int i = 1; i < 1000; i+=10) {
for (int i = 30; i < 50; i+=1) {
Graph<Integer> g = generateGraph(i);
DumbGraphAlgorithm ga = new DumbGraphAlgorithm(g, g.getNodes().get(0));
@ -27,6 +27,19 @@ public class GraphAlgoComplexityTest {
double divN3 = (double)ga.getN() / ((double)i*i*i);
System.out.println(i + "," + ga.getN() + "," + divN + "," + divN2 + "," + divN3);
/////////////
Graph<Integer> g2 = generateGraph2(i);
DumbGraphAlgorithm ga2 = new DumbGraphAlgorithm(g2, g2.getNodes().get(4));
ga2.run();
List<Edge<Integer>> path = ga2.getPath(g2.getNodes().get(12));
for (Edge<Integer> edge : path) {
System.out.println(edge.getNodeA().getValue().toString() + " " + edge.getNodeB().getValue().toString());
}
//System.out.println();
}
@ -53,6 +66,23 @@ public class GraphAlgoComplexityTest {
}
public Graph<Integer> generateGraph2(int n) {
Graph<Integer> g = new Graph<Integer>();
List<Node<Integer>> nodes = new ArrayList<>();
for (int i = 0; i < n; i++)
nodes.add(g.addNode(i));
for (int i = 0; i < n - 1; i++) {
g.addEdge(nodes.get(i), nodes.get(i+1));
}
return g;
}
public class DumbGraphAlgorithm extends GraphAlgorithm<Integer> {
public DumbGraphAlgorithm(Graph<Integer> graph, Node<Integer> sourceNode) {

View file

@ -145,7 +145,7 @@ Eine pseudocode-Darstellung des Algorithmus:
\If{edge is passable}
\State $n \gets$ otherNode
\State $a \gets$ v.value + edge.value
\If{n.value = -1 or n.value > a}
\If{n.value $= -1$ or n.value $> a$}
\State n.value $\gets$ a
\State n.previous $\gets$ v
\EndIf
@ -182,9 +182,8 @@ Knoten eine Kante mit sich selber haben kann.
\subsubsection{Teil (b)}
Anstelle einer \texttt{LinkedList} braucht man eine
Datenstruktur, die bereits nach der Größe sortiert ist,
damit bei dem Zugriff auf das kleinste Element nur ein
Schritt erforderlich ist.
Datenstruktur, die den Zugriff auf das kleinste Element
effektiver gestaltet.
Ein Beispiel dafür ist die \texttt{PriorityQueue},
die wir in Hausübung 8 implementiert haben. Dort werden
@ -192,8 +191,26 @@ Elemente beim Einfügen bereits sortiert, sodass der
Zugriff auf das (in diesem Fall) kleinste Element
in $O(1)$, also konstanter Zeit, gemacht werden kann.
Die algorithmische Komplexität mit dieser Änderung
beträgt dann im worst case
$$O(n)$$
Für einen allgemeine Datentyp \texttt{T} kann man
folgendes feststellen:
Sei $x$ die algorithmische Komplexität für das
Suchen vom kleinsten Element (z.B. $x = O(n)$ bei
\texttt{LinkedList}).
Sei $y$ die algorithmische Komplexität für das
Entfernen vom kleinsten Element (bei einer normalen
\texttt{LinkedList} $O(1)$).
Dann beträgt die algorithmische Komplexität
$$O(n \cdot x \cdot y)$$
\subsubsection{Teil (c)}
Sei $n$ die Anzahl an Knoten.
@ -210,18 +227,37 @@ $n - h$ Elemente wurden noch nicht abgearbeitet.
Für alle abgearbeiteten Knoten gilt:
$h$ Knoten sind schon abgearbeitet worden.
Die zu den Knoten zugehörigen \texttt{AlgorithmNodes}-Objekte
beinhalten die insgesamte Länge zu dem Startknoten.
\subsection{Kürzester Pfad zu allen Knoten}
\subsubsection{Teil (a)}
Wenn ein negativer Zyklus auftaucht,
Wenn ein Zykel auftaucht, dann bedeutet
das, dass eine Menge $K$ an Knoten gibt, sodass
$K = \{k_1 ... k_n\}$ und Kanten zwischen $k_1$
und $k_2$ usw. bis $k_n$ und $k_1$ existieren.
Ein negativer Zykel ist dann vorhanden, wenn
$M^0(k_1, k_2) + ... + M^0(k_n, k_1) < 0$.
Oder mathematischer aufgeschrieben:
$$\sum_{l=1}^{n-1} {M^0(k_l, k_{l+1})} + M^0(k_n, k_1) < 0$$
Laut der Schleifeninvariante gilt, dass nach $h \geq 0$
Schritten $M^h$ die Längen von den Pfaden enthält,
die am kürzesten sind und dabei nicht mehr als
$h + 1$ Kanten besuchen.
%Für die Graphmatrix $M$ gilt außerdem
%$M(k_1, k_2) < 0$ usw. bis $M(k_n, k_1) < 0$.
\subsubsection{Teil (b)}
Best case:
Best case: $\Theta()$
Worst case:
Worst case: $\Theta()$
\section{Weitergestaltung des Spiels}
@ -231,6 +267,12 @@ Worst case:
\subsubsection{Begrenzte Rundenanzahl}
Wenn man diese Mission wählt, gilt es, nach einer
festgelegten Anzahl an Runden die meisten Burgen
zu besitzen. Sollten zwei oder mehr Spieler
gleich viele Burgen zu diesem Zeitpunkt in Besitz haben,
gibt es ein Unentschieden.
\subsubsection{Capture the Flag}
In dieser Mission werden wichtige Burgen, sogenannte
@ -257,6 +299,10 @@ wenn die Mission aktiv ist und die Burgen verteilt wurden.
\subsubsection{Bevölkerung}
Das Ziel der Spieler, die diese Mission ausgewählt haben,
ist es, vor allen anderen Spielern eine bestimmte Anzahl
an Truppen auf verschiedenen Burgen stationiert zu haben.
\subsection{Joker}
\end{document}