blob: 75a5a73f26eaa1d43ac7589e122d74b446cc352b [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
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 */
tom144de692014-08-29 11:38:44 -070019package org.onlab.graph;
20
21import java.util.HashSet;
22import java.util.Set;
23
24/**
25 * Implementation of the BFS algorithm.
26 */
27public class BreadthFirstSearch<V extends Vertex, E extends Edge<V>>
28 extends AbstractGraphPathSearch<V, E> {
29
30 @Override
tom2e1f0712014-08-29 13:32:00 -070031 public Result<V, E> search(Graph<V, E> graph, V src, V dst,
32 EdgeWeight<V, E> weight) {
tom144de692014-08-29 11:38:44 -070033 checkArguments(graph, src, dst);
tomc53fa0d2014-08-29 11:57:11 -070034
tom144de692014-08-29 11:38:44 -070035 // Prepare the graph result.
36 DefaultResult result = new DefaultResult(src, dst);
37
38 // Setup the starting frontier with the source as the sole vertex.
39 Set<V> frontier = new HashSet<>();
tom2e1f0712014-08-29 13:32:00 -070040 result.updateVertex(src, null, 0.0, true);
tom144de692014-08-29 11:38:44 -070041 frontier.add(src);
tomc53fa0d2014-08-29 11:57:11 -070042
tom19bf4212014-08-29 13:08:29 -070043 boolean reachedEnd = false;
44 while (!reachedEnd && !frontier.isEmpty()) {
tom144de692014-08-29 11:38:44 -070045 // Prepare the next frontier.
46 Set<V> next = new HashSet<>();
47
48 // Visit all vertexes in the current frontier.
49 for (V vertex : frontier) {
50 double cost = result.cost(vertex);
tomc53fa0d2014-08-29 11:57:11 -070051
tom144de692014-08-29 11:38:44 -070052 // Visit all egress edges of the current frontier vertex.
53 for (E edge : graph.getEdgesFrom(vertex)) {
54 V nextVertex = edge.dst();
55 if (!result.hasCost(nextVertex)) {
56 // If this vertex has not been visited yet, update it.
tom2e1f0712014-08-29 13:32:00 -070057 double newCost = cost + (weight == null ? 1.0 : weight.weight(edge));
58 result.updateVertex(nextVertex, edge, newCost, true);
tom144de692014-08-29 11:38:44 -070059 // If we have reached our intended destination, bail.
tomc53fa0d2014-08-29 11:57:11 -070060 if (nextVertex.equals(dst)) {
tom19bf4212014-08-29 13:08:29 -070061 reachedEnd = true;
62 break;
tomc53fa0d2014-08-29 11:57:11 -070063 }
tom144de692014-08-29 11:38:44 -070064 next.add(nextVertex);
65 }
tom19bf4212014-08-29 13:08:29 -070066
67 if (reachedEnd) {
68 break;
69 }
tom144de692014-08-29 11:38:44 -070070 }
71 }
tomc53fa0d2014-08-29 11:57:11 -070072
tom144de692014-08-29 11:38:44 -070073 // Promote the next frontier.
74 frontier = next;
75 }
tomc53fa0d2014-08-29 11:57:11 -070076
tom144de692014-08-29 11:38:44 -070077 // Finally, but the paths on the search result and return.
78 result.buildPaths();
79 return result;
80 }
tomc53fa0d2014-08-29 11:57:11 -070081
tom144de692014-08-29 11:38:44 -070082}