From fa236a612fd6d35307d09542a83f001b148c4d2e Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Sun, 22 Mar 2020 19:24:52 +0100 Subject: [PATCH] Implemented all functions to pass all tests --- .../main/java/org/insa/graphs/model/Path.java | 123 +++++++++++------- 1 file changed, 77 insertions(+), 46 deletions(-) diff --git a/be-graphes-model/src/main/java/org/insa/graphs/model/Path.java b/be-graphes-model/src/main/java/org/insa/graphs/model/Path.java index 42c23dd..9ac73cb 100644 --- a/be-graphes-model/src/main/java/org/insa/graphs/model/Path.java +++ b/be-graphes-model/src/main/java/org/insa/graphs/model/Path.java @@ -8,68 +8,105 @@ import java.util.List; *

* Class representing a path between nodes in a graph. *

- * + * *

* A path is represented as a list of {@link Arc} with an origin and not a list * of {@link Node} due to the multi-graph nature (multiple arcs between two * nodes) of the considered graphs. *

- * */ public class Path { /** * Create a new path that goes through the given list of nodes (in order), * choosing the fastest route if multiple are available. - * + * * @param graph Graph containing the nodes in the list. * @param nodes List of nodes to build the path. - * * @return A path that goes through the given list of nodes. - * * @throws IllegalArgumentException If the list of nodes is not valid, i.e. two - * consecutive nodes in the list are not connected in the graph. - * - * @deprecated Need to be implemented. + * consecutive nodes in the list are not connected in the graph. */ public static Path createFastestPathFromNodes(Graph graph, List nodes) throws IllegalArgumentException { - List arcs = new ArrayList(); - // TODO: - return new Path(graph, arcs); + return Path.createSmallestPath(graph, nodes, false); } /** * Create a new path that goes through the given list of nodes (in order), * choosing the shortest route if multiple are available. - * + * * @param graph Graph containing the nodes in the list. * @param nodes List of nodes to build the path. - * * @return A path that goes through the given list of nodes. - * * @throws IllegalArgumentException If the list of nodes is not valid, i.e. two - * consecutive nodes in the list are not connected in the graph. - * - * @deprecated Need to be implemented. + * consecutive nodes in the list are not connected in the graph. */ public static Path createShortestPathFromNodes(Graph graph, List nodes) throws IllegalArgumentException { - List arcs = new ArrayList(); - // TODO: + return Path.createSmallestPath(graph, nodes, true); + } + + /** + * Create a new path that goes through the given list of nodes (in order), + * choosing the shortest or fastest route if multiple are available. + * + * @param graph Graph containing the nodes in the list. + * @param nodes List of nodes to build the path. + * @param isLength Should we search the shortest path (true) or the fastest path (false) + * @return A path that goes through the given list of nodes. + * @throws IllegalArgumentException If the list of nodes is not valid, i.e. two + * consecutive nodes in the list are not connected in the graph. + */ + private static Path createSmallestPath(Graph graph, List nodes, boolean isLength) { + List arcs = new ArrayList<>(); + if (nodes.size() != 0 && nodes.size() != 1) { + for (int i = 0; i < (nodes.size() - 1); i++) { + Arc shortest = Path.getSmallestArc( + nodes.get(i).getSuccessors(), nodes.get(i + 1), isLength + ); + arcs.add(shortest); + } + } else if (nodes.size() == 1) + return new Path(graph, nodes.get(0)); return new Path(graph, arcs); } + /** + * Gets the smallest arc in the given list. + * If an arc destination does not match the given node, it is ignored. + * + * @param arcs The arcs list to search in + * @param nextNode The next node to match the arc destination + * @param isLength Should we search the shortest arc (true) or the fastest arc (false) + * @return The smallest arc to nextNode + * @throws IllegalArgumentException If no node is found + */ + private static Arc getSmallestArc(List arcs, Node nextNode, boolean isLength) { + Arc shortestArc = null; + double smallestComparator = -1; + for (Arc arc : arcs) { + if (nextNode.equals(arc.getDestination())) { + double comparator = isLength ? arc.getLength() : arc.getMinimumTravelTime(); + if (comparator < smallestComparator || smallestComparator < 0) { + smallestComparator = comparator; + shortestArc = arc; + } + } + } + if (shortestArc == null) + throw new IllegalArgumentException(); + return shortestArc; + } + /** * Concatenate the given paths. - * + * * @param paths Array of paths to concatenate. - * * @return Concatenated path. - * * @throws IllegalArgumentException if the paths cannot be concatenated (IDs of - * map do not match, or the end of a path is not the beginning of the - * next). + * map do not match, or the end of a path is not the beginning of the + * next). */ public static Path concatenate(Path... paths) throws IllegalArgumentException { if (paths.length == 0) { @@ -83,7 +120,7 @@ public class Path { } } ArrayList arcs = new ArrayList<>(); - for (Path path: paths) { + for (Path path : paths) { arcs.addAll(path.getArcs()); } Path path = new Path(paths[0].getGraph(), arcs); @@ -105,7 +142,7 @@ public class Path { /** * Create an empty path corresponding to the given graph. - * + * * @param graph Graph containing the path. */ public Path(Graph graph) { @@ -116,9 +153,9 @@ public class Path { /** * Create a new path containing a single node. - * + * * @param graph Graph containing the path. - * @param node Single node of the path. + * @param node Single node of the path. */ public Path(Graph graph, Node node) { this.graph = graph; @@ -128,9 +165,9 @@ public class Path { /** * Create a new path with the given list of arcs. - * + * * @param graph Graph containing the path. - * @param arcs Arcs to construct the path. + * @param arcs Arcs to construct the path. */ public Path(Graph graph, List arcs) { this.graph = graph; @@ -168,7 +205,7 @@ public class Path { /** * Check if this path is empty (it does not contain any node). - * + * * @return true if this path is empty, false otherwise. */ public boolean isEmpty() { @@ -177,7 +214,7 @@ public class Path { /** * Get the number of nodes in this path. - * + * * @return Number of nodes in this path. */ public int size() { @@ -186,7 +223,7 @@ public class Path { /** * Check if this path is valid. - * + *

* A path is valid if any of the following is true: *

    *
  • it is empty;
  • @@ -195,10 +232,8 @@ public class Path { * consecutive arcs, the destination of the first one is the origin of the * second one. *
- * + * * @return true if the path is valid, false otherwise. - * - * @deprecated Need to be implemented. */ public boolean isValid() { boolean valid = isEmpty() || (this.arcs.size() == 0 && this.origin != null); @@ -206,7 +241,7 @@ public class Path { valid = this.arcs.get(0).getOrigin().equals(this.origin); for (int i = 1; i < 3; i++) { if (this.arcs.size() > i) - valid = valid && (this.arcs.get(i).getOrigin().equals(this.arcs.get(i-1).getDestination())); + valid = valid && (this.arcs.get(i).getOrigin().equals(this.arcs.get(i - 1).getDestination())); } } return valid; @@ -214,9 +249,8 @@ public class Path { /** * Compute the length of this path (in meters). - * - * @return Total length of the path (in meters). * + * @return Total length of the path (in meters). */ public float getLength() { float length = 0; @@ -228,12 +262,10 @@ public class Path { /** * Compute the time required to travel this path if moving at the given speed. - * - * @param speed Speed to compute the travel time. - * - * @return Time (in seconds) required to travel this path at the given speed (in - * kilometers-per-hour). * + * @param speed Speed to compute the travel time. + * @return Time (in seconds) required to travel this path at the given speed (in + * kilometers-per-hour). */ public double getTravelTime(double speed) { float time = 0; @@ -246,9 +278,8 @@ public class Path { /** * Compute the time to travel this path if moving at the maximum allowed speed * on every arc. - * - * @return Minimum travel time to travel this path (in seconds). * + * @return Minimum travel time to travel this path (in seconds). */ public double getMinimumTravelTime() { float time = 0;