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

@ -70,7 +70,7 @@ public abstract class GraphAlgorithm<T> {
* @return Der nächste abzuarbeitende Knoten oder null * @return Der nächste abzuarbeitende Knoten oder null
*/ */
private AlgorithmNode<T> getSmallestNode() { private AlgorithmNode<T> getSmallestNode() {
if (DEBUG_2) if (DEBUG_2)
System.out.println("Enter gSN"); System.out.println("Enter gSN");
@ -79,13 +79,15 @@ public abstract class GraphAlgorithm<T> {
} }
Iterator<Node<T>> iter = availableNodes.iterator(); Iterator<Node<T>> iter = availableNodes.iterator();
AlgorithmNode<T> MinElem; Iterator<Node<T>> minElemIter = availableNodes.iterator();
AlgorithmNode<T> minElem;
AlgorithmNode<T> tempElem; AlgorithmNode<T> tempElem;
if (iter.hasNext()) { if (iter.hasNext()) {
// Set minimum to first elements // Set minimum to first element
MinElem = algorithmNodes.get(iter.next()); minElem = algorithmNodes.get(iter.next());
minElemIter.next();
while (iter.hasNext()) { while (iter.hasNext()) {
@ -99,15 +101,18 @@ public abstract class GraphAlgorithm<T> {
tempElem = algorithmNodes.get(iter.next()); tempElem = algorithmNodes.get(iter.next());
if (tempElem.value > 0) { if (tempElem.value > 0) {
if (tempElem.value < MinElem.value) { if (tempElem.value < minElem.value) {
MinElem = tempElem;
// 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) if (prevNode == null)
return null; return null;
while (!prevNode.node.equals(destination)) { while (!(prevNode.value == 0)) {
AlgorithmNode<T> prevPrevNode = prevNode.previous; AlgorithmNode<T> prevPrevNode = prevNode.previous;

View file

@ -15,7 +15,7 @@ public class GraphAlgoComplexityTest {
@Test @Test
public void 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); Graph<Integer> g = generateGraph(i);
DumbGraphAlgorithm ga = new DumbGraphAlgorithm(g, g.getNodes().get(0)); 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); double divN3 = (double)ga.getN() / ((double)i*i*i);
System.out.println(i + "," + ga.getN() + "," + divN + "," + divN2 + "," + divN3); 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(); //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 class DumbGraphAlgorithm extends GraphAlgorithm<Integer> {
public DumbGraphAlgorithm(Graph<Integer> graph, Node<Integer> sourceNode) { public DumbGraphAlgorithm(Graph<Integer> graph, Node<Integer> sourceNode) {

View file

@ -145,7 +145,7 @@ Eine pseudocode-Darstellung des Algorithmus:
\If{edge is passable} \If{edge is passable}
\State $n \gets$ otherNode \State $n \gets$ otherNode
\State $a \gets$ v.value + edge.value \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.value $\gets$ a
\State n.previous $\gets$ v \State n.previous $\gets$ v
\EndIf \EndIf
@ -182,9 +182,8 @@ Knoten eine Kante mit sich selber haben kann.
\subsubsection{Teil (b)} \subsubsection{Teil (b)}
Anstelle einer \texttt{LinkedList} braucht man eine Anstelle einer \texttt{LinkedList} braucht man eine
Datenstruktur, die bereits nach der Größe sortiert ist, Datenstruktur, die den Zugriff auf das kleinste Element
damit bei dem Zugriff auf das kleinste Element nur ein effektiver gestaltet.
Schritt erforderlich ist.
Ein Beispiel dafür ist die \texttt{PriorityQueue}, Ein Beispiel dafür ist die \texttt{PriorityQueue},
die wir in Hausübung 8 implementiert haben. Dort werden 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 Zugriff auf das (in diesem Fall) kleinste Element
in $O(1)$, also konstanter Zeit, gemacht werden kann. in $O(1)$, also konstanter Zeit, gemacht werden kann.
Die algorithmische Komplexität mit dieser Änderung
beträgt dann im worst case
$$O(n)$$ $$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)} \subsubsection{Teil (c)}
Sei $n$ die Anzahl an Knoten. Sei $n$ die Anzahl an Knoten.
@ -210,18 +227,37 @@ $n - h$ Elemente wurden noch nicht abgearbeitet.
Für alle abgearbeiteten Knoten gilt: Für alle abgearbeiteten Knoten gilt:
$h$ Knoten sind schon abgearbeitet worden. $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} \subsection{Kürzester Pfad zu allen Knoten}
\subsubsection{Teil (a)} \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)} \subsubsection{Teil (b)}
Best case: Best case: $\Theta()$
Worst case: Worst case: $\Theta()$
\section{Weitergestaltung des Spiels} \section{Weitergestaltung des Spiels}
@ -231,6 +267,12 @@ Worst case:
\subsubsection{Begrenzte Rundenanzahl} \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} \subsubsection{Capture the Flag}
In dieser Mission werden wichtige Burgen, sogenannte In dieser Mission werden wichtige Burgen, sogenannte
@ -257,6 +299,10 @@ wenn die Mission aktiv ist und die Burgen verteilt wurden.
\subsubsection{Bevölkerung} \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} \subsection{Joker}
\end{document} \end{document}