From 221782f2c11082fc7ed8c9f63ada0294ca8be648 Mon Sep 17 00:00:00 2001 From: stiv2804 Date: Thu, 14 Feb 2019 16:35:06 +0100 Subject: [PATCH] solved 3.1.3 getSmallestNode --- .../src/base/GraphAlgorithm.java | 273 ++++++++++-------- 1 file changed, 148 insertions(+), 125 deletions(-) diff --git a/Projektgruppe_175/src/base/GraphAlgorithm.java b/Projektgruppe_175/src/base/GraphAlgorithm.java index baa1f6b..30ddbc7 100644 --- a/Projektgruppe_175/src/base/GraphAlgorithm.java +++ b/Projektgruppe_175/src/base/GraphAlgorithm.java @@ -1,125 +1,148 @@ -package base; - -import java.util.*; - -/** - * Abstrakte generische Klasse um Wege zwischen Knoten in einem Graph zu finden. - * Eine implementierende Klasse ist beispielsweise {@link game.map.PathFinding} - * @param Die Datenstruktur des Graphen - */ -public abstract class GraphAlgorithm { - - /** - * Innere Klasse um {@link Node} zu erweitern, aber nicht zu verändern - * Sie weist jedem Knoten einen Wert und einen Vorgängerknoten zu. - * @param - */ - private static class AlgorithmNode { - - private Node node; - private double value; - private AlgorithmNode previous; - - AlgorithmNode(Node parentNode, AlgorithmNode previousNode, double value) { - this.node = parentNode; - this.previous = previousNode; - this.value = value; - } - } - - private Graph graph; - - // Diese Liste enthält alle Knoten, die noch nicht abgearbeitet wurden - private List> availableNodes; - - // Diese Map enthält alle Zuordnungen - private Map, AlgorithmNode> algorithmNodes; - - /** - * Erzeugt ein neues GraphAlgorithm-Objekt mit dem dazugehörigen Graphen und dem Startknoten. - * @param graph der zu betrachtende Graph - * @param sourceNode der Startknoten - */ - public GraphAlgorithm(Graph graph, Node sourceNode) { - this.graph = graph; - this.availableNodes = new LinkedList<>(graph.getNodes()); - this.algorithmNodes = new HashMap<>(); - - for(Node node : graph.getNodes()) - this.algorithmNodes.put(node, new AlgorithmNode<>(node, null, -1)); - - this.algorithmNodes.get(sourceNode).value = 0; - } - - /** - * Diese Methode gibt einen Knoten mit dem kleinsten Wert, der noch nicht abgearbeitet wurde, zurück und entfernt ihn aus der Liste {@link #availableNodes}. - * Sollte kein Knoten gefunden werden, wird null zurückgegeben. - * Verbindliche Anforderung: Verwenden Sie beim Durchlaufen der Liste Iteratoren - * @return Der nächste abzuarbeitende Knoten oder null - */ - private AlgorithmNode getSmallestNode() { - // TODO: GraphAlgorithm#getSmallestNode() - return null; - } - - /** - * Diese Methode startet den Algorithmus. Dieser funktioniert wie folgt: - * 1. Suche den Knoten mit dem geringsten Wert (siehe {@link #getSmallestNode()}) - * 2. Für jede angrenzende Kante: - * 2a. Überprüfe ob die Kante passierbar ist ({@link #isPassable(Edge)}) - * 2b. Berechne den Wert des Knotens, in dem du den aktuellen Wert des Knotens und den der Kante addierst - * 2c. Ist der alte Wert nicht gesetzt (-1) oder ist der neue Wert kleiner, setze den neuen Wert und den Vorgängerknoten - * 3. Wiederhole solange, bis alle Knoten abgearbeitet wurden - - * Nützliche Methoden: - * @see #getSmallestNode() - * @see #isPassable(Edge) - * @see Graph#getEdges(Node) - * @see Edge#getOtherNode(Node) - */ - public void run() { - // TODO: GraphAlgorithm#run() - } - - /** - * Diese Methode gibt eine Liste von Kanten zurück, die einen Pfad zu dem angegebenen Zielknoten representiert. - * Dabei werden zuerst beginnend mit dem Zielknoten alle Kanten mithilfe des Vorgängerattributs {@link AlgorithmNode#previous} zu der Liste hinzugefügt. - * Zum Schluss muss die Liste nur noch umgedreht werden. Sollte kein Pfad existieren, geben Sie null zurück. - * @param destination Der Zielknoten des Pfads - * @return eine Liste von Kanten oder null - */ - public List> getPath(Node destination) { - // TODO: GraphAlgorithm#getPath(Node) - return null; - } - - /** - * Gibt den betrachteten Graphen zurück - * @return der zu betrachtende Graph - */ - protected Graph getGraph() { - return this.graph; - } - - /** - * Gibt den Wert einer Kante zurück. - * Diese Methode ist abstrakt und wird in den implementierenden Klassen definiert um eigene Kriterien für Werte zu ermöglichen. - * @param edge Eine Kante - * @return Ein Wert, der der Kante zugewiesen wird - */ - protected abstract double getValue(Edge edge); - - /** - * Gibt an, ob eine Kante passierbar ist. - * @param edge Eine Kante - * @return true, wenn die Kante passierbar ist. - */ - protected abstract boolean isPassable(Edge edge); - - /** - * Gibt an, ob eine Knoten passierbar ist. - * @param node Eine Knoten - * @return true, wenn der Knoten passierbar ist. - */ - protected abstract boolean isPassable(Node node); -} +package base; + +import java.util.*; + +/** + * Abstrakte generische Klasse um Wege zwischen Knoten in einem Graph zu finden. + * Eine implementierende Klasse ist beispielsweise {@link game.map.PathFinding} + * @param Die Datenstruktur des Graphen + */ +public abstract class GraphAlgorithm { + + /** + * Innere Klasse um {@link Node} zu erweitern, aber nicht zu verändern + * Sie weist jedem Knoten einen Wert und einen Vorgängerknoten zu. + * @param + */ + private static class AlgorithmNode { + + private Node node; + private double value; + private AlgorithmNode previous; + + AlgorithmNode(Node parentNode, AlgorithmNode previousNode, double value) { + this.node = parentNode; + this.previous = previousNode; + this.value = value; + } + } + + private Graph graph; + + // Diese Liste enthält alle Knoten, die noch nicht abgearbeitet wurden + private List> availableNodes; + + // Diese Map enthält alle Zuordnungen + private Map, AlgorithmNode> algorithmNodes; + + /** + * Erzeugt ein neues GraphAlgorithm-Objekt mit dem dazugehörigen Graphen und dem Startknoten. + * @param graph der zu betrachtende Graph + * @param sourceNode der Startknoten + */ + public GraphAlgorithm(Graph graph, Node sourceNode) { + this.graph = graph; + this.availableNodes = new LinkedList<>(graph.getNodes()); + this.algorithmNodes = new HashMap<>(); + + for(Node node : graph.getNodes()) + this.algorithmNodes.put(node, new AlgorithmNode<>(node, null, -1)); + + this.algorithmNodes.get(sourceNode).value = 0; + } + + /** + * Diese Methode gibt einen Knoten mit dem kleinsten Wert, der noch nicht abgearbeitet wurde, zurück und entfernt ihn aus der Liste {@link #availableNodes}. + * Sollte kein Knoten gefunden werden, wird null zurückgegeben. + * Verbindliche Anforderung: Verwenden Sie beim Durchlaufen der Liste Iteratoren + * @return Der nächste abzuarbeitende Knoten oder null + */ + private AlgorithmNode getSmallestNode() { + // TODO: GraphAlgorithm#getSmallestNode() + if(availableNodes.isEmpty()) + { + return null; + } + Iterator> iter = availableNodes.iterator(); + Iterator> iterMinElem = iter; + AlgorithmNode MinElem; + AlgorithmNode tempElem; + if(iter.hasNext()) + { + MinElem = algorithmNodes.get(iter.next()); + while (iter.hasNext()) + { + tempElem = algorithmNodes.get(iter.next()); + if(tempElem.value < MinElem.value) + { + iterMinElem = iter; + MinElem = tempElem; + } + } + iter.remove(); + return MinElem; + } + return null; + } + + /** + * Diese Methode startet den Algorithmus. Dieser funktioniert wie folgt: + * 1. Suche den Knoten mit dem geringsten Wert (siehe {@link #getSmallestNode()}) + * 2. Für jede angrenzende Kante: + * 2a. Überprüfe ob die Kante passierbar ist ({@link #isPassable(Edge)}) + * 2b. Berechne den Wert des Knotens, in dem du den aktuellen Wert des Knotens und den der Kante addierst + * 2c. Ist der alte Wert nicht gesetzt (-1) oder ist der neue Wert kleiner, setze den neuen Wert und den Vorgängerknoten + * 3. Wiederhole solange, bis alle Knoten abgearbeitet wurden + + * Nützliche Methoden: + * @see #getSmallestNode() + * @see #isPassable(Edge) + * @see Graph#getEdges(Node) + * @see Edge#getOtherNode(Node) + */ + public void run() { + // TODO: GraphAlgorithm#run() + } + + /** + * Diese Methode gibt eine Liste von Kanten zurück, die einen Pfad zu dem angegebenen Zielknoten representiert. + * Dabei werden zuerst beginnend mit dem Zielknoten alle Kanten mithilfe des Vorgängerattributs {@link AlgorithmNode#previous} zu der Liste hinzugefügt. + * Zum Schluss muss die Liste nur noch umgedreht werden. Sollte kein Pfad existieren, geben Sie null zurück. + * @param destination Der Zielknoten des Pfads + * @return eine Liste von Kanten oder null + */ + public List> getPath(Node destination) { + // TODO: GraphAlgorithm#getPath(Node) + return null; + } + + /** + * Gibt den betrachteten Graphen zurück + * @return der zu betrachtende Graph + */ + protected Graph getGraph() { + return this.graph; + } + + /** + * Gibt den Wert einer Kante zurück. + * Diese Methode ist abstrakt und wird in den implementierenden Klassen definiert um eigene Kriterien für Werte zu ermöglichen. + * @param edge Eine Kante + * @return Ein Wert, der der Kante zugewiesen wird + */ + protected abstract double getValue(Edge edge); + + /** + * Gibt an, ob eine Kante passierbar ist. + * @param edge Eine Kante + * @return true, wenn die Kante passierbar ist. + */ + protected abstract boolean isPassable(Edge edge); + + /** + * Gibt an, ob eine Knoten passierbar ist. + * @param node Eine Knoten + * @return true, wenn der Knoten passierbar ist. + */ + protected abstract boolean isPassable(Node node); +}