Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
DijkstraAdvanced |
|
| 0.0;0 |
1 | package fr.inria.opengve.bridge.algorithms.common.shortestPath; | |
2 | ||
3 | import java.awt.Color; | |
4 | import java.util.HashSet; | |
5 | import java.util.Iterator; | |
6 | import java.util.NoSuchElementException; | |
7 | ||
8 | import fr.inria.opengve.bridge.abstractClasses.AbstractScalar; | |
9 | import fr.inria.opengve.bridge.interfaces.Graph; | |
10 | import fr.inria.opengve.bridge.interfaces.Link; | |
11 | import fr.inria.opengve.bridge.interfaces.Map; | |
12 | import fr.inria.opengve.tools.dataStructures.FibonacciHeap; | |
13 | ||
14 | ||
15 | /** | |
16 | * Provides a advanced algorithm to find all shortest paths from a vertex. You | |
17 | * must note that this algorithm doesn't work with negative distance you must | |
18 | * use {@link fr.inria.opengve.bridge.algorithms.common.shortestPath.BellmanFord}. | |
19 | * <p> | |
20 | * After constructing the dijkstra object, some steps are necessary to obtains | |
21 | * shortest paths or distances. </br> | |
22 | * <nl> | |
23 | * <li> Initialize Algorithm : | |
24 | * <ul> | |
25 | * <li> Set the {@link fr.inria.opengve.bridge.interfaces.Map} used to load edges distance : | |
26 | * {@link #setDistanceMap(Map)} | |
27 | * <li> Set the name of the distance value : {@link #setDistanceName(String)} | |
28 | * <li> Set the context of distance value : {@link #setDistanceContext(Object)} | |
29 | * <li> Set the {@link fr.inria.opengve.bridge.abstractClasses.AbstractScalar} corresponding to | |
30 | * infinity : {@link #setInfiniteDistance(AbstractScalar)} | |
31 | * </nl> | |
32 | * <p> | |
33 | * After initialisation call {@link #valuateFromSource(Object)} for shortest | |
34 | * path computation. | |
35 | * <p> | |
36 | * You can get result with two methods : | |
37 | * <nl> | |
38 | * <li> Get a shortest path to a given vertex : | |
39 | * {@link #getShortestPathTo(Object)} | |
40 | * <li> Get the distance to a given vertex : {@link #getDistanceTo(Object)} | |
41 | * </nl> | |
42 | * </p> | |
43 | * If you use the {@link #DijkstraAdvanced(Graph, boolean, Object)} constructor | |
44 | * the algorithm stop when the shortest path to the given vertice is found. | |
45 | * | |
46 | * @param V | |
47 | * the type of vertices. | |
48 | * @param E | |
49 | * the type of edges. | |
50 | * @author fabrice.peix@sophia.inria.fr | |
51 | */ | |
52 | public abstract class DijkstraAdvanced<V, E extends Link<V>, G extends Graph<V, E>> | |
53 | extends ShortestPathWithSingleOrigin<V, E, G> | |
54 | { | |
55 | ||
56 | /** | |
57 | * In optimized mode the vertex for which shortest path is computed. | |
58 | */ | |
59 | private final V destination; | |
60 | ||
61 | ||
62 | ||
63 | /** | |
64 | * Classic Dijkstra constructor. | |
65 | * | |
66 | * @param g | |
67 | * the graph used by Dijkstra algorithm | |
68 | */ | |
69 | public DijkstraAdvanced(G g) { | |
70 | 0 | this(g, false); |
71 | 0 | } |
72 | ||
73 | ||
74 | ||
75 | /** | |
76 | * This constructor permit to specify if algorithm must run in stepMode. | |
77 | * | |
78 | * @param g | |
79 | * the graph used by Dijkstra algorithm | |
80 | * @param stepMode | |
81 | * The mode of the algorithms. | |
82 | */ | |
83 | public DijkstraAdvanced(G g, boolean stepMode) { | |
84 | 0 | this(g, stepMode, null); |
85 | 0 | } |
86 | ||
87 | ||
88 | ||
89 | /** | |
90 | * This constructor is used to do optimized computation when you want to | |
91 | * compute shortest path between two vertices. | |
92 | * | |
93 | * @param g | |
94 | * The graph on which the algorithm is applied. | |
95 | * @param stepMode | |
96 | * The mode of the algorithm. | |
97 | * @param destination | |
98 | * The destination. | |
99 | */ | |
100 | protected DijkstraAdvanced(G g, boolean stepMode, V destination) { | |
101 | 0 | super(g, stepMode); |
102 | 0 | this.destination = destination; |
103 | 0 | } |
104 | ||
105 | ||
106 | ||
107 | /** | |
108 | * This method must not be call, use instead | |
109 | * {@link ShortestPathWithSingleOrigin#valuateFromSource(Object)}. | |
110 | */ | |
111 | @Override | |
112 | public void run() { | |
113 | ||
114 | 0 | if (infiniteDistance == null) |
115 | 0 | throw new RuntimeException("You must specify infiniteDistance with setInfiniteDistance method"); |
116 | ||
117 | // For Demo | |
118 | 0 | if (getDemoMode()) { |
119 | 0 | pause(); |
120 | } | |
121 | 0 | AbstractScalar zero = infiniteDistance.zero(); |
122 | 0 | FibonacciHeap<V, AbstractScalar> nonComputedVertices = new FibonacciHeap<V, AbstractScalar>(); |
123 | 0 | HashSet<V> alreadyComputeVertices = new HashSet<V>(); |
124 | ||
125 | // Initialisation | |
126 | 0 | Initialize(zero); |
127 | ||
128 | // Modify the source... | |
129 | 0 | nonComputedVertices.insert(start_, zero.clone()); |
130 | 0 | pause(); |
131 | ||
132 | 0 | while ( !nonComputedVertices.isEmpty()) { |
133 | 0 | V minNode = null; |
134 | try { | |
135 | 0 | minNode = nonComputedVertices.findMin(); |
136 | 0 | nonComputedVertices.deleteMin(); |
137 | 0 | if (getDemoMode()) |
138 | 0 | result.putString(minNode, "Color", "" + Color.green.getRGB()); |
139 | 0 | } catch (NoSuchElementException u) { |
140 | 0 | System.err.println("findMin : fibonacci heap is empty"); |
141 | 0 | } |
142 | 0 | pause(); |
143 | ||
144 | 0 | Iterator<? extends E> itMAJ = g_.outEdges(minNode).iterator(); |
145 | 0 | while (itMAJ.hasNext()) { |
146 | 0 | E currentEdge2 = itMAJ.next(); |
147 | 0 | V currentNode2 = currentEdge2.getOpposite(minNode); |
148 | ||
149 | // Don't test fixed node. | |
150 | 0 | if (alreadyComputeVertices.contains(currentNode2)) |
151 | 0 | continue; |
152 | ||
153 | 0 | if (getDemoMode()) { |
154 | // Pause in demo mode | |
155 | 0 | result.putString(currentEdge2, "Color", "" + Color.red.getRGB()); |
156 | 0 | pause(); |
157 | } | |
158 | // Update vertices connected to minNode | |
159 | 0 | if (updateVerticesDistance(minNode, currentNode2, currentEdge2)) { |
160 | try { | |
161 | 0 | nonComputedVertices.FibHeapDecreaseKey(currentNode2, result |
162 | .getValue(currentNode2, VERTEX_DISTANCE, g_)); | |
163 | 0 | } catch (IllegalArgumentException u) { |
164 | 0 | System.err |
165 | .println("FibHeapDecreaseKey : New value greater than older"); | |
166 | 0 | } |
167 | } | |
168 | 0 | } |
169 | // Add the node to fixedNode. | |
170 | 0 | alreadyComputeVertices.add(minNode); |
171 | ||
172 | // When destination is set. | |
173 | 0 | if (destination != null && minNode == destination) { |
174 | 0 | this.ends(); |
175 | 0 | return; |
176 | } | |
177 | ||
178 | // For demo minNode is now red | |
179 | 0 | if (getDemoMode()) |
180 | 0 | result.putString(minNode, "Color", "" + Color.red.getRGB()); |
181 | 0 | } |
182 | 0 | this.ends(); |
183 | 0 | } |
184 | } |