Beispiel #1
0
 public Paths(Vertex source, HashMap <Vertex, Edge <Vertex> > edgeTo)
 {
     Source      = source;
     this.edgeTo = edgeTo;
 }
Beispiel #2
0
        /// <summary>
        /// Solves the single-source shortest path problem in O(E*V) time for a graph without any negative cycles, or in O(V+E) time if it is a DAG.
        /// </summary>
        public static Paths <V> BellmanFord <V>(DiGraph <V> graph, V source)
        {
            if (graph == null || source == null)
            {
                throw new ArgumentNullException();
            }

            if (!graph.Contains(source))
            {
                throw new ArgumentException();
            }

            var distTo = new HashMap <V, Double>();
            var edgeTo = new HashMap <V, Edge <V> >();

            bool Relax(Edge <V> e)
            {
                var(v, w) = (e.from, e.to);
                var weight = new Double(e.weight);

                if (distTo[v] > distTo[w] + weight)
                {
                    distTo[w] = distTo[v] + weight;
                    edgeTo[w] = e;
                    return(true);
                }
                return(false);
            }

            foreach (var v in graph.Vertices())
            {
                distTo[v] = Double.MaxValue;
            }
            distTo[source] = new Double(0);

            // The Bellman Ford procedure involves relaxing every edge V times.
            // However, for a DAG we can delegate to a simpler algorithm that runs in linear time

            try
            {
                var vertices = TopologicalSort(graph);
                foreach (var v in vertices)
                {
                    foreach (var e in graph.Edges(v))
                    {
                        Relax(e);
                    }
                }
            }
            catch (InvalidOperationException)
            {
                // Graph is not a DAG
                var N = graph.Size();
                foreach (var i in Enumerable.Range(1, N))
                {
                    foreach (var e in graph.Edges())
                    {
                        var relaxed = Relax(e);
                        if (i == N && relaxed)
                        {
                            throw new InvalidOperationException("Negative cycle detected");
                        }
                    }
                }
            }

            return(new Paths <V>(source, edgeTo));
        }