001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU Lesser General Public License (LGPL): http://www.gnu.org/licenses/
004    
005    package graphlab.library.algorithms.shortestpath;
006    
007    import graphlab.library.BaseEdge;
008    import graphlab.library.BaseGraph;
009    import graphlab.library.BaseVertex;
010    import graphlab.library.algorithms.Algorithm;
011    import graphlab.library.algorithms.AutomatedAlgorithm;
012    import graphlab.library.event.GraphRequest;
013    import graphlab.library.event.VertexRequest;
014    
015    import java.util.Iterator;
016    import java.util.Vector;
017    
018    /**
019     * This method finds the shortest path from a source vertex v, to all
020     * vertices of the graph.
021     * Unlike dijkstra, this method will works properly, for
022     * graphs with negative edges, as well as graphs with non negative edge's
023     * weights.
024     *
025     * @author Soroush Sabet
026     */
027    public class BellmanFord<VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>> extends Algorithm implements AutomatedAlgorithm {
028        private BaseGraph<VertexType, EdgeType> graph;
029    
030        /**
031         * A graph with a negative cycle is not well defined
032         * as the input of a shortest path algorithm. Bellman-Ford
033         * algorithms checks for this inconvenienc, along with
034         * solving the single source shortest path algorithm.
035         *
036         * @param graph  with arbitrary edge weights.
037         * @param Vertex as the source.
038         * @return null if there be a negative cycle in the graph;
039         *         and the vector of predecessors, otherwise.
040         */
041    
042        public Vector<VertexType> computePaths
043                (final BaseGraph<VertexType, EdgeType> graph, VertexType Vertex) {
044    
045    //        graph.checkVertex(Vertex);
046    
047            Integer[] dist;
048            dist = new Integer[graph.getVerticesCount()];
049            Vector<VertexType> ret = new Vector<VertexType>();
050    
051            for (int i = 0; i < dist.length; i++)
052                dist[i] = Integer.MAX_VALUE;
053    
054            dist[Vertex.getId()] = 0;
055    
056            EdgeType edge;
057            int i;
058            Iterator<EdgeType> iet;
059    
060            for (i = 1; i < graph.getVerticesCount(); i++) {
061                iet = graph.edgeIterator();
062                while (iet.hasNext()) {
063                    edge = iet.next();
064                    if (dist[edge.source.getId()] > dist[edge.target.getId()] + edge.getWeight()) {
065                        dist[edge.source.getId()] = dist[edge.target.getId()] + edge.getWeight();
066                        ret.add(edge.source.getId(), edge.target);
067                    }
068                }
069            }
070    
071            iet = graph.edgeIterator();
072            while (iet.hasNext()) {
073                edge = iet.next();
074                if (dist[edge.source.getId()] > dist[edge.target.getId()] + edge.getWeight())
075                    return null;
076            }
077            return ret;
078        }
079    
080        public void doAlgorithm() {
081            GraphRequest<VertexType, EdgeType> gr = new GraphRequest<VertexType, EdgeType>();
082            dispatchEvent(gr);
083            this.graph = gr.getGraph();
084            VertexRequest<VertexType, EdgeType> vr = new VertexRequest<VertexType, EdgeType>(graph, "Please choose a vertex for the BellmanFord algorithm.");
085            dispatchEvent(vr);
086            Vector<VertexType> vv = this.computePaths(graph, vr.getVertex());
087            for (VertexType v : vv)
088                v.setColor(v.getColor() + 1);
089            //how to show the results??
090        }
091    }