// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea // Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology // Distributed under the terms of the GNU Lesser General Public License (LGPL): http://www.gnu.org/licenses/ package graphtea.library.algorithms.shortestpath; import graphtea.library.BaseEdge; import graphtea.library.BaseGraph; import graphtea.library.BaseVertex; import graphtea.library.algorithms.Algorithm; import graphtea.library.algorithms.AutomatedAlgorithm; import graphtea.library.event.GraphRequest; import graphtea.library.event.VertexRequest; import java.util.Iterator; import java.util.Vector; /** * This method finds the shortest path from a source vertex v, to all * vertices of the graph. * Unlike dijkstra, this method will works properly, for * graphs with negative edges, as well as graphs with non negative edge's * weights. * * @author Soroush Sabet */ public class BellmanFord<VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>> extends Algorithm implements AutomatedAlgorithm { private BaseGraph<VertexType, EdgeType> graph; /** * A graph with a negative cycle is not well defined * as the input of a shortest path algorithm. Bellman-Ford * algorithms checks for this inconvenienc, along with * solving the single source shortest path algorithm. * * @param graph with arbitrary edge weights. * @param Vertex as the source. * @return null if there be a negative cycle in the graph; * and the vector of predecessors, otherwise. */ public Vector<VertexType> computePaths (final BaseGraph<VertexType, EdgeType> graph, VertexType Vertex) { // graph.checkVertex(Vertex); Integer[] dist; dist = new Integer[graph.getVerticesCount()]; Vector<VertexType> ret = new Vector<>(); for (int i = 0; i < dist.length; i++) dist[i] = Integer.MAX_VALUE; dist[Vertex.getId()] = 0; EdgeType edge; int i; Iterator<EdgeType> iet; for (i = 1; i < graph.getVerticesCount(); i++) { iet = graph.edgeIterator(); while (iet.hasNext()) { edge = iet.next(); if (dist[edge.source.getId()] > dist[edge.target.getId()] + edge.getWeight()) { dist[edge.source.getId()] = dist[edge.target.getId()] + edge.getWeight(); ret.add(edge.source.getId(), edge.target); } } } iet = graph.edgeIterator(); while (iet.hasNext()) { edge = iet.next(); if (dist[edge.source.getId()] > dist[edge.target.getId()] + edge.getWeight()) return null; } return ret; } public void doAlgorithm() { GraphRequest<VertexType, EdgeType> gr = new GraphRequest<>(); dispatchEvent(gr); this.graph = gr.getGraph(); VertexRequest<VertexType, EdgeType> vr = new VertexRequest<>(graph, "Please choose a vertex for the BellmanFord algorithm."); dispatchEvent(vr); Vector<VertexType> vv = this.computePaths(graph, vr.getVertex()); for (VertexType v : vv) v.setColor(v.getColor() + 1); //how to show the results?? } }