K-shorest path algorithm to support UC1, it can be used by other modules as well.
Change-Id: I736ec55c6211a505d6cf43ab22e1197fdb86ecf3
Showing
3 changed files
with
636 additions
and
0 deletions
1 | +/* | ||
2 | + * Licensed to the Apache Software Foundation (ASF) under one | ||
3 | + * or more contributor license agreements. See the NOTICE file | ||
4 | + * distributed with this work for additional information | ||
5 | + * regarding copyright ownership. The ASF licenses this file | ||
6 | + * to you under the Apache License, Version 2.0 (the | ||
7 | + * "License"); you may not use this file except in compliance | ||
8 | + * with the License. You may obtain a copy of the License at | ||
9 | + * | ||
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + * | ||
12 | + * Unless required by applicable law or agreed to in writing, | ||
13 | + * software distributed under the License is distributed on an | ||
14 | + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
15 | + * KIND, either express or implied. See the License for the | ||
16 | + * specific language governing permissions and limitations | ||
17 | + * under the License. | ||
18 | + */ | ||
19 | +package org.onlab.graph; | ||
20 | + | ||
21 | +import java.util.ArrayList; | ||
22 | +//import java.util.HashMap; | ||
23 | +import java.util.Iterator; | ||
24 | +import java.util.List; | ||
25 | +//import java.util.Map; | ||
26 | +//import java.util.PriorityQueue; | ||
27 | +import java.util.Set; | ||
28 | + | ||
29 | +//import org.apache.commons.lang3.tuple.Pair; | ||
30 | +//import org.onlab.graph.AbstractGraphPathSearch.DefaultResult; | ||
31 | + | ||
32 | +/** | ||
33 | + * K-shortest-path graph search algorithm capable of finding not just one, | ||
34 | + * but K shortest paths with descending order between the source and destinations. | ||
35 | + */ | ||
36 | + | ||
37 | +public class KshortestPathSearch<V extends Vertex, E extends Edge<V>> { | ||
38 | + | ||
39 | + // Define class variables. | ||
40 | + private Graph<V, E> immutableGraph; | ||
41 | + private MutableGraph<V, E> mutableGraph; | ||
42 | + private List<List<E>> pathResults = new ArrayList<List<E>>(); | ||
43 | + private List<List<E>> pathCandidates = new ArrayList<List<E>>(); | ||
44 | + private V source; | ||
45 | + private V sink; | ||
46 | + private int numK = 0; | ||
47 | + private EdgeWeight<V, E> weight = null; | ||
48 | + // private PriorityQueue<List<E>> pathCandidates = new PriorityQueue<List<E>>(); | ||
49 | + | ||
50 | + // Initialize the graph. | ||
51 | + public KshortestPathSearch(Graph<V, E> graph) { | ||
52 | + immutableGraph = graph; | ||
53 | + mutableGraph = new MutableAdjacencyListsGraph(graph.getVertexes(), | ||
54 | + graph.getEdges()); | ||
55 | + } | ||
56 | + | ||
57 | + public List<List<E>> search(V src, | ||
58 | + V dst, | ||
59 | + EdgeWeight<V, E> wei, | ||
60 | + int k) { | ||
61 | + | ||
62 | + weight = wei; | ||
63 | + source = src; | ||
64 | + sink = dst; | ||
65 | + numK = k; | ||
66 | + // pathCandidates = new PriorityQueue<List<E>>(); | ||
67 | + | ||
68 | + pathResults.clear(); | ||
69 | + pathCandidates.clear(); | ||
70 | + | ||
71 | + // Double check the parameters | ||
72 | + checkArguments(immutableGraph, src, dst, numK); | ||
73 | + | ||
74 | + // DefaultResult result = new DefaultResult(src, dst); | ||
75 | + | ||
76 | + searchKShortestPaths(); | ||
77 | + | ||
78 | + return pathResults; | ||
79 | + } | ||
80 | + | ||
81 | + private void checkArguments(Graph<V, E> graph, V src, V dst, int k) { | ||
82 | + if (graph == null) { | ||
83 | + throw new NullPointerException("graph is null"); | ||
84 | + } | ||
85 | + if (!graph.getVertexes().contains(src)) { | ||
86 | + throw new NullPointerException("source node does not exist"); | ||
87 | + } | ||
88 | + if (!graph.getVertexes().contains(dst)) { | ||
89 | + throw new NullPointerException("target node does not exist"); | ||
90 | + } | ||
91 | + if (k <= 0) { | ||
92 | + throw new NullPointerException("K is negative or 0"); | ||
93 | + } | ||
94 | + if (weight == null) { | ||
95 | + throw new NullPointerException("the cost matrix is null"); | ||
96 | + } | ||
97 | + } | ||
98 | + | ||
99 | + private void searchKShortestPaths() { | ||
100 | + // Step 1: find the shortest path. | ||
101 | + List<E> shortestPath = searchShortestPath(immutableGraph, source, sink); | ||
102 | + // no path exists, exit. | ||
103 | + if (shortestPath == null) { | ||
104 | + return; | ||
105 | + } | ||
106 | + | ||
107 | + // Step 2: update the results. | ||
108 | + pathResults.add(shortestPath); | ||
109 | + // pathCandidates.add(shortestPath); | ||
110 | + | ||
111 | + // Step 3: find the other K-1 paths. | ||
112 | + while (/*pathCandidates.size() > 0 &&*/pathResults.size() < numK) { | ||
113 | + // 3.1 the spur node ranges from the first node to the last node in the previous k-shortest path. | ||
114 | + List<E> lastPath = pathResults.get(pathResults.size() - 1); | ||
115 | + for (int i = 0; i < lastPath.size(); i++) { | ||
116 | + // 4.1 convert the graph into mutable. | ||
117 | + convertGraph(); | ||
118 | + // 4.2 transform the graph. | ||
119 | + List<E> rootPath = createSpurNode(lastPath, i); | ||
120 | + transformGraph(rootPath); | ||
121 | + // 4.3 find the deviation node. | ||
122 | + V devNode; | ||
123 | + devNode = getDevNode(rootPath); | ||
124 | + List<E> spurPath; | ||
125 | + // 4.4 find the shortest path in the transformed graph. | ||
126 | + spurPath = searchShortestPath(mutableGraph, devNode, sink); | ||
127 | + // 4.5 update the path candidates. | ||
128 | + if (spurPath != null) { | ||
129 | + // totalPath = rootPath + spurPath; | ||
130 | + rootPath.addAll(spurPath); | ||
131 | + pathCandidates.add(rootPath); | ||
132 | + } | ||
133 | + } | ||
134 | + // 3.2 if there is no spur path, exit. | ||
135 | + if (pathCandidates.size() == 0) { | ||
136 | + break; | ||
137 | + } | ||
138 | + // 3.3 add the path into the results. | ||
139 | + addPathResult(); | ||
140 | + } | ||
141 | + } | ||
142 | + | ||
143 | + private List<E> searchShortestPath(Graph<V, E> graph, V src, V dst) { | ||
144 | + // Determine the shortest path from the source to the destination by using the Dijkstra algorithm. | ||
145 | + DijkstraGraphSearch dijkstraAlg = new DijkstraGraphSearch(); | ||
146 | + Set<Path> paths = dijkstraAlg.search(graph, src, dst, weight).paths(); | ||
147 | + Iterator<Path> itr = paths.iterator(); | ||
148 | + if (!itr.hasNext()) { | ||
149 | + return null; | ||
150 | + } | ||
151 | + // return the first shortest path only. | ||
152 | + return (List<E>) itr.next().edges(); | ||
153 | + } | ||
154 | + | ||
155 | + private void convertGraph() { | ||
156 | + // clear the mutableGraph first | ||
157 | + if (mutableGraph != null) { | ||
158 | + ((MutableAdjacencyListsGraph) mutableGraph).clear(); | ||
159 | + } | ||
160 | + | ||
161 | + // create a immutableGraph | ||
162 | + Set<E> copyEa = immutableGraph.getEdges(); | ||
163 | + Set<V> copyVa = immutableGraph.getVertexes(); | ||
164 | + for (V vertex : copyVa) { | ||
165 | + mutableGraph.addVertex(vertex); | ||
166 | + } | ||
167 | + for (E edge : copyEa) { | ||
168 | + mutableGraph.addEdge(edge); | ||
169 | + } | ||
170 | + } | ||
171 | + | ||
172 | + private V getDevNode(List<E> path) { | ||
173 | + V srcA; | ||
174 | + V dstB; | ||
175 | + | ||
176 | + if (path.size() == 0) { | ||
177 | + return source; | ||
178 | + } | ||
179 | + | ||
180 | + E temp1 = path.get(path.size() - 1); | ||
181 | + srcA = temp1.src(); | ||
182 | + dstB = temp1.dst(); | ||
183 | + | ||
184 | + if (path.size() == 1) { | ||
185 | + if (srcA.equals(source)) { | ||
186 | + return dstB; | ||
187 | + } else { | ||
188 | + return srcA; | ||
189 | + } | ||
190 | + } else { | ||
191 | + E temp2 = path.get(path.size() - 2); | ||
192 | + if (srcA.equals(temp2.src()) || srcA.equals(temp2.dst())) { | ||
193 | + return dstB; | ||
194 | + } else { | ||
195 | + return srcA; | ||
196 | + } | ||
197 | + } | ||
198 | + } | ||
199 | + | ||
200 | + private List<E> createSpurNode(List<E> path, int n) { | ||
201 | + List<E> root = new ArrayList<E>(); | ||
202 | + | ||
203 | + for (int i = 0; i < n; i++) { | ||
204 | + root.add(path.get(i)); | ||
205 | + } | ||
206 | + return root; | ||
207 | + } | ||
208 | + | ||
209 | + private void transformGraph(List<E> rootPath) { | ||
210 | + List<E> prePath; | ||
211 | + //remove edges | ||
212 | + for (int i = 0; i < pathResults.size(); i++) { | ||
213 | + prePath = pathResults.get(i); | ||
214 | + if (prePath.size() == 1) { | ||
215 | + mutableGraph.removeEdge(prePath.get(0)); | ||
216 | + } else if (comparePath(rootPath, prePath)) { | ||
217 | + for (int j = 0; j <= rootPath.size(); j++) { | ||
218 | + mutableGraph.removeEdge(prePath.get(j)); | ||
219 | + } | ||
220 | + } | ||
221 | + } | ||
222 | + for (int i = 0; i < pathCandidates.size(); i++) { | ||
223 | + prePath = pathCandidates.get(i); | ||
224 | + if (prePath.size() == 1) { | ||
225 | + mutableGraph.removeEdge(prePath.get(0)); | ||
226 | + } else if (comparePath(rootPath, prePath)) { | ||
227 | + for (int j = 0; j <= rootPath.size(); j++) { | ||
228 | + mutableGraph.removeEdge(prePath.get(j)); | ||
229 | + } | ||
230 | + } | ||
231 | + } | ||
232 | + | ||
233 | + if (rootPath.size() == 0) { | ||
234 | + return; | ||
235 | + } | ||
236 | + | ||
237 | + //remove nodes | ||
238 | + List<V> nodes = new ArrayList<V>(); | ||
239 | + nodes.add(source); | ||
240 | + V pre = source; | ||
241 | + V srcA; | ||
242 | + V dstB; | ||
243 | + for (int i = 0; i < rootPath.size() - 1; i++) { | ||
244 | + E temp = rootPath.get(i); | ||
245 | + srcA = temp.src(); | ||
246 | + dstB = temp.dst(); | ||
247 | + | ||
248 | + if (srcA.equals(pre)) { | ||
249 | + nodes.add(dstB); | ||
250 | + pre = dstB; | ||
251 | + } else { | ||
252 | + nodes.add(srcA); | ||
253 | + pre = srcA; | ||
254 | + } | ||
255 | + } | ||
256 | + for (int i = 0; i < nodes.size(); i++) { | ||
257 | + mutableGraph.removeVertex(nodes.get(i)); | ||
258 | + } | ||
259 | + } | ||
260 | + | ||
261 | + private boolean comparePath(List<E> path1, List<E> path2) { | ||
262 | + if (path1.size() > path2.size()) { | ||
263 | + return false; | ||
264 | + } | ||
265 | + if (path1.size() == 0) { | ||
266 | + return true; | ||
267 | + } | ||
268 | + for (int i = 0; i < path1.size(); i++) { | ||
269 | + if (path1.get(i) != path2.get(i)) { | ||
270 | + return false; | ||
271 | + } | ||
272 | + } | ||
273 | + return true; | ||
274 | + } | ||
275 | + | ||
276 | + private void addPathResult() { | ||
277 | + List<E> sp; | ||
278 | + sp = pathCandidates.get(0); | ||
279 | + for (int i = 1; i < pathCandidates.size(); i++) { | ||
280 | + if (sp.size() > pathCandidates.get(i).size()) { | ||
281 | + sp = pathCandidates.get(i); | ||
282 | + } | ||
283 | + } | ||
284 | + pathResults.add(sp); | ||
285 | + // Log.info(sp.toString()); | ||
286 | + pathCandidates.remove(sp); | ||
287 | + } | ||
288 | + | ||
289 | +} |
1 | +package org.onlab.graph; | ||
2 | + | ||
3 | +import static com.google.common.base.MoreObjects.toStringHelper; | ||
4 | + | ||
5 | +import java.util.HashSet; | ||
6 | +import java.util.Objects; | ||
7 | +import java.util.Set; | ||
8 | + | ||
9 | +import com.google.common.collect.HashMultimap; | ||
10 | +import com.google.common.collect.SetMultimap; | ||
11 | + | ||
12 | +public class MutableAdjacencyListsGraph<V extends Vertex, E extends Edge<V>> | ||
13 | +implements MutableGraph<V, E> { | ||
14 | + private Set<V> vertexes = new HashSet<V>(); | ||
15 | + private Set<E> edges = new HashSet<E>(); | ||
16 | + | ||
17 | + private SetMultimap<V, E> sources = HashMultimap.create(); | ||
18 | + private SetMultimap<V, E> destinations = HashMultimap.create(); | ||
19 | + | ||
20 | + /** | ||
21 | + * Creates a graph comprising of the specified vertexes and edges. | ||
22 | + * | ||
23 | + * @param vertexes set of graph vertexes | ||
24 | + * @param edges set of graph edges | ||
25 | + */ | ||
26 | + public MutableAdjacencyListsGraph(Set<V> vertex, Set<E> edge) { | ||
27 | + vertexes.addAll(vertex); | ||
28 | + edges.addAll(edge); | ||
29 | + for (E e : edge) { | ||
30 | + sources.put(e.src(), e); | ||
31 | + vertexes.add(e.src()); | ||
32 | + destinations.put(e.dst(), e); | ||
33 | + vertexes.add(e.dst()); | ||
34 | + } | ||
35 | + } | ||
36 | + | ||
37 | + @Override | ||
38 | + public Set<V> getVertexes() { | ||
39 | + return vertexes; | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public Set<E> getEdges() { | ||
44 | + return edges; | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public Set<E> getEdgesFrom(V src) { | ||
49 | + return sources.get(src); | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public Set<E> getEdgesTo(V dst) { | ||
54 | + return destinations.get(dst); | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public boolean equals(Object obj) { | ||
59 | + if (this == obj) { | ||
60 | + return true; | ||
61 | + } | ||
62 | + if (obj instanceof MutableAdjacencyListsGraph) { | ||
63 | + MutableAdjacencyListsGraph that = (MutableAdjacencyListsGraph) obj; | ||
64 | + return this.getClass() == that.getClass() && | ||
65 | + Objects.equals(this.vertexes, that.vertexes) && | ||
66 | + Objects.equals(this.edges, that.edges); | ||
67 | + } | ||
68 | + return false; | ||
69 | + } | ||
70 | + | ||
71 | + @Override | ||
72 | + public int hashCode() { | ||
73 | + return Objects.hash(vertexes, edges); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public String toString() { | ||
78 | + return toStringHelper(this) | ||
79 | + .add("vertexes", vertexes) | ||
80 | + .add("edges", edges) | ||
81 | + .toString(); | ||
82 | + } | ||
83 | + | ||
84 | + | ||
85 | + @Override | ||
86 | + public void addVertex(V vertex) { | ||
87 | + if (vertexes != null) { | ||
88 | + if (!vertexes.contains(vertex)) { | ||
89 | + vertexes.add(vertex); | ||
90 | + } | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + @Override | ||
95 | + public void removeVertex(V vertex) { | ||
96 | + // TODO Auto-generated method stub | ||
97 | + if (vertexes != null && edges != null) { | ||
98 | + if (vertexes.contains(vertex)) { | ||
99 | + vertexes.remove(vertex); | ||
100 | + Set<E> srcEdgesList = sources.get(vertex); | ||
101 | + Set<E> dstEdgesList = destinations.get(vertex); | ||
102 | + edges.removeAll(srcEdgesList); | ||
103 | + edges.removeAll(dstEdgesList); | ||
104 | + sources.remove(vertex, srcEdgesList); | ||
105 | + sources.remove(vertex, dstEdgesList); | ||
106 | + } | ||
107 | + } | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + public void addEdge(E edge) { | ||
112 | + if (edges != null) { | ||
113 | + if (!edges.contains(edge)) { | ||
114 | + edges.add(edge); | ||
115 | + sources.put(edge.src(), edge); | ||
116 | + destinations.put(edge.dst(), edge); | ||
117 | + } | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + @Override | ||
122 | + public void removeEdge(E edge) { | ||
123 | + if (edges != null) { | ||
124 | + if (edges.contains(edge)) { | ||
125 | + edges.remove(edge); | ||
126 | + sources.remove(edge.src(), edge); | ||
127 | + destinations.remove(edge.dst(), edge); | ||
128 | + } | ||
129 | + } | ||
130 | + } | ||
131 | + | ||
132 | + @Override | ||
133 | + public Graph<V, E> toImmutable() { | ||
134 | + // TODO Auto-generated method stub | ||
135 | + return null; | ||
136 | + } | ||
137 | + | ||
138 | + /** | ||
139 | + * Clear the graph. | ||
140 | + */ | ||
141 | + public void clear() { | ||
142 | + edges.clear(); | ||
143 | + vertexes.clear(); | ||
144 | + sources.clear(); | ||
145 | + destinations.clear(); | ||
146 | + } | ||
147 | +} |
1 | +/* | ||
2 | + * Licensed to the Apache Software Foundation (ASF) under one | ||
3 | + * or more contributor license agreements. See the NOTICE file | ||
4 | + * distributed with this work for additional information | ||
5 | + * regarding copyright ownership. The ASF licenses this file | ||
6 | + * to you under the Apache License, Version 2.0 (the | ||
7 | + * "License"); you may not use this file except in compliance | ||
8 | + * with the License. You may obtain a copy of the License at | ||
9 | + * | ||
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + * | ||
12 | + * Unless required by applicable law or agreed to in writing, | ||
13 | + * software distributed under the License is distributed on an | ||
14 | + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
15 | + * KIND, either express or implied. See the License for the | ||
16 | + * specific language governing permissions and limitations | ||
17 | + * under the License. | ||
18 | + */ | ||
19 | +package org.onlab.graph; | ||
20 | + | ||
21 | +import static com.google.common.collect.ImmutableSet.of; | ||
22 | +import static org.junit.Assert.*; | ||
23 | + | ||
24 | +import java.io.ByteArrayOutputStream; | ||
25 | +//import java.io.PrintStream; | ||
26 | +import java.util.ArrayList; | ||
27 | +import java.util.Iterator; | ||
28 | +import java.util.List; | ||
29 | + | ||
30 | +import org.junit.After; | ||
31 | +import org.junit.AfterClass; | ||
32 | +import org.junit.Before; | ||
33 | +import org.junit.BeforeClass; | ||
34 | +import org.junit.Test; | ||
35 | + | ||
36 | +public class KshortestPathSearchTest extends BreadthFirstSearchTest { | ||
37 | + | ||
38 | + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); | ||
39 | + | ||
40 | + @Test | ||
41 | + public void noPath() { | ||
42 | + graph = new AdjacencyListsGraph<>(of(A, B, C, D), | ||
43 | + of(new TestEdge(A, B, 1), | ||
44 | + new TestEdge(B, A, 1), | ||
45 | + new TestEdge(C, D, 1), | ||
46 | + new TestEdge(D, C, 1))); | ||
47 | + KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph); | ||
48 | + List<List<TestEdge>> result = gs.search(A, D, weight, 1); | ||
49 | + List<Path> paths = new ArrayList<>(); | ||
50 | + Iterator<List<TestEdge>> itr = result.iterator(); | ||
51 | + while (itr.hasNext()) { | ||
52 | + System.out.println(itr.next().toString()); | ||
53 | + } | ||
54 | + assertEquals("incorrect paths count", 0, result.size()); | ||
55 | + } | ||
56 | + | ||
57 | + @Test | ||
58 | + public void test2Path() { | ||
59 | + graph = new AdjacencyListsGraph<>(of(A, B, C, D), | ||
60 | + of(new TestEdge(A, B, 1), | ||
61 | + new TestEdge(B, A, 1), | ||
62 | + new TestEdge(B, D, 1), | ||
63 | + new TestEdge(D, B, 1), | ||
64 | + new TestEdge(A, C, 1), | ||
65 | + new TestEdge(C, A, 1), | ||
66 | + new TestEdge(C, D, 1), | ||
67 | + new TestEdge(D, C, 1))); | ||
68 | + KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph); | ||
69 | + List<List<TestEdge>> result = gs.search(A, D, weight, 2); | ||
70 | + List<Path> paths = new ArrayList<>(); | ||
71 | + Iterator<List<TestEdge>> itr = result.iterator(); | ||
72 | + while (itr.hasNext()) { | ||
73 | + System.out.println(itr.next().toString()); | ||
74 | + } | ||
75 | + assertEquals("incorrect paths count", 2, result.size()); | ||
76 | + // assertEquals("printing the paths", outContent.toString()); | ||
77 | + } | ||
78 | + | ||
79 | + @Test | ||
80 | + public void test3Path() { | ||
81 | + graph = new AdjacencyListsGraph<>(of(A, B, C, D), | ||
82 | + of(new TestEdge(A, B, 1), | ||
83 | + new TestEdge(B, A, 1), | ||
84 | + new TestEdge(A, D, 1), | ||
85 | + new TestEdge(D, A, 1), | ||
86 | + new TestEdge(B, D, 1), | ||
87 | + new TestEdge(D, B, 1), | ||
88 | + new TestEdge(A, C, 1), | ||
89 | + new TestEdge(C, A, 1), | ||
90 | + new TestEdge(C, D, 1), | ||
91 | + new TestEdge(D, C, 1))); | ||
92 | + KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph); | ||
93 | + List<List<TestEdge>> result = gs.search(A, D, weight, 3); | ||
94 | + List<Path> paths = new ArrayList<>(); | ||
95 | + Iterator<List<TestEdge>> itr = result.iterator(); | ||
96 | + while (itr.hasNext()) { | ||
97 | + System.out.println(itr.next().toString()); | ||
98 | + } | ||
99 | + assertEquals("incorrect paths count", 3, result.size()); | ||
100 | + // assertEquals("printing the paths", outContent.toString()); | ||
101 | + } | ||
102 | + | ||
103 | + @Test | ||
104 | + public void test4Path() { | ||
105 | + graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F), | ||
106 | + of(new TestEdge(A, B, 1), | ||
107 | + new TestEdge(B, A, 1), | ||
108 | + new TestEdge(A, C, 1), | ||
109 | + new TestEdge(C, A, 1), | ||
110 | + new TestEdge(B, D, 1), | ||
111 | + new TestEdge(D, B, 1), | ||
112 | + new TestEdge(C, E, 1), | ||
113 | + new TestEdge(E, C, 1), | ||
114 | + new TestEdge(D, F, 1), | ||
115 | + new TestEdge(F, D, 1), | ||
116 | + new TestEdge(F, E, 1), | ||
117 | + new TestEdge(E, F, 1), | ||
118 | + new TestEdge(C, D, 1), | ||
119 | + new TestEdge(D, C, 1))); | ||
120 | + KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph); | ||
121 | + List<List<TestEdge>> result = gs.search(A, F, weight, 4); | ||
122 | + List<Path> paths = new ArrayList<>(); | ||
123 | + Iterator<List<TestEdge>> itr = result.iterator(); | ||
124 | + while (itr.hasNext()) { | ||
125 | + System.out.println(itr.next().toString()); | ||
126 | + } | ||
127 | + assertEquals("incorrect paths count", 4, result.size()); | ||
128 | + // assertEquals("printing the paths", outContent.toString()); | ||
129 | + } | ||
130 | + | ||
131 | + @Test | ||
132 | + public void test6Path() { | ||
133 | + graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F), | ||
134 | + of(new TestEdge(A, B, 1), | ||
135 | + new TestEdge(B, A, 1), | ||
136 | + new TestEdge(A, C, 1), | ||
137 | + new TestEdge(C, A, 1), | ||
138 | + new TestEdge(B, D, 1), | ||
139 | + new TestEdge(D, B, 1), | ||
140 | + new TestEdge(B, C, 1), | ||
141 | + new TestEdge(C, B, 1), | ||
142 | + new TestEdge(D, E, 1), | ||
143 | + new TestEdge(E, D, 1), | ||
144 | + new TestEdge(C, E, 1), | ||
145 | + new TestEdge(E, C, 1), | ||
146 | + new TestEdge(D, F, 1), | ||
147 | + new TestEdge(F, D, 1), | ||
148 | + new TestEdge(E, F, 1), | ||
149 | + new TestEdge(F, E, 1))); | ||
150 | + KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph); | ||
151 | + List<List<TestEdge>> result = gs.search(A, F, weight, 6); | ||
152 | + List<Path> paths = new ArrayList<>(); | ||
153 | + Iterator<List<TestEdge>> itr = result.iterator(); | ||
154 | + while (itr.hasNext()) { | ||
155 | + System.out.println(itr.next().toString()); | ||
156 | + } | ||
157 | + assertEquals("incorrect paths count", 6, result.size()); | ||
158 | + // assertEquals("printing the paths", outContent.toString()); | ||
159 | + } | ||
160 | + | ||
161 | + @Test | ||
162 | + public void dualEdgePath() { | ||
163 | + graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G, H), | ||
164 | + of(new TestEdge(A, B, 1), new TestEdge(A, C, 3), | ||
165 | + new TestEdge(B, D, 2), new TestEdge(B, C, 1), | ||
166 | + new TestEdge(B, E, 4), new TestEdge(C, E, 1), | ||
167 | + new TestEdge(D, H, 5), new TestEdge(D, E, 1), | ||
168 | + new TestEdge(E, F, 1), new TestEdge(F, D, 1), | ||
169 | + new TestEdge(F, G, 1), new TestEdge(F, H, 1), | ||
170 | + new TestEdge(A, E, 3), new TestEdge(B, D, 1))); | ||
171 | + KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph); | ||
172 | + List<List<TestEdge>> result = gs.search(A, G, weight, 6); | ||
173 | + List<Path> paths = new ArrayList<>(); | ||
174 | + Iterator<List<TestEdge>> itr = result.iterator(); | ||
175 | + while (itr.hasNext()) { | ||
176 | + System.out.println(itr.next().toString()); | ||
177 | + } | ||
178 | + assertEquals("incorrect paths count", 6, result.size()); | ||
179 | + // assertEquals("printing the paths", outContent.toString()); | ||
180 | + } | ||
181 | + | ||
182 | + @BeforeClass | ||
183 | + public static void setUpBeforeClass() throws Exception { | ||
184 | + } | ||
185 | + | ||
186 | + @AfterClass | ||
187 | + public static void tearDownAfterClass() throws Exception { | ||
188 | + } | ||
189 | + | ||
190 | + @Before | ||
191 | + public void setUp() throws Exception { | ||
192 | + // System.setOut(new PrintStream(outContent)); | ||
193 | + } | ||
194 | + | ||
195 | + @After | ||
196 | + public void tearDown() throws Exception { | ||
197 | + // System.setOut(null); | ||
198 | + } | ||
199 | + | ||
200 | +} |
-
Please register or login to post a comment