blob: c5b0f4f86ed2fc6c77c2b6fccfa5dac991097267 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
tom144de692014-08-29 11:38:44 -070016package org.onlab.graph;
17
18import java.util.HashSet;
19import java.util.Set;
20
21/**
22 * Implementation of the BFS algorithm.
23 */
24public class BreadthFirstSearch<V extends Vertex, E extends Edge<V>>
25 extends AbstractGraphPathSearch<V, E> {
26
27 @Override
Andrey Komarov2398d962016-09-26 15:11:23 +030028 protected Result<V, E> internalSearch(Graph<V, E> graph, V src, V dst,
29 EdgeWeigher<V, E> weigher, int maxPaths) {
tomc53fa0d2014-08-29 11:57:11 -070030
tom144de692014-08-29 11:38:44 -070031 // Prepare the graph result.
Thomas Vachuskac31d9f12015-01-22 12:33:27 -080032 DefaultResult result = new DefaultResult(src, dst, maxPaths);
tom144de692014-08-29 11:38:44 -070033
34 // Setup the starting frontier with the source as the sole vertex.
35 Set<V> frontier = new HashSet<>();
Andrey Komarov2398d962016-09-26 15:11:23 +030036 result.updateVertex(src, null, weigher.getInitialWeight(), true);
tom144de692014-08-29 11:38:44 -070037 frontier.add(src);
tomc53fa0d2014-08-29 11:57:11 -070038
tom19bf4212014-08-29 13:08:29 -070039 boolean reachedEnd = false;
40 while (!reachedEnd && !frontier.isEmpty()) {
tom144de692014-08-29 11:38:44 -070041 // Prepare the next frontier.
42 Set<V> next = new HashSet<>();
43
44 // Visit all vertexes in the current frontier.
45 for (V vertex : frontier) {
Andrey Komarov2398d962016-09-26 15:11:23 +030046 Weight cost = result.cost(vertex);
tomc53fa0d2014-08-29 11:57:11 -070047
tom144de692014-08-29 11:38:44 -070048 // Visit all egress edges of the current frontier vertex.
49 for (E edge : graph.getEdgesFrom(vertex)) {
50 V nextVertex = edge.dst();
51 if (!result.hasCost(nextVertex)) {
52 // If this vertex has not been visited yet, update it.
Andrey Komarov2398d962016-09-26 15:11:23 +030053 Weight newCost = cost.merge(weigher.weight(edge));
tom2e1f0712014-08-29 13:32:00 -070054 result.updateVertex(nextVertex, edge, newCost, true);
tom144de692014-08-29 11:38:44 -070055 // If we have reached our intended destination, bail.
tomc53fa0d2014-08-29 11:57:11 -070056 if (nextVertex.equals(dst)) {
tom19bf4212014-08-29 13:08:29 -070057 reachedEnd = true;
58 break;
tomc53fa0d2014-08-29 11:57:11 -070059 }
tom144de692014-08-29 11:38:44 -070060 next.add(nextVertex);
61 }
tom19bf4212014-08-29 13:08:29 -070062
63 if (reachedEnd) {
64 break;
65 }
tom144de692014-08-29 11:38:44 -070066 }
67 }
tomc53fa0d2014-08-29 11:57:11 -070068
tom144de692014-08-29 11:38:44 -070069 // Promote the next frontier.
70 frontier = next;
71 }
tomc53fa0d2014-08-29 11:57:11 -070072
tom144de692014-08-29 11:38:44 -070073 // Finally, but the paths on the search result and return.
74 result.buildPaths();
75 return result;
76 }
tomc53fa0d2014-08-29 11:57:11 -070077
tom144de692014-08-29 11:38:44 -070078}