No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Path.java 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. package org.insa.graphs.model;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. /**
  6. * <p>
  7. * Class representing a path between nodes in a graph.
  8. * </p>
  9. *
  10. * <p>
  11. * A path is represented as a list of {@link Arc} with an origin and not a list
  12. * of {@link Node} due to the multi-graph nature (multiple arcs between two
  13. * nodes) of the considered graphs.
  14. * </p>
  15. *
  16. */
  17. public class Path {
  18. /**
  19. * Create a new path that goes through the given list of nodes (in order),
  20. * choosing the fastest route if multiple are available.
  21. *
  22. * @param graph Graph containing the nodes in the list.
  23. * @param nodes List of nodes to build the path.
  24. *
  25. * @return A path that goes through the given list of nodes.
  26. *
  27. * @throws IllegalArgumentException If the list of nodes is not valid, i.e. two
  28. * consecutive nodes in the list are not connected in the graph.
  29. *
  30. * @deprecated Need to be implemented.
  31. */
  32. public static Path createFastestPathFromNodes(Graph graph, List<Node> nodes)
  33. throws IllegalArgumentException {
  34. List<Arc> arcs = new ArrayList<Arc>();
  35. // TODO:
  36. return new Path(graph, arcs);
  37. }
  38. /**
  39. * Create a new path that goes through the given list of nodes (in order),
  40. * choosing the shortest route if multiple are available.
  41. *
  42. * @param graph Graph containing the nodes in the list.
  43. * @param nodes List of nodes to build the path.
  44. *
  45. * @return A path that goes through the given list of nodes.
  46. *
  47. * @throws IllegalArgumentException If the list of nodes is not valid, i.e. two
  48. * consecutive nodes in the list are not connected in the graph.
  49. *
  50. */
  51. public static Path createShortestPathFromNodes(Graph graph, List<Node> nodes)
  52. throws IllegalArgumentException {
  53. List<Arc> arcs = new ArrayList<Arc>();
  54. boolean suiv;
  55. Arc bonarc;
  56. for (int i=0;i<nodes.size()-1;i++) {
  57. if (nodes.get(i).getNumberOfSuccessors()<=0)
  58. throw new IllegalArgumentException();
  59. bonarc=Node.linkNodes(null, null, Float.MAX_VALUE, null, null);
  60. for (int parcourt=0; parcourt<nodes.get(i).getNumberOfSuccessors(); parcourt++) {
  61. suiv=false;
  62. if (nodes.get(i).getSuccessors().get(parcourt).getDestination()==nodes.get(i+1)) {
  63. if (nodes.get(i).getSuccessors().get(parcourt).getLength()<bonarc.getLength()) {
  64. bonarc=nodes.get(i).getSuccessors().get(parcourt);
  65. suiv=true;
  66. }
  67. }
  68. if (!suiv)
  69. throw new IllegalArgumentException();
  70. }
  71. arcs.add(bonarc);
  72. }
  73. return new Path(graph, arcs);
  74. }
  75. /**
  76. * Concatenate the given paths.
  77. *
  78. * @param paths Array of paths to concatenate.
  79. *
  80. * @return Concatenated path.
  81. *
  82. * @throws IllegalArgumentException if the paths cannot be concatenated (IDs of
  83. * map do not match, or the end of a path is not the beginning of the
  84. * next).
  85. */
  86. public static Path concatenate(Path... paths) throws IllegalArgumentException {
  87. if (paths.length == 0) {
  88. throw new IllegalArgumentException("Cannot concatenate an empty list of paths.");
  89. }
  90. final String mapId = paths[0].getGraph().getMapId();
  91. for (int i = 1; i < paths.length; ++i) {
  92. if (!paths[i].getGraph().getMapId().equals(mapId)) {
  93. throw new IllegalArgumentException(
  94. "Cannot concatenate paths from different graphs.");
  95. }
  96. }
  97. ArrayList<Arc> arcs = new ArrayList<>();
  98. for (Path path: paths) {
  99. arcs.addAll(path.getArcs());
  100. }
  101. Path path = new Path(paths[0].getGraph(), arcs);
  102. if (!path.isValid()) {
  103. throw new IllegalArgumentException(
  104. "Cannot concatenate paths that do not form a single path.");
  105. }
  106. return path;
  107. }
  108. // Graph containing this path.
  109. private final Graph graph;
  110. // Origin of the path
  111. private final Node origin;
  112. // List of arcs in this path.
  113. private final List<Arc> arcs;
  114. /**
  115. * Create an empty path corresponding to the given graph.
  116. *
  117. * @param graph Graph containing the path.
  118. */
  119. public Path(Graph graph) {
  120. this.graph = graph;
  121. this.origin = null;
  122. this.arcs = new ArrayList<>();
  123. }
  124. /**
  125. * Create a new path containing a single node.
  126. *
  127. * @param graph Graph containing the path.
  128. * @param node Single node of the path.
  129. */
  130. public Path(Graph graph, Node node) {
  131. this.graph = graph;
  132. this.origin = node;
  133. this.arcs = new ArrayList<>();
  134. }
  135. /**
  136. * Create a new path with the given list of arcs.
  137. *
  138. * @param graph Graph containing the path.
  139. * @param arcs Arcs to construct the path.
  140. */
  141. public Path(Graph graph, List<Arc> arcs) {
  142. this.graph = graph;
  143. this.arcs = arcs;
  144. this.origin = arcs.size() > 0 ? arcs.get(0).getOrigin() : null;
  145. }
  146. /**
  147. * @return Graph containing the path.
  148. */
  149. public Graph getGraph() {
  150. return graph;
  151. }
  152. /**
  153. * @return First node of the path.
  154. */
  155. public Node getOrigin() {
  156. return origin;
  157. }
  158. /**
  159. * @return Last node of the path.
  160. */
  161. public Node getDestination() {
  162. return arcs.get(arcs.size() - 1).getDestination();
  163. }
  164. /**
  165. * @return List of arcs in the path.
  166. */
  167. public List<Arc> getArcs() {
  168. return Collections.unmodifiableList(arcs);
  169. }
  170. /**
  171. * Check if this path is empty (it does not contain any node).
  172. *
  173. * @return true if this path is empty, false otherwise.
  174. */
  175. public boolean isEmpty() {
  176. return this.origin == null;
  177. }
  178. /**
  179. * Get the number of <b>nodes</b> in this path.
  180. *
  181. * @return Number of nodes in this path.
  182. */
  183. public int size() {
  184. return isEmpty() ? 0 : 1 + this.arcs.size();
  185. }
  186. /**
  187. * Check if this path is valid.
  188. *
  189. * A path is valid if any of the following is true:
  190. * <ul>
  191. * <li>it is empty;</li>
  192. * <li>it contains a single node (without arcs);</li>
  193. * <li>the first arc has for origin the origin of the path and, for two
  194. * consecutive arcs, the destination of the first one is the origin of the
  195. * second one.</li>
  196. * </ul>
  197. *
  198. * @return true if the path is valid, false otherwise.
  199. *
  200. */
  201. public boolean isValid() {
  202. boolean bool=true;
  203. if (!this.isEmpty() && !this.arcs.isEmpty()) {
  204. if (this.origin!=this.arcs.get(0).getOrigin())
  205. bool=false;
  206. else if (this.arcs.size()>1) {
  207. for (int i=0;i<this.arcs.size()-1;i++) {
  208. if (this.arcs.get(i).getDestination()!=this.arcs.get(i+1).getOrigin())
  209. bool=false;
  210. }
  211. }
  212. }
  213. return bool;
  214. }
  215. /**
  216. * Compute the length of this path (in meters).
  217. *
  218. * @return Total length of the path (in meters).
  219. *
  220. */
  221. public float getLength() {
  222. float longeur=0;
  223. for (int i=0;i<this.arcs.size();i++) {
  224. longeur+=this.arcs.get(i).getLength();
  225. }
  226. return longeur;
  227. }
  228. /**
  229. * Compute the time required to travel this path if moving at the given speed.
  230. *
  231. * @param speed Speed to compute the travel time.
  232. *
  233. * @return Time (in seconds) required to travel this path at the given speed (in
  234. * kilometers-per-hour).
  235. *
  236. */
  237. public double getTravelTime(double speed) {
  238. return this.getLength()*3.6/speed;
  239. }
  240. /**
  241. * Compute the time to travel this path if moving at the maximum allowed speed
  242. * on every arc.
  243. *
  244. * @return Minimum travel time to travel this path (in seconds).
  245. *
  246. */
  247. public double getMinimumTravelTime() {
  248. double temps=0.0;
  249. for (int i=0;i<this.arcs.size();i++) {
  250. temps+=this.arcs.get(i).getMinimumTravelTime();
  251. }
  252. return temps;
  253. }
  254. }