Advertisement
moreiramota

Untitled

Jan 8th, 2019
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.45 KB | None | 0 0
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package lapr.project.utils;
  7.  
  8. import java.util.ArrayList;
  9. import java.util.Collections;
  10. import java.util.HashSet;
  11. import java.util.Iterator;
  12. import java.util.LinkedList;
  13. import java.util.List;
  14. import java.util.Set;
  15. import lapr.project.model.Journey;
  16. import lapr.project.model.Park;
  17. import lapr.project.model.Point;
  18. import lapr.project.model.TouristicPoint;
  19. import lapr.project.model.User;
  20.  
  21. /**
  22. *
  23. * @author Vasco_Rodrigues
  24. */
  25. public class GraphAlgorithms extends GraphHandler {
  26.  
  27. public static final boolean ASCENDING = true;
  28. public static final boolean DESCENDING = false;
  29.  
  30. public GraphAlgorithms(User user) {
  31. super(user);
  32. }
  33.  
  34. public LinkedList<Point> getShortestPath(Point orig, Point dest, Attribute att) {
  35.  
  36. int size = graph.numVertices();
  37.  
  38. Point[] points = new Point[size];
  39. Iterator<Point> it = graph.vertices().iterator();
  40. for (int i = 0; i < size; i++) {
  41. points[i] = it.next();
  42. }
  43.  
  44. LinkedList<Point> path = new LinkedList<>();
  45. for (Integer i : getSmallestRoute(orig, dest, att, points).track) {
  46. path.add(points[i]);
  47. }
  48. return path;
  49. }
  50.  
  51. private Track getSmallestRoute(Point vOrig, Point vDest, Attribute att, Point[] points) {
  52.  
  53. int size = graph.numVertices();
  54.  
  55. boolean[] visited = new boolean[size];
  56.  
  57. int[] pathKeys = new int[size];
  58. double[] dist = new double[size];
  59.  
  60. for (int i = 0; i < size; i++) {
  61. dist[i] = Double.MAX_VALUE;
  62. pathKeys[i] = -1;
  63. }
  64. int ogIndex = indexOf(vOrig, points);
  65. dist[ogIndex] = 0;
  66. shortestRoute(ogIndex, points, visited, pathKeys, dist, vDest, att);
  67. Track sp = new Track();
  68. buildPath(vOrig, vDest, points, pathKeys, sp);
  69. sp = revPath(sp);
  70. sp.weight = dist[sp.getLastVert()];
  71. return sp;
  72. }
  73.  
  74. /**
  75. * Computes shortest-path distance from a source vertex to all reachable
  76. * vertices of a graph g with nonnegative edge weights This implementation
  77. * uses Dijkstra's algorithm
  78. *
  79. * @param vOrig Vertex that will be the source of the path
  80. * @param vertices
  81. * @param visited set of discovered vertices
  82. * @param pathKeys minimum path vertices keys
  83. * @param dist minimum distances
  84. * @param verticeParagem
  85. */
  86. private void shortestRoute(int indexOrigin, Point[] vertices,
  87. boolean[] visited, int[] pathKeys, double[] dist, Point verticeParagem, Attribute att) {
  88.  
  89. visited[indexOrigin] = true;
  90.  
  91. if (vertices[indexOrigin].equals(verticeParagem)) {
  92. return;
  93. }
  94.  
  95. int indexVert;
  96. for (Edge<Point, Path> edge : graph.outgoingEdges(vertices[indexOrigin])) {
  97.  
  98. indexVert = indexOf(edge.getVDest(), vertices);
  99. Double addedWeight = 0.0;
  100. if (!visited[indexVert]) {
  101. if (att.equals(ENERGY)) {
  102. //addedWeight = Journey.calculateEnergyBetweenTwoLocations(edge.getVOrig().getLocation(), edge.getVDest().getLocation(), user, user.getAverageSpeed(), BICYCLE, GraphHandler.PATH);
  103. } else {
  104. addedWeight = getAttribute(edge, att);
  105. }
  106. if (addedWeight != null && addedWeight >= 0) {
  107. double weight = dist[indexOrigin] + addedWeight;
  108. if (dist[indexVert] > weight) {
  109. dist[indexVert] = weight;
  110. pathKeys[indexVert] = indexOrigin;
  111. }
  112. }
  113. }
  114. }
  115.  
  116. indexVert = getLowestDist(dist, visited);
  117.  
  118. if (indexVert == -1) {
  119. return;
  120. }
  121. shortestRoute(indexVert, vertices, visited, pathKeys, dist, verticeParagem, att);
  122. }
  123.  
  124. private static <V, E> int getLowestDist(double[] distancias, boolean[] visited) {
  125. double lowest = Double.MAX_VALUE;
  126. int index = -1;
  127. for (int i = 0; i < distancias.length; i++) {
  128. if (distancias[i] < lowest) {
  129. if (!visited[i]) {
  130. lowest = distancias[i];
  131. index = i;
  132. }
  133. }
  134. }
  135. return index;
  136. }
  137.  
  138. private static <V, E> int indexOf(V vertice, V[] vertices) {
  139. for (int i = 0; i < vertices.length; i++) {
  140. if (vertices[i].equals(vertice)) {
  141. return i;
  142. }
  143. }
  144. return -1;
  145. }
  146.  
  147. /**
  148. * Reverses the path
  149. *
  150. * @param path stack with path
  151. */
  152. private Track revPath(Track path) {
  153.  
  154. Track pathrev = new Track();
  155. int size = path.track.size();
  156. for (int i = size - 1; i >= 0; i--) {
  157. pathrev.track.add(path.track.get(i));
  158. }
  159.  
  160. return pathrev;
  161. }
  162.  
  163. /**
  164. * Extracts from pathKeys the minimum path between voInf and vdInf The path
  165. * is constructed from the end to the beginning
  166. *
  167. * @param vOrig information of the Vertex origin
  168. * @param vDest information of the Vertex destination
  169. * @param verts
  170. * @param pathKeys minimum path vertices keys
  171. * @param path stack with the minimum path (correct order)
  172. */
  173. private static void buildPath(Point vOrig, Point vDest, Point[] verts, int[] pathKeys, Track path) {
  174. int index = indexOf(vDest, verts);
  175. int indexOG = indexOf(vOrig, verts);
  176. if (indexOG == -1 || index == -1) {
  177. return;
  178. }
  179.  
  180. do {
  181. path.track.add(index);
  182. index = pathKeys[index];
  183. } while (index != -1);
  184.  
  185. }
  186. //-----------------------------------------------
  187.  
  188. public List<LinkedList<Point>> shortestRouteWithCertainPoints(Point origin, Point dest, int minPoints, Set<Point> mustGoes, Attribute att, boolean ordering) {
  189.  
  190. if (!graph.validVertex(origin) || !graph.validVertex(dest)) {
  191. return null;
  192. }
  193.  
  194. if (!(origin instanceof Park) || !(dest instanceof Park)) {
  195. return null;
  196. }
  197.  
  198. int size = graph.numVertices();
  199. Point[] points = new Point[size];
  200. Iterator<Point> it = graph.vertices().iterator();
  201. for (int i = 0; i < size; i++) {
  202. points[i] = it.next();
  203. }
  204.  
  205. LinkedList<Track> allTracks = new LinkedList<>();
  206. Set<Track> finishedTracks = new HashSet<>();
  207. allTracks.add(new Track(indexOf(origin, points)));
  208.  
  209. Set<Integer> mgInteger = new HashSet<>();
  210. for (Point p : mustGoes) {
  211. mgInteger.add(indexOf(p, points));
  212. }
  213.  
  214. List<Track> tracks = new ArrayList<>();
  215.  
  216. //This variable might be initialized by parameter in the future
  217. final int defautlNumberOfResults = 5;
  218.  
  219. recursivePathFinder(tracks, defautlNumberOfResults, allTracks, dest, minPoints, mgInteger, finishedTracks, att, points);
  220.  
  221. int mult;
  222. int index;
  223. if (ordering) {
  224. mult = 1;
  225. index = 0;
  226. } else {
  227. mult = -1;
  228. index = tracks.size() - 1;
  229. }
  230.  
  231. List<LinkedList<Point>> orderedResult = new ArrayList<>();
  232.  
  233. LinkedList<Point> path;
  234. for (int j = 0; j < tracks.size(); j++) {
  235. path = new LinkedList<>();
  236. Track track = tracks.get(index);
  237.  
  238. for (Integer i : track.track) {
  239. path.add(points[i]);
  240. }
  241. orderedResult.add(path);
  242. index += mult;
  243. }
  244.  
  245. return orderedResult;
  246. }
  247.  
  248. private void recursivePathFinder(List<Track> result, int numResults, LinkedList<Track> allTracks, Point vertFim, int minPoints, Set<Integer> mustGoes, Set<Track> finished, Attribute att, Point[] vertices) {
  249. if (allTracks.isEmpty()) {
  250. return;
  251. }
  252. Collections.sort(allTracks);
  253. Track track = allTracks.remove();
  254. if (finished.contains(track)) {
  255. result.add(track);
  256. if (result.size() == numResults) {
  257. return;
  258. }
  259. } else {
  260. for (Edge<Point, Path> edge : graph.getVertex(track.getLastVert()).getAllOutEdges()) {
  261. if (track.validateEdge(edge, vertices)) {
  262. Track sec = new Track(track);
  263. sec.AddEdge(edge, att, vertices);
  264. if (sec.track.containsAll(mustGoes) && sec.numPoints >= minPoints) {
  265. sec.track.remove(sec.track.size() - 1);
  266. Track temp = getSmallestRoute(edge.getVDest(), vertFim, att, vertices);
  267. sec.addAll(temp.track, temp.weight, vertices);
  268. finished.add(sec);
  269. }
  270. allTracks.add(sec);
  271. }
  272. }
  273. }
  274. recursivePathFinder(result, numResults, allTracks, vertFim, minPoints, mustGoes, finished, att, vertices);
  275. }
  276.  
  277. /**
  278. * Inner class Track
  279. *
  280. */
  281. private class Track implements Comparable<Track> {
  282.  
  283. private List<Integer> track;
  284. private double weight;
  285. private int numPoints;
  286.  
  287. public Track() {
  288. weight = 0;
  289. numPoints = 0;
  290. track = new ArrayList<>();
  291.  
  292. }
  293.  
  294. public Track(Integer vertInicial) {
  295. weight = 0;
  296. numPoints = 0;
  297. track = new ArrayList<>();
  298. track.add(vertInicial);
  299. }
  300.  
  301. /**
  302. * Construtor da classe caminho
  303. *
  304. * @param caminho_inicial
  305. * @param weight
  306. */
  307. private Track(Track that) {
  308. this.track = new ArrayList<>(that.track);
  309. this.weight = that.weight;
  310. this.numPoints = that.numPoints;
  311. }
  312.  
  313. /**
  314. * Construtor da classe caminho
  315. *
  316. * @param caminho_inicial
  317. * @param weight
  318. */
  319. private Track(LinkedList<Integer> caminho, double weight) {
  320. this.track = new ArrayList<>(caminho);
  321. this.weight = weight;
  322. }
  323.  
  324. public Integer getLastVert() {
  325. return track.get(track.size() - 1);
  326. }
  327.  
  328. public boolean addAll(List<Integer> list, double weight, Point[] vertices) {
  329. this.weight += weight;
  330. for (Integer p : list) {
  331. if (vertices[p] instanceof TouristicPoint && !track.contains(p)) {
  332. numPoints++;
  333. }
  334. track.add(p);
  335. }
  336. return true;
  337. }
  338.  
  339. public boolean AddEdge(Edge<Point, Path> edge, Attribute att, Point[] vertices) {
  340. if (validateEdge(edge, vertices)) {
  341. double toAdd = getAttribute(edge, att);
  342. if (toAdd >= 0) {
  343. Point p = (edge.getVDest());
  344. weight += toAdd;
  345. if (p instanceof TouristicPoint && !track.contains(indexOf(p, vertices))) {
  346. numPoints++;
  347. }
  348. track.add(indexOf(p, vertices));
  349. return true;
  350. }
  351. return false;
  352. }
  353. return false;
  354. }
  355.  
  356. /**
  357. * Verifica se é possível adicionar um vértice à lista, as condições de
  358. * adição são: Um vértice V não pode ocupar duas posicões consecutivas V
  359. * != penúltimo vértice && último vértice!= penúltimo vértice ou seja, é
  360. * possível um caminho ser ABA, mas nunca AAB ou ABAB
  361. *
  362. * @param edge
  363. * @return
  364. */
  365. public boolean validateEdge(Edge<Point, Path> edge, Point[] vertices) {
  366. int size = track.size();
  367. if (size > 1) {
  368. if (vertices[track.get(size - 1)].equals(edge.getVDest())) {
  369. return false;
  370. }
  371. }
  372. if (size > 2) {
  373. if (track.get(size - 1).equals(track.get(size - 3)) && vertices[track.get(size - 2)].equals(edge.getVDest())) {
  374. return false;
  375. }
  376. }
  377. if (size > 4) {
  378. int index = track.indexOf(track.get(size - 1));
  379. if (index == size - 1) {
  380. return true;
  381. }
  382.  
  383. return !vertices[track.get(index + 1)].equals(edge.getVDest());
  384. }
  385. return true;
  386. }
  387.  
  388. @Override
  389. public int compareTo(Track that) {
  390. if (this.weight > that.weight) {
  391. return 1;
  392. }
  393. if (this.weight < that.weight) {
  394. return -1;
  395. }
  396. return 0;
  397. }
  398.  
  399. @Override
  400. public int hashCode() {
  401. int hash = 5;
  402. return hash;
  403. }
  404.  
  405. @Override
  406. public boolean equals(Object obj) {
  407. if (this == obj) {
  408. return true;
  409. }
  410. if (!(obj instanceof Track)) {
  411. return false;
  412. }
  413. Track that = (Track) obj;
  414. if (Math.abs(this.weight - that.weight) > 0.0001) {
  415. return false;
  416. }
  417. return this.track.equals(that.track);
  418. }
  419. }
  420. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement