blob: ed92be99f3284d7d171659a989b5d608b5f45897 [file] [log] [blame]
Brian O'Connor7cbbbb72016-04-09 02:13:23 -07001/*
2 * Copyright 2015-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Aaron Kruglikov07d80382015-12-07 16:54:37 -080016package org.onlab.graph;
17
18import com.google.common.collect.Lists;
19import org.junit.Before;
20import org.junit.Test;
21
22import java.util.Iterator;
23import java.util.List;
24import java.util.Set;
25
26import static com.google.common.collect.ImmutableSet.of;
27import static org.junit.Assert.assertEquals;
28import static org.junit.Assert.assertTrue;
29
30/**
31 * Class for test KshortestPathsSearch.
32 */
33public class KShortestPathsSearchTest<V extends Vertex, E extends Edge<V>> extends GraphTest {
34 private KShortestPathsSearch<TestVertex, TestEdge> kShortestPathsSearch = new KShortestPathsSearch<>();
35 private GraphPathSearch.Result<TestVertex, TestEdge> result;
36
37 @Before
38 public void setUp() {
39 graph = new AdjacencyListsGraph<>(vertexes(), edges());
40 }
41 @Test
42 public void noPath() {
43 graph = new AdjacencyListsGraph<>(of(A, B, C, D),
Andrey Komarov2398d962016-09-26 15:11:23 +030044 of(new TestEdge(A, B),
45 new TestEdge(B, A),
46 new TestEdge(C, D),
47 new TestEdge(D, C)));
Aaron Kruglikov07d80382015-12-07 16:54:37 -080048 KShortestPathsSearch<TestVertex, TestEdge> kShortestPathsSearch = new KShortestPathsSearch<>();
Andrey Komarov2398d962016-09-26 15:11:23 +030049 GraphPathSearch.Result<TestVertex, TestEdge> result = kShortestPathsSearch.search(graph, A, D, weigher, 1);
Aaron Kruglikov07d80382015-12-07 16:54:37 -080050 Set<Path<TestVertex, TestEdge>> resultPathSet = result.paths();
51 assertTrue("There should not be any paths.", resultPathSet.isEmpty());
52 }
53
54 @Test
55 public void testSinglePath() {
56 //Tests that there is only a single path possible between A and B
57 graph = new AdjacencyListsGraph<>(vertexes(), edges());
Andrey Komarov2398d962016-09-26 15:11:23 +030058 this.result = kShortestPathsSearch.search(graph, A, B, weigher, 2);
Aaron Kruglikov07d80382015-12-07 16:54:37 -080059 Iterator<Path<TestVertex, TestEdge>> itr = result.paths().iterator();
60 assertEquals("incorrect paths count", 1, result.paths().size());
61 List<TestEdge> correctEdgeList = Lists.newArrayList();
Andrey Komarov2398d962016-09-26 15:11:23 +030062 correctEdgeList.add(new TestEdge(A, B, W1));
Aaron Kruglikov07d80382015-12-07 16:54:37 -080063 assertTrue("That wrong path was returned.",
64 edgeListsAreEqual(correctEdgeList, result.paths().iterator().next().edges()));
65 }
66
67 @Test
68 public void testTwoPath() {
69 //Tests that there are only two paths between A and C and that they are returned in the correct order
Andrey Komarov2398d962016-09-26 15:11:23 +030070 result = kShortestPathsSearch.search(graph, A, C, weigher, 3);
Aaron Kruglikov07d80382015-12-07 16:54:37 -080071 assertTrue("There are an unexpected number of paths.", result.paths().size() == 2);
72 Iterator<Path<TestVertex, TestEdge>> edgeListIterator = result.paths().iterator();
73 List<TestEdge> correctEdgeList = Lists.newArrayList();
Andrey Komarov2398d962016-09-26 15:11:23 +030074 correctEdgeList.add(new TestEdge(A, B, W1));
75 correctEdgeList.add(new TestEdge(B, C, W1));
Aaron Kruglikov07d80382015-12-07 16:54:37 -080076 assertTrue("The first path from A to C was incorrect.",
77 edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
78 correctEdgeList.clear();
Andrey Komarov2398d962016-09-26 15:11:23 +030079 correctEdgeList.add(new TestEdge(A, C, W3));
Aaron Kruglikov07d80382015-12-07 16:54:37 -080080 assertTrue("The second path from A to C was incorrect.",
81 edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
82 }
83
84 @Test
85 public void testFourPath() {
86 //Tests that there are only four paths between A and E and that they are returned in the correct order
87 //Also tests the special case where some correct solutions are equal
Andrey Komarov2398d962016-09-26 15:11:23 +030088 result = kShortestPathsSearch.search(graph, A, E, weigher, 5);
Aaron Kruglikov07d80382015-12-07 16:54:37 -080089 assertTrue("There are an unexpected number of paths.", result.paths().size() == 4);
90 Iterator<Path<TestVertex, TestEdge>> edgeListIterator = result.paths().iterator();
91 List<TestEdge> correctEdgeList = Lists.newArrayList();
Andrey Komarov2398d962016-09-26 15:11:23 +030092 correctEdgeList.add(new TestEdge(A, B, W1));
93 correctEdgeList.add(new TestEdge(B, C, W1));
94 correctEdgeList.add(new TestEdge(C, E, W1));
Aaron Kruglikov07d80382015-12-07 16:54:37 -080095 assertTrue("The first path from A to E was incorrect.",
96 edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
97 correctEdgeList.clear();
98 //There are two paths of equal length that should hold positions two and three
99 List<TestEdge> alternateCorrectEdgeList = Lists.newArrayList();
Andrey Komarov2398d962016-09-26 15:11:23 +0300100 correctEdgeList.add(new TestEdge(A, C, W3));
101 correctEdgeList.add(new TestEdge(C, E, W1));
102 alternateCorrectEdgeList.add(new TestEdge(A, B, W1));
103 alternateCorrectEdgeList.add(new TestEdge(B, D, W2));
104 alternateCorrectEdgeList.add(new TestEdge(D, E, W1));
Aaron Kruglikov07d80382015-12-07 16:54:37 -0800105 List<TestEdge> candidateOne = edgeListIterator.next().edges();
106 List<TestEdge> candidateTwo = edgeListIterator.next().edges();
107 if (candidateOne.size() == 2) {
108 assertTrue("The second path from A to E was incorrect.",
109 edgeListsAreEqual(candidateOne, correctEdgeList));
110 assertTrue("The third path from A to E was incorrect.",
111 edgeListsAreEqual(candidateTwo, alternateCorrectEdgeList));
112 } else {
113 assertTrue("The second path from A to E was incorrect.",
114 edgeListsAreEqual(candidateOne, alternateCorrectEdgeList));
115 assertTrue("The third path from A to E was incorrect.",
116 edgeListsAreEqual(candidateTwo, correctEdgeList));
117 }
118 correctEdgeList.clear();
Andrey Komarov2398d962016-09-26 15:11:23 +0300119 correctEdgeList.add(new TestEdge(A, B, W1));
120 correctEdgeList.add(new TestEdge(B, E, W4));
Aaron Kruglikov07d80382015-12-07 16:54:37 -0800121 assertTrue("The fourth path rom A to E was incorrect",
122 edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
123
124 }
125
126 @Test
127 public void testPathsFromSink() {
128 //H is a sink in this topology, insure there are no paths from it to any other location
129 for (TestVertex vertex : vertexes()) {
130 assertTrue("There should be no paths from vertex H to any other node.",
Andrey Komarov2398d962016-09-26 15:11:23 +0300131 kShortestPathsSearch.search(graph, H, vertex, weigher, 1).paths().size() == 0);
Aaron Kruglikov07d80382015-12-07 16:54:37 -0800132 }
133 }
134
135 @Test
136 public void testLimitPathSetSize() {
137 //Checks to make sure that no more than K paths are returned
Andrey Komarov2398d962016-09-26 15:11:23 +0300138 result = kShortestPathsSearch.search(graph, A, E, weigher, 3);
Aaron Kruglikov07d80382015-12-07 16:54:37 -0800139 assertTrue("There are an unexpected number of paths.", result.paths().size() == 3);
Andrey Komarov2398d962016-09-26 15:11:23 +0300140 result = kShortestPathsSearch.search(graph, A, G, weigher, 1);
Aaron Kruglikov07d80382015-12-07 16:54:37 -0800141 assertTrue("There are an unexpected number of paths.", result.paths().size() == 1);
142 }
143
Koosha1525c452016-10-28 18:25:19 +0330144
145 @Test
146 public void testVariableLenPathsWithConstantLinkWeight() {
147
148 /*
149 * Test graph:
150 *
151 * +-+-+ +---+ +---+ +-+-+
152 * +--+ B +--+ C +-+ D +--+ E |
153 * | +-+-+ +---+ +---+ +-+-+
154 * | | |
155 * +-+-+ | +---+ +---+ +-+-+
156 * | A | +----+ F +-+ G +--+ H |
157 * +---+ +---+ +---+ +---+
158 */
159 graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G, H), of(
Andrey Komarov2398d962016-09-26 15:11:23 +0300160 new TestEdge(A, B),
161 new TestEdge(B, A),
162 new TestEdge(B, C),
163 new TestEdge(C, B),
164 new TestEdge(C, D),
165 new TestEdge(D, C),
166 new TestEdge(D, E),
167 new TestEdge(E, D),
168 new TestEdge(E, H),
169 new TestEdge(H, E),
170 new TestEdge(H, G),
171 new TestEdge(G, H),
172 new TestEdge(G, F),
173 new TestEdge(F, G),
174 new TestEdge(F, B),
175 new TestEdge(B, F)
Koosha1525c452016-10-28 18:25:19 +0330176 ));
177
Koosha1525c452016-10-28 18:25:19 +0330178 //Tests that there are only two paths between A and G and that they are returned in the correct order
Andrey Komarov2398d962016-09-26 15:11:23 +0300179 result = kShortestPathsSearch.search(graph, A, G, weigher, 5);
Koosha1525c452016-10-28 18:25:19 +0330180
181 assertEquals("There are an unexpected number of paths.", 2, result.paths().size());
182
183 Iterator<Path<TestVertex, TestEdge>> edgeListIterator = result.paths().iterator();
184
185 List<TestEdge> correctEdgeList = Lists.newArrayList();
Andrey Komarov2398d962016-09-26 15:11:23 +0300186 correctEdgeList.add(new TestEdge(A, B));
187 correctEdgeList.add(new TestEdge(B, F));
188 correctEdgeList.add(new TestEdge(F, G));
Koosha1525c452016-10-28 18:25:19 +0330189 assertTrue("The first path from A to G was incorrect.",
190 edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
191
192 correctEdgeList.clear();
Andrey Komarov2398d962016-09-26 15:11:23 +0300193 correctEdgeList.add(new TestEdge(A, B));
194 correctEdgeList.add(new TestEdge(B, C));
195 correctEdgeList.add(new TestEdge(C, D));
196 correctEdgeList.add(new TestEdge(D, E));
197 correctEdgeList.add(new TestEdge(E, H));
198 correctEdgeList.add(new TestEdge(H, G));
Koosha1525c452016-10-28 18:25:19 +0330199 assertTrue("The second path from A to G was incorrect.",
200 edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
201 }
202
203
Aaron Kruglikov07d80382015-12-07 16:54:37 -0800204 private boolean edgeListsAreEqual(List<TestEdge> edgeListOne, List<TestEdge> edgeListTwo) {
205 if (edgeListOne.size() != edgeListTwo.size()) {
206 return false;
207 }
208 TestEdge edgeOne;
209 TestEdge edgeTwo;
210 for (int i = 0; i < edgeListOne.size(); i++) {
211 edgeOne = edgeListOne.get(i);
212 edgeTwo = edgeListTwo.get(i);
213 if (!edgeOne.equals(edgeTwo)) {
214 return false;
215 }
216 }
217 return true;
218 }
Koosha1525c452016-10-28 18:25:19 +0330219}