Пример #1
0
        internal static Dictionary <string, double> Ancestor(Graph weightedDirectedGraph)
        {
            var tempGraph        = new Graph();
            var resultDictionary = new Dictionary <string, double>();

            //Create negative weighted directed graph
            tempGraph.AddVertexRange(weightedDirectedGraph.Vertices);
            tempGraph.AddEdgeRange(weightedDirectedGraph.Edges.Select(x => new Edge(x.Name, x.Source, x.Target, -x.Weight)));
            //Solve shortest path of Top -> vertex
            var algorithm = new BellmanFordShortestPathAlgorithm <string, Edge>(tempGraph, e => e.Weight);
            var pred      = new VertexPredecessorRecorderObserver <string, Edge>();

            pred.Attach(algorithm);
            foreach (var vertex in tempGraph.Vertices)
            {
                algorithm.Compute("Top");
                IEnumerable <Edge> path;
                pred.TryGetPath(vertex, out path);
                if (path != null)
                {
                    resultDictionary[vertex] = -path.Sum(a => a.Weight);
                }
            }
            return(resultDictionary);
        }
Пример #2
0
        public static TryFunc <TVertex, IEnumerable <TEdge> > ShortestPathsBellmanFord <TVertex, TEdge>(
#if !NET20
            this
#endif
            IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
            Func <TEdge, double> edgeWeights,
            TVertex source
            )
            where TEdge : IEdge <TVertex>
        {
            Contract.Requires(visitedGraph != null);
            Contract.Requires(edgeWeights != null);
            Contract.Requires(source != null);

            var algorithm           = new BellmanFordShortestPathAlgorithm <TVertex, TEdge>(visitedGraph, edgeWeights);
            var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (predecessorRecorder.Attach(algorithm))
                algorithm.Compute(source);

            var predecessors = predecessorRecorder.VertexPredecessors;

            return(delegate(TVertex v, out IEnumerable <TEdge> edges)
            {
                return EdgeExtensions.TryGetPath(predecessors, v, out edges);
            });
        }
Пример #3
0
        public static IDictionary <int, double> Get(AdjacencyGraph <int, Edge <int> > graph, int root)
        {
            Func <Edge <int>, double> Weights = e => 1.0;

            var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, Weights);

            algorithm.Compute(root);
            return(algorithm.Distances);
        }
Пример #4
0
        public static IDictionary <string, double> Get(AdjacencyGraph <string, TaggedEdge <string, string> > graph, string root)
        {
            Func <TaggedEdge <string, string>, double> Weights = e => double.Parse(e.Tag);

            var algorithm = new BellmanFordShortestPathAlgorithm <string, TaggedEdge <string, string> >(graph, Weights);

            algorithm.Compute(root);
            return(algorithm.Distances);
        }
Пример #5
0
        public void GetVertexColor_Throws()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVertex(0);
            var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, edge => 1.0);

            algorithm.Compute(0);

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            Assert.Throws <VertexNotFoundException>(() => algorithm.GetVertexColor(1));
        }
Пример #6
0
        public void GetVertexColor()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVerticesAndEdge(new Edge <int>(1, 2));

            var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, _ => 1.0);

            algorithm.Compute(1);

            Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(1));
            Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(2));
        }
Пример #7
0
        public static BellmanFordShortestPathAlgorithm <T, Edge <T> > CreateAlgorithmAndMaybeDoComputation <T>(
            [NotNull] ContractScenario <T> scenario)
        {
            var graph = new AdjacencyGraph <T, Edge <T> >();

            graph.AddVerticesAndEdgeRange(scenario.EdgesInGraph.Select(e => new Edge <T>(e.Source, e.Target)));
            graph.AddVertexRange(scenario.SingleVerticesInGraph);

            double Weights(Edge <T> e) => 1.0;

            var algorithm = new BellmanFordShortestPathAlgorithm <T, Edge <T> >(graph, Weights);

            if (scenario.DoComputation)
            {
                algorithm.Compute(scenario.Root);
            }
            return(algorithm);
        }
Пример #8
0
        //public void FindPath(string @from = "START", string @to = "END")
        //{
        //    Func<Edge<string>, double> edgeCost = AlgorithmExtensions.GetIndexer(EdgeCost);
        //    // Positive or negative weights
        //    TryFunc<string, System.Collections.Generic.IEnumerable<Edge<string>>> tryGetPath = Graph.ShortestPathsBellmanFord(edgeCost, @from);

        //    IEnumerable<Edge<string>> path;
        //    if (tryGetPath(@to, out path))
        //    {
        //        Console.Write("Path found from {0} to {1}: {0}", @from, @to);
        //        foreach (var e in path) { Console.Write(" > {0}", e.Target); }
        //        Console.WriteLine();
        //    }
        //    else { Console.WriteLine("No path found from {0} to {1}."); }
        //}

        public double GetETA(string start = "A")
        {
            Func <Edge <Vertex>, double> edgeCost = e => this.edgeCostList[e];

            // Bellman algorithm works with either positive or negative weights
            BellmanFordShortestPathAlgorithm <Vertex, Edge <Vertex> > pathCalc = new BellmanFordShortestPathAlgorithm <Vertex, Edge <Vertex> >(this.graph, edgeCost);

            Vertex source = nodeMap[start];
            Vertex target = nodeMap["Z"];

            pathCalc.Compute(source);

            var distances = pathCalc.Distances;

            var distanceToTarget = 0 - distances[target];

            return(distanceToTarget);
        }
Пример #9
0
        private static void RunBellmanFordAndCheck <TVertex, TEdge>(
            [NotNull] IVertexAndEdgeListGraph <TVertex, TEdge> graph,
            [NotNull] TVertex root)
            where TEdge : IEdge <TVertex>
        {
            var distances = new Dictionary <TEdge, double>();

            foreach (TEdge edge in graph.Edges)
            {
                distances[edge] = graph.OutDegree(edge.Source) + 1;
            }

            var algorithm = new BellmanFordShortestPathAlgorithm <TVertex, TEdge>(
                graph,
                e => distances[e]);

            algorithm.InitializeVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]);
            };

            var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (predecessors.Attach(algorithm))
                algorithm.Compute(root);

            Assert.AreEqual(graph.VertexCount, algorithm.VerticesColors.Count);
            foreach (TVertex vertex in graph.Vertices)
            {
                Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]);
            }

            Assert.IsFalse(algorithm.FoundNegativeCycle);
            CollectionAssert.IsNotEmpty(algorithm.GetDistances());
            Assert.AreEqual(graph.VertexCount, algorithm.GetDistances().Count());

            Verify(algorithm, predecessors);
        }
Пример #10
0
        public void BellmanFord_NegativeCycle()
        {
            // Without negative cycle
            var edge12 = new Edge <int>(1, 2);
            var edge23 = new Edge <int>(2, 3);
            var edge34 = new Edge <int>(3, 4);

            var negativeWeightGraph = new AdjacencyGraph <int, Edge <int> >();

            negativeWeightGraph.AddVerticesAndEdgeRange(new[]
            {
                edge12, edge23, edge34
            });

            var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(
                negativeWeightGraph,
                e =>
            {
                if (e == edge12)
                {
                    return(12.0);
                }
                if (e == edge23)
                {
                    return(-23.0);
                }
                if (e == edge34)
                {
                    return(-34.0);
                }
                return(1.0);
            });

            Assert.DoesNotThrow(() => algorithm.Compute(1));
            Assert.IsFalse(algorithm.FoundNegativeCycle);

            // With negative cycle
            var edge41 = new Edge <int>(4, 1);

            var negativeCycleGraph = new AdjacencyGraph <int, Edge <int> >();

            negativeCycleGraph.AddVerticesAndEdgeRange(new[]
            {
                edge12, edge23, edge34, edge41
            });

            algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(
                negativeCycleGraph,
                e =>
            {
                if (e == edge12)
                {
                    return(12.0);
                }
                if (e == edge23)
                {
                    return(-23.0);
                }
                if (e == edge34)
                {
                    return(-34.0);
                }
                if (e == edge41)
                {
                    return(41.0);
                }
                return(1.0);
            });
            Assert.DoesNotThrow(() => algorithm.Compute(1));
            Assert.IsTrue(algorithm.FoundNegativeCycle);
        }