Advertisement
Guest User

Untitled

a guest
May 1st, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.21 KB | None | 0 0
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Copyright (C) 2008-2011, The 100GET-E3-R3G Project Team.
  3. *
  4. * This work has been funded by the Federal Ministry of Education
  5. * and Research of the Federal Republic of Germany
  6. * (BMBF Förderkennzeichen 01BP0775). It is part of the EUREKA project
  7. * "100 Gbit/s Carrier-Grade Ethernet Transport Technologies
  8. * (CELTIC CP4-001)". The authors alone are responsible for this work.
  9. *
  10. * See the file AUTHORS for details and contact information.
  11. *
  12. * This file is part of MuLaViTo (Multi-Layer Visualization Tool).
  13. *
  14. * MuLaViTo is free software; you can redistribute it and/or modify it
  15. * under the terms of the GNU General Public License Version 3 or later
  16. * (the "GPL"), or the GNU Lesser General Public License Version 3 or later
  17. * (the "LGPL") as published by the Free Software Foundation.
  18. *
  19. * MuLaViTo is distributed in the hope that it will be useful, but
  20. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  21. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  22. * or the GNU Lesser General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License and
  25. * GNU Lesser General Public License along with MuLaViTo; see the file
  26. * COPYING. If not, see <http://www.gnu.org/licenses/>.
  27. *
  28. * ***** END LICENSE BLOCK ***** */
  29. package mulavito.algorithms.shortestpath.ksp;
  30.  
  31. import java.util.HashMap;
  32. import java.util.HashSet;
  33. import java.util.LinkedList;
  34. import java.util.List;
  35. import java.util.Map;
  36. import java.util.PriorityQueue;
  37. import java.util.Set;
  38.  
  39. import org.apache.commons.collections15.Transformer;
  40. import org.apache.commons.collections15.functors.MapTransformer;
  41.  
  42. import edu.uci.ics.jung.graph.Graph;
  43.  
  44. /**
  45. * Main idea: Translate the problem from one with two terminals (s, t), to a
  46. * problem with only one terminal (s) by finding paths from s to any other
  47. * vertex and concatenating shortest path from that vertex to t.
  48. *
  49. * k shortest paths problem with only one terminal: (breadth first search)
  50. *
  51. * 1. Maintain a priority queue of paths, initially containing the single
  52. * zero-edge path from s to itself.
  53. *
  54. * 2. Repeatedly remove the shortest path from the priority queue, add it to the
  55. * list of output paths and add all one-edge extensions of that path to the
  56. * priority queue.
  57. *
  58. * <p>
  59. * For implementation the following reference was used:
  60. *
  61. * <blockquote>We give algorithms for finding the k shortest paths (not required
  62. * to be simple) connecting a pair of vertices in a digraph. Our algorithms
  63. * output an implicit representation of these paths in a digraph with n vertices
  64. * and m edges, in time <math>O(m + n log n + k)</math>. We can also find the k
  65. * shortest paths from a given source s to each vertex in the graph, in total
  66. * time <math>O(m + n log n + kn)</math>.</blockquote>
  67. *
  68. * <pre>
  69. * @Article{ Eppstein98,
  70. * title = {{Finding the $k$ Shortest Paths}},
  71. * author = {David Eppstein},
  72. * journal = {SIAM J. Computing},
  73. * publisher = {SIAM},
  74. * volume = {28},
  75. * number = {2},
  76. * pages = {652--673},
  77. * year = {1998},
  78. * url = {http://dx.doi.org/10.1137/S0097539795290477},
  79. * review = {MR-99h:05073}
  80. * }
  81. * </pre>
  82. *
  83. * </p>
  84. *
  85. * @author Thilo Müller
  86. * @author Michael Duelli
  87. * @since 2010-11-26
  88. *
  89. * @param <V>
  90. * The parameter for vertices
  91. * @param <E>
  92. * The parameter for edges
  93. */
  94. public class Eppstein<V, E> extends KShortestPathAlgorithm<V, E> {
  95. /**
  96. * Constructor of the Eppstein-K-shortest-Path
  97. *
  98. * @param graph
  99. * the original graph
  100. * @param nev
  101. * the weight transformer
  102. */
  103. public Eppstein(Graph<V, E> graph, Transformer<E, Number> nev) {
  104. super(graph, nev);
  105. }
  106.  
  107. private final class WeightedPath implements Comparable<WeightedPath> {
  108. private final Set<V> path_vertices;
  109. private final List<E> path_edges;
  110. private double weight;
  111. private V lastV;
  112.  
  113. public WeightedPath(V start) {
  114. weight = 0.0;
  115. path_edges = new LinkedList<E>();
  116.  
  117. path_vertices = new HashSet<V>();
  118. path_vertices.add(start);
  119. lastV = start;
  120. }
  121.  
  122. public WeightedPath(WeightedPath copy) {
  123. weight = copy.weight;
  124. path_edges = new LinkedList<E>(copy.path_edges);
  125. path_vertices = new HashSet<V>(copy.path_vertices);
  126. lastV = copy.lastV;
  127. }
  128.  
  129. public void addHop(E via, Double weight, V v) {
  130. this.weight += weight;
  131. path_edges.add(via);
  132. path_vertices.add(v);
  133. lastV = v;
  134. }
  135.  
  136. public V getLast() {
  137. return lastV;
  138. }
  139.  
  140. public boolean contains(V v) {
  141. return path_vertices.contains(v);
  142. }
  143.  
  144. public List<E> getPath() {
  145. return path_edges;
  146. }
  147.  
  148. @Override
  149. public int compareTo(WeightedPath o) {
  150. if (weight < o.weight)
  151. return -1;
  152. else if (weight > o.weight)
  153. return 1;
  154.  
  155. // from here on equal weight
  156. int sizeDiff = path_edges.size() - o.path_edges.size();
  157. if (sizeDiff < 0)
  158. return -1;
  159. else if (sizeDiff > 0)
  160. return 1;
  161.  
  162. return 0;
  163. }
  164.  
  165. @Override
  166. public String toString() {
  167. return path_vertices + ";" + path_edges + ";" + weight;
  168. }
  169. }
  170.  
  171. /**
  172. * Create <math>delta(e)</math> for each edge in graph {@link #g}.
  173. *
  174. * @param target
  175. * The target
  176. * @return The delta edge weight.
  177. */
  178. private Transformer<E, Double> prepareTransformations(V target) {
  179. Map<V, Double> lengthMap = new HashMap<V, Double>(); // d(x, t)
  180. Map<E, Double> edgeMap = new HashMap<E, Double>();
  181.  
  182. // Search the shortest path from "target" to any vertex,
  183. // and store the length in a map.
  184. for (V v : graph.getVertices()) {
  185. Number dist = dijkstra.getDistance(v, target);
  186.  
  187. if (dist != null) // target is reachable from v.
  188. lengthMap.put(v, dist.doubleValue());
  189. else {
  190. // Block edges from or to unreachable vertices.
  191. for (E e : graph.getIncidentEdges(v))
  192. edgeMap.put(e, Double.POSITIVE_INFINITY);
  193. }
  194. }
  195.  
  196. // Calculate delta(e)
  197. for (E e : graph.getEdges()) {
  198. if (edgeMap.get(e) == null) {
  199. // Only consider edges to reachable vertices.
  200. double l = nev.transform(e).doubleValue() /* l(e) */
  201. + lengthMap.get(graph.getDest(e)) /* d(head(e), t) */
  202. - lengthMap.get(graph.getSource(e)) /* d(tail(e), t) */;
  203. edgeMap.put(e, l);
  204. }
  205. }
  206.  
  207. return MapTransformer.getInstance(edgeMap);
  208. }
  209.  
  210. @Override
  211. protected List<List<E>> getShortestPathsIntern(V source, V target, int k) {
  212. PriorityQueue<WeightedPath> prioQ = new PriorityQueue<WeightedPath>();
  213. List<List<E>> found_paths = new LinkedList<List<E>>();
  214.  
  215. Transformer<E, Double> delta = prepareTransformations(target);
  216.  
  217. // Initialize with start vertex.
  218. prioQ.add(new WeightedPath(source));
  219.  
  220. while (!prioQ.isEmpty() && found_paths.size() < k) {
  221. WeightedPath curPath = prioQ.poll(); // get & remove next shortest
  222. V curV = curPath.getLast();
  223.  
  224. if (curV.equals(target)) {
  225. addValidPath(found_paths, curPath.getPath());
  226. continue;
  227. }
  228.  
  229. // Create new paths for every expanded vertex ...
  230. for (V nextV : graph.getSuccessors(curV)) {
  231. if (curPath.contains(nextV))
  232. continue; // Prevent looping!
  233.  
  234. // ... and every possible edge.
  235. for (E e : graph.findEdgeSet(curV, nextV)) {
  236. if (Double.isInfinite(delta.transform(e)))
  237. continue; // Skip unreachable vertices.
  238.  
  239. WeightedPath tmpPath = new WeightedPath(curPath); // clone
  240. tmpPath.addHop(e, delta.transform(e), nextV);
  241.  
  242. prioQ.add(tmpPath);
  243. }
  244. }
  245. }
  246.  
  247. return found_paths;
  248. }
  249. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement