blob: 3eff440137ed30d856598441a5f6cc5bf2e13568 [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 */
tom2e1f0712014-08-29 13:32:00 -070019package org.onlab.graph;
20
21/**
22 * Bellman-Ford graph search algorithm for locating shortest-paths in
23 * directed graphs that may contain negative cycles.
24 */
25public class BellmanFordGraphSearch<V extends Vertex, E extends Edge<V>>
26 extends AbstractGraphPathSearch<V, E> {
27
28 @Override
29 public Result<V, E> search(Graph<V, E> graph, V src, V dst,
30 EdgeWeight<V, E> weight) {
31 checkArguments(graph, src, dst);
32
33 // Prepare the graph search result.
34 DefaultResult result = new DefaultResult(src, dst);
35
36 // The source vertex has cost 0, of course.
37 result.updateVertex(src, null, 0.0, true);
38
39 int max = graph.getVertexes().size() - 1;
40 for (int i = 0; i < max; i++) {
41 // Relax, if possible, all egress edges of the current vertex.
42 for (E edge : graph.getEdges()) {
43 if (result.hasCost(edge.src())) {
44 result.relaxEdge(edge, result.cost(edge.src()), weight);
45 }
46 }
47 }
48
49 // Remove any vertexes reached by traversing edges with negative weights.
50 for (E edge : graph.getEdges()) {
51 if (result.hasCost(edge.src())) {
52 if (result.relaxEdge(edge, result.cost(edge.src()), weight)) {
53 result.removeVertex(edge.dst());
54 }
55 }
56 }
57
58 // Finally, but the paths on the search result and return.
59 result.buildPaths();
60 return result;
61 }
62
63}