blob: f5c60dbc8de966a8687f44aabf53dd6ad30ef4e7 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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
tom2e1f0712014-08-29 13:32:00 -070028 public Result<V, E> search(Graph<V, E> graph, V src, V dst,
29 EdgeWeight<V, E> weight) {
tom144de692014-08-29 11:38:44 -070030 checkArguments(graph, src, dst);
tomc53fa0d2014-08-29 11:57:11 -070031
tom144de692014-08-29 11:38:44 -070032 // Prepare the graph result.
33 DefaultResult result = new DefaultResult(src, dst);
34
35 // Setup the starting frontier with the source as the sole vertex.
36 Set<V> frontier = new HashSet<>();
tom2e1f0712014-08-29 13:32:00 -070037 result.updateVertex(src, null, 0.0, true);
tom144de692014-08-29 11:38:44 -070038 frontier.add(src);
tomc53fa0d2014-08-29 11:57:11 -070039
tom19bf4212014-08-29 13:08:29 -070040 boolean reachedEnd = false;
41 while (!reachedEnd && !frontier.isEmpty()) {
tom144de692014-08-29 11:38:44 -070042 // Prepare the next frontier.
43 Set<V> next = new HashSet<>();
44
45 // Visit all vertexes in the current frontier.
46 for (V vertex : frontier) {
47 double cost = result.cost(vertex);
tomc53fa0d2014-08-29 11:57:11 -070048
tom144de692014-08-29 11:38:44 -070049 // Visit all egress edges of the current frontier vertex.
50 for (E edge : graph.getEdgesFrom(vertex)) {
51 V nextVertex = edge.dst();
52 if (!result.hasCost(nextVertex)) {
53 // If this vertex has not been visited yet, update it.
tom2e1f0712014-08-29 13:32:00 -070054 double newCost = cost + (weight == null ? 1.0 : weight.weight(edge));
55 result.updateVertex(nextVertex, edge, newCost, true);
tom144de692014-08-29 11:38:44 -070056 // If we have reached our intended destination, bail.
tomc53fa0d2014-08-29 11:57:11 -070057 if (nextVertex.equals(dst)) {
tom19bf4212014-08-29 13:08:29 -070058 reachedEnd = true;
59 break;
tomc53fa0d2014-08-29 11:57:11 -070060 }
tom144de692014-08-29 11:38:44 -070061 next.add(nextVertex);
62 }
tom19bf4212014-08-29 13:08:29 -070063
64 if (reachedEnd) {
65 break;
66 }
tom144de692014-08-29 11:38:44 -070067 }
68 }
tomc53fa0d2014-08-29 11:57:11 -070069
tom144de692014-08-29 11:38:44 -070070 // Promote the next frontier.
71 frontier = next;
72 }
tomc53fa0d2014-08-29 11:57:11 -070073
tom144de692014-08-29 11:38:44 -070074 // Finally, but the paths on the search result and return.
75 result.buildPaths();
76 return result;
77 }
tomc53fa0d2014-08-29 11:57:11 -070078
tom144de692014-08-29 11:38:44 -070079}