public void Constructor()
        {
            var graph = new BidirectionalGraph <int, Edge <int> >();

            graph.AddVertexRange(new[] { 1, 2 });
            graph.AddVerticesAndEdge(new Edge <int>(1, 3));
            VertexFactory <int>            vertexFactory = () => 1;
            EdgeFactory <int, Edge <int> > edgeFactory   = (source, target) => new Edge <int>(source, target);
            var capacities = new Dictionary <Edge <int>, double>();

            var algorithm = new GraphBalancerAlgorithm <int, Edge <int> >(graph, 1, 2, vertexFactory, edgeFactory);

            Assert.AreSame(graph, algorithm.VisitedGraph);
            Assert.AreSame(vertexFactory, algorithm.VertexFactory);
            Assert.AreSame(edgeFactory, algorithm.EdgeFactory);
            Assert.IsFalse(algorithm.Balanced);
            Assert.AreEqual(1, algorithm.Source);
            Assert.AreEqual(2, algorithm.Sink);
            Assert.IsNotNull(algorithm.Capacities);
            Assert.AreEqual(graph.EdgeCount, algorithm.Capacities.Count);
            CollectionAssert.IsEmpty(algorithm.SurplusVertices);
            CollectionAssert.IsEmpty(algorithm.SurplusEdges);
            CollectionAssert.IsEmpty(algorithm.DeficientVertices);
            CollectionAssert.IsEmpty(algorithm.DeficientEdges);
            Assert.AreEqual(default(int), algorithm.BalancingSource);
            Assert.AreEqual(default(Edge <int>), algorithm.BalancingSourceEdge);
            Assert.AreEqual(default(int), algorithm.BalancingSink);
            Assert.AreEqual(default(Edge <int>), algorithm.BalancingSinkEdge);

            algorithm = new GraphBalancerAlgorithm <int, Edge <int> >(graph, 1, 2, vertexFactory, edgeFactory, capacities);
            Assert.AreSame(graph, algorithm.VisitedGraph);
            Assert.AreSame(vertexFactory, algorithm.VertexFactory);
            Assert.AreSame(edgeFactory, algorithm.EdgeFactory);
            Assert.IsFalse(algorithm.Balanced);
            Assert.AreEqual(1, algorithm.Source);
            Assert.AreEqual(2, algorithm.Sink);
            Assert.AreSame(capacities, algorithm.Capacities);
            CollectionAssert.IsEmpty(algorithm.SurplusVertices);
            CollectionAssert.IsEmpty(algorithm.SurplusEdges);
            CollectionAssert.IsEmpty(algorithm.DeficientVertices);
            CollectionAssert.IsEmpty(algorithm.DeficientEdges);
            Assert.AreEqual(default(int), algorithm.BalancingSource);
            Assert.AreEqual(default(Edge <int>), algorithm.BalancingSourceEdge);
            Assert.AreEqual(default(int), algorithm.BalancingSink);
            Assert.AreEqual(default(Edge <int>), algorithm.BalancingSinkEdge);
        }
Esempio n. 2
0
        public void AddReversedEdges <TEdge>([NotNull] EdgeFactory <int, TEdge> edgeFactory)
            where TEdge : IEdge <int>
        {
            TEdge edge12 = edgeFactory(1, 2);
            TEdge edge13 = edgeFactory(1, 3);
            TEdge edge23 = edgeFactory(2, 3);
            TEdge edge32 = edgeFactory(3, 2);

            var graph = new AdjacencyGraph <int, TEdge>();

            graph.AddVerticesAndEdgeRange(new[]
            {
                edge12, edge13, edge23, edge32
            });

            var algorithm = new ReversedEdgeAugmentorAlgorithm <int, TEdge>(graph, edgeFactory);

            var reverseEdgesAdded = new List <TEdge>();

            algorithm.ReversedEdgeAdded += edge => reverseEdgesAdded.Add(edge);

            algorithm.AddReversedEdges();

            Assert.IsTrue(algorithm.Augmented);
            CollectionAssert.IsNotEmpty(algorithm.AugmentedEdges);
            TEdge[] augmentedEdges = algorithm.AugmentedEdges.ToArray();
            Assert.AreEqual(2, augmentedEdges.Length);
            Assert.AreEqual(2, augmentedEdges[0].Source);
            Assert.AreEqual(1, augmentedEdges[0].Target);
            Assert.AreEqual(3, augmentedEdges[1].Source);
            Assert.AreEqual(1, augmentedEdges[1].Target);

            CollectionAssert.AreEquivalent(
                new Dictionary <TEdge, TEdge>
            {
                [edge12]            = augmentedEdges[0],
                [augmentedEdges[0]] = edge12,
                [edge13]            = augmentedEdges[1],
                [augmentedEdges[1]] = edge13,
                [edge23]            = edge32,
                [edge32]            = edge23,
            },
                algorithm.ReversedEdges);

            CollectionAssert.AreEqual(augmentedEdges, reverseEdgesAdded);
        }
        public void GetBalancingIndex_Throws()
        {
            var source = new TestVertex("1");
            var sink   = new TestVertex("2");
            var graph  = new BidirectionalGraph <TestVertex, Edge <TestVertex> >();

            graph.AddVertexRange(new[] { source, sink });
            VertexFactory <TestVertex> vertexFactory = () => new TestVertex();
            EdgeFactory <TestVertex, Edge <TestVertex> > edgeFactory = (s, t) => new Edge <TestVertex>(s, t);

            var algorithm = new GraphBalancerAlgorithm <TestVertex, Edge <TestVertex> >(
                graph, source, sink, vertexFactory, edgeFactory);

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            // ReSharper disable once AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(() => algorithm.GetBalancingIndex(null));
        }
        public static void Create <TVertex, TEdge>(
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> g,
            VertexFactory <TVertex> vertexFactory,
            EdgeFactory <TVertex, TEdge> edgeFactory,
            Random rnd,
            int vertexCount,
            int edgeCount,
            bool selfEdges
            ) where TEdge : IEdge <TVertex>
        {
            //Contract.Requires(g != null);
            //Contract.Requires(vertexFactory != null);
            //Contract.Requires(edgeFactory != null);
            //Contract.Requires(rnd != null);
            //Contract.Requires(vertexCount > 0);
            //Contract.Requires(edgeCount >= 0);
            //Contract.Requires(
            //    !(!g.AllowParallelEdges && !selfEdges) ||
            //    edgeCount <= vertexCount * (vertexCount -1) // directed graph
            //   );

            var vertices = new TVertex[vertexCount];

            for (int i = 0; i < vertexCount; ++i)
            {
                g.AddVertex(vertices[i] = vertexFactory());
            }

            TVertex a;
            TVertex b;
            int     j = 0;

            while (j < edgeCount)
            {
                a = vertices[rnd.Next(vertexCount)];
                do
                {
                    b = vertices[rnd.Next(vertexCount)];
                }while (selfEdges == false && a.Equals(b));

                if (g.AddEdge(edgeFactory(a, b)))
                {
                    ++j;
                }
            }
        }
Esempio n. 5
0
        public void NotReachableSink()
        {
            const string source = "A";
            const string sink   = "G";

            var graph = new AdjacencyGraph <string, TaggedEdge <string, double> >(true);

            graph.AddVertexRange(new[] { "A", "B", "C", "D", "E", "F", "G" });

            // TaggedEdge.Tag is the capacity of the edge
            graph.AddEdgeRange(new[]
            {
                new TaggedEdge <string, double>("A", "D", 3),
                new TaggedEdge <string, double>("A", "B", 3),
                new TaggedEdge <string, double>("B", "C", 4),
                new TaggedEdge <string, double>("C", "A", 3),
                new TaggedEdge <string, double>("C", "D", 1),
                new TaggedEdge <string, double>("D", "E", 2),
                new TaggedEdge <string, double>("D", "F", 6),
                new TaggedEdge <string, double>("E", "B", 1),
                new TaggedEdge <string, double>("C", "E", 2)
            });

            // edgeFactory will be used to create the reversed edges to store residual capacities using the ReversedEdgeAugmentorAlgorithm-class.
            // The edgeFactory assigns a capacity of 0.0 for the new edges because the initial (residual) capacity must be 0.0.
            EdgeFactory <string, TaggedEdge <string, double> > edgeFactory = (sourceNode, targetNode) => new TaggedEdge <string, double>(sourceNode, targetNode, 0.0);
            var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <string, TaggedEdge <string, double> >(graph, edgeFactory);

            reverseEdgesAlgorithm.AddReversedEdges();

            var algorithm = new EdmondsKarpMaximumFlowAlgorithm <string, TaggedEdge <string, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm);

            algorithm.Compute(source, sink);

            Assert.AreEqual(source, algorithm.Source);
            Assert.AreEqual(sink, algorithm.Sink);
            Assert.AreEqual(graph.VertexCount, algorithm.VerticesColors.Count);
            foreach (KeyValuePair <string, GraphColor> pair in algorithm.VerticesColors)
            {
                Assert.AreEqual(
                    pair.Key == sink ? GraphColor.White : GraphColor.Black,
                    pair.Value);
            }
            Assert.AreEqual(0, algorithm.MaxFlow);
        }
Esempio n. 6
0
        public void Constructor()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();
            VertexFactory <int>            vertexFactory = () => 1;
            EdgeFactory <int, Edge <int> > edgeFactory   = (source, target) => new Edge <int>(source, target);

            int[] sourceToVertices = { 1, 2 };
            int[] verticesToSink   = { 1, 2 };

            var algorithm = new MaximumBipartiteMatchingAlgorithm <int, Edge <int> >(
                graph,
                sourceToVertices,
                verticesToSink,
                vertexFactory,
                edgeFactory);

            AssertAlgorithmProperties(
                algorithm,
                graph,
                sourceToVertices,
                verticesToSink,
                vertexFactory,
                edgeFactory);

            #region Local function

            void AssertAlgorithmProperties <TVertex, TEdge>(
                MaximumBipartiteMatchingAlgorithm <TVertex, TEdge> algo,
                IMutableVertexAndEdgeListGraph <TVertex, TEdge> g,
                IEnumerable <TVertex> soToV,
                IEnumerable <TVertex> vToSi,
                VertexFactory <int> vFactory,
                EdgeFactory <int, Edge <int> > eFactory)
                where TEdge : IEdge <TVertex>
            {
                AssertAlgorithmState(algo, g);
                Assert.AreSame(vFactory, algo.VertexFactory);
                Assert.AreSame(eFactory, algo.EdgeFactory);
                Assert.AreSame(soToV, algo.SourceToVertices);
                Assert.AreSame(vToSi, algo.VerticesToSink);
                CollectionAssert.IsEmpty(algo.MatchedEdges);
            }

            #endregion
        }
Esempio n. 7
0
        public MaximumBipartiteMatchingAlgorithm(
            IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
            IEnumerable <TVertex> vertexSetA,
            IEnumerable <TVertex> vertexSetB,
            VertexFactory <TVertex> vertexFactory,
            EdgeFactory <TVertex, TEdge> edgeFactory
            )
            : base(visitedGraph)
        {
            Contract.Requires(vertexFactory != null);
            Contract.Requires(edgeFactory != null);

            this.VertexSetA    = vertexSetA;
            this.VertexSetB    = vertexSetB;
            this.VertexFactory = vertexFactory;
            this.EdgeFactory   = edgeFactory;
            this.MatchedEdges  = new List <TEdge>();
        }
        /**
         * Construct a new graph. The graph can either be directed or undirected, depending on the
         * specified edge factory.
         *
         * @param ef the edge factory of the new graph.
         * @param directed if true the graph will be directed, otherwise undirected
         * @param allowMultipleEdges whether to allow multiple edges or not.
         * @param allowLoops whether to allow edges that are self-loops or not.
         * @param weighted whether the graph is weighted, i.e. the edges support a weight attribute
         *
         * @throws NullPointerException if the specified edge factory is <code>
         * null</code>.
         */
        protected AbstractBaseGraph(
            EdgeFactory <V, E> ef, bool directed, bool allowMultipleEdges, bool allowLoops,
            bool weighted)
        {
            Contract.Requires(ef != null);

            this.edgeFactory           = ef;
            this.allowingLoops         = allowLoops;
            this.allowingMultipleEdges = allowMultipleEdges;
            this.directed = directed;
            this.weighted = weighted;

            this.specifics = createSpecifics(directed);
            Contract.Requires(specifics != null);

            this.intrusiveEdgesSpecifics = createIntrusiveEdgesSpecifics(weighted);
            Contract.Requires(intrusiveEdgesSpecifics != null);
        }
Esempio n. 9
0
        public void EdmondsKarpMaxFlow_Throws()
        {
            var graph = new AdjacencyGraph <TestVertex, TaggedEdge <TestVertex, double> >();
            EdgeFactory <TestVertex, TaggedEdge <TestVertex, double> > edgeFactory = (source, target) => new TaggedEdge <TestVertex, double>(source, target, 0.0);
            var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >(graph, edgeFactory);

            reverseEdgesAlgorithm.AddReversedEdges();

            var algorithm = new EdmondsKarpMaximumFlowAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm);

            var vertex = new TestVertex("1");

            // ReSharper disable AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(() => algorithm.Compute(null, vertex));
            Assert.Throws <ArgumentNullException>(() => algorithm.Compute(vertex, null));
            Assert.Throws <ArgumentNullException>(() => algorithm.Compute(null, null));
            // ReSharper restore AssignNullToNotNullAttribute
        }
Esempio n. 10
0
        public List <TEdge> AddTemporaryEdges([NotNull, InstantHandle] EdgeFactory <TVertex, TEdge> edgeFactory)
        {
            // First gather odd edges
            var oddVertices = VisitedGraph.OddVertices().ToList();

            // Check that there are an even number of them
            if (oddVertices.Count % 2 != 0)
            {
                throw new InvalidOperationException("Number of odd vertices in not even!");
            }

            // Add temporary edges to create even edges
            _temporaryEdges = new List <TEdge>();

            while (oddVertices.Count > 0)
            {
                TVertex u = oddVertices[0];
                // Find adjacent odd vertex
                bool found = FindAdjacentOddVertex(u, oddVertices, edgeFactory, out bool foundAdjacent);
                if (!foundAdjacent)
                {
                    // Pick another vertex
                    if (oddVertices.Count < 2)
                    {
                        throw new InvalidOperationException("Eulerian trail failure.");
                    }
                    TVertex v = oddVertices[1];

                    // Add to temporary edges
                    AddTemporaryEdge(u, v, oddVertices, edgeFactory);

                    // Set u to null
                    found = true;
                }

                if (!found)
                {
                    oddVertices.Remove(u);
                    oddVertices.Add(u);
                }
            }

            return(_temporaryEdges);
        }
Esempio n. 11
0
        /// <summary>
        /// Removes vertices matching the given <paramref name="vertexPredicate"/> and merges all their
        /// connections to other vertices.
        /// </summary>
        /// <param name="vertexPredicate">Predicate to match vertices.</param>
        /// <param name="edgeFactory">Factory method to create an edge.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="vertexPredicate"/> is <see langword="null"/>.</exception>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeFactory"/> is <see langword="null"/>.</exception>
        public void MergeVerticesIf(
            [NotNull, InstantHandle] VertexPredicate<TVertex> vertexPredicate,
            [NotNull, InstantHandle] EdgeFactory<TVertex, TEdge> edgeFactory)
        {
            if (vertexPredicate is null)
                throw new ArgumentNullException(nameof(vertexPredicate));
            if (edgeFactory is null)
                throw new ArgumentNullException(nameof(edgeFactory));

            // Storing vertices to merge
            var mergeVertices = new VertexList<TVertex>(VertexCount / 4);
            mergeVertices.AddRange(Vertices.Where(vertex => vertexPredicate(vertex)));

            // Applying merge recursively
            foreach (TVertex vertex in mergeVertices)
            {
                MergeVertex(vertex, edgeFactory);
            }
        }
        public void GetVertexColor_Throws()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVertexRange(new[] { 0, 1 });

            Func <Edge <int>, double>      capacities  = edge => 1.0;
            EdgeFactory <int, Edge <int> > edgeFactory = (source, target) => new Edge <int>(source, target);
            var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph, edgeFactory);

            reverseEdgesAlgorithm.AddReversedEdges();

            var algorithm = new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph, capacities, edgeFactory, reverseEdgesAlgorithm);

            algorithm.Compute(0, 1);

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            Assert.Throws <VertexNotFoundException>(() => algorithm.GetVertexColor(2));
        }
Esempio n. 13
0
        private void EdmondsKarpMaxFlow <TVertex, TEdge>(IMutableVertexAndEdgeListGraph <TVertex, TEdge> g,
                                                         EdgeFactory <TVertex, TEdge> edgeFactory)
            where TEdge : IEdge <TVertex>
        {
            Assert.True(g.VertexCount > 0);

            foreach (var source in g.Vertices)
            {
                foreach (var sink in g.Vertices)
                {
                    if (source.Equals(sink))
                    {
                        continue;
                    }

                    RunMaxFlowAlgorithm <TVertex, TEdge>(g, edgeFactory, source, sink);
                }
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GraphAugmentorAlgorithmBase{TVertex,TEdge,TGraph}"/> class.
        /// </summary>
        /// <param name="host">Host to use if set, otherwise use this reference.</param>
        /// <param name="visitedGraph">Graph to visit.</param>
        /// <param name="vertexFactory">Vertex factory method.</param>
        /// <param name="edgeFactory">Edge factory method.</param>
        protected GraphAugmentorAlgorithmBase(
            [CanBeNull] IAlgorithmComponent host,
            [NotNull] TGraph visitedGraph,
            [NotNull] VertexFactory <TVertex> vertexFactory,
            [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory)
            : base(host, visitedGraph)
        {
            if (vertexFactory is null)
            {
                throw new ArgumentNullException(nameof(vertexFactory));
            }
            if (edgeFactory is null)
            {
                throw new ArgumentNullException(nameof(edgeFactory));
            }

            VertexFactory = vertexFactory;
            EdgeFactory   = edgeFactory;
        }
        private void AddTemporaryEdge(
            TVertex u,
            TVertex v,
            ICollection <TVertex> oddVertices,
            EdgeFactory <TVertex, TEdge> edgeFactory)
        {
            TEdge tempEdge = edgeFactory(u, v);

            if (!VisitedGraph.AddEdge(tempEdge))
            {
                throw new InvalidOperationException("Cannot add temporary edge.");
            }

            // Add to temporary edges
            _temporaryEdges.Add(tempEdge);

            // Remove u,v from oddVertices
            oddVertices.Remove(u);
            oddVertices.Remove(v);
        }
Esempio n. 16
0
        private static void EdmondsKarpMaxFlow <TVertex, TEdge>(
            [NotNull] IMutableVertexAndEdgeListGraph <TVertex, TEdge> graph,
            [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory)
            where TEdge : IEdge <TVertex>
        {
            Assert.IsTrue(graph.VertexCount > 0);

            foreach (TVertex source in graph.Vertices)
            {
                foreach (TVertex sink in graph.Vertices)
                {
                    if (source.Equals(sink))
                    {
                        continue;
                    }

                    Assert.Positive(RunMaxFlowAlgorithmAndCheck(graph, edgeFactory, source, sink));
                }
            }
        }
Esempio n. 17
0
        private void AddTemporaryEdge(
            [NotNull] TVertex u,
            [NotNull] TVertex v,
            [NotNull, ItemNotNull] List <TVertex> oddVertices,
            [NotNull, InstantHandle] EdgeFactory <TVertex, TEdge> edgeFactory)
        {
            TEdge tempEdge = edgeFactory(u, v);

            if (!VisitedGraph.AddEdge(tempEdge))
            {
                throw new InvalidOperationException();
            }

            // Add to temporary edges
            _temporaryEdges.Add(tempEdge);

            // Remove u,v from oddVertices
            oddVertices.Remove(u);
            oddVertices.Remove(v);
        }
Esempio n. 18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmondsKarpMaximumFlowAlgorithm{TVertex,TEdge}"/> class.
        /// </summary>
        /// <param name="host">Host to use if set, otherwise use this reference.</param>
        /// <param name="visitedGraph">Graph to visit.</param>
        /// <param name="capacities">Function that given an edge return the capacity of this edge.</param>
        /// <param name="edgeFactory">Edge factory method.</param>
        /// <param name="reverseEdgesAugmentorAlgorithm">Algorithm that is in of charge augmenting the graph (creating missing reversed edges).</param>
        public EdmondsKarpMaximumFlowAlgorithm(
            [CanBeNull] IAlgorithmComponent host,
            [NotNull] IMutableVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph,
            [NotNull] Func <TEdge, double> capacities,
            [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory,
            [NotNull] ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverseEdgesAugmentorAlgorithm)
            : base(host, visitedGraph, capacities, edgeFactory)
        {
            if (reverseEdgesAugmentorAlgorithm is null)
            {
                throw new ArgumentNullException(nameof(reverseEdgesAugmentorAlgorithm));
            }
            if (!ReferenceEquals(visitedGraph, reverseEdgesAugmentorAlgorithm.VisitedGraph))
            {
                throw new ArgumentException("Must target the same graph.", nameof(reverseEdgesAugmentorAlgorithm));
            }

            _reverserAlgorithm = reverseEdgesAugmentorAlgorithm;
            ReversedEdges      = reverseEdgesAugmentorAlgorithm.ReversedEdges;
        }
        /// <summary>
        /// Removes the given <paramref name="vertex"/> and merges all its connection to other vertices.
        /// </summary>
        /// <param name="vertex">The vertex.</param>
        /// <param name="edgeFactory">Factory method to create an edge.</param>
        public void MergeVertex(
            [NotNull] TVertex vertex,
            [NotNull, InstantHandle] EdgeFactory <TVertex, TEdge> edgeFactory)
        {
            if (vertex == null)
            {
                throw new ArgumentNullException(nameof(vertex));
            }
            if (edgeFactory is null)
            {
                throw new ArgumentNullException(nameof(edgeFactory));
            }

            // Storing edges in local array
            IEdgeList <TVertex, TEdge> inEdges  = _vertexInEdges[vertex];
            IEdgeList <TVertex, TEdge> outEdges = _vertexOutEdges[vertex];

            // Remove vertex
            RemoveVertex(vertex);

            // Add edges from each source to each target
            foreach (TEdge source in inEdges)
            {
                // Is it a self edge?
                if (source.Source.Equals(vertex))
                {
                    continue;
                }

                foreach (TEdge target in outEdges)
                {
                    if (vertex.Equals(target.Target))
                    {
                        continue;
                    }

                    // We add an new edge
                    AddEdge(edgeFactory(source.Source, target.Target));
                }
            }
        }
Esempio n. 20
0
        public void GetVertexColor()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

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

            Func <Edge <int>, double>      capacities  = edge => 1.0;
            EdgeFactory <int, Edge <int> > edgeFactory = (source, target) => new Edge <int>(source, target);
            var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph, edgeFactory);

            reverseEdgesAlgorithm.AddReversedEdges();

            var algorithm = new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph, capacities, edgeFactory, reverseEdgesAlgorithm);

            algorithm.Compute(1, 2);

            Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(1));
            Assert.AreEqual(GraphColor.White, algorithm.GetVertexColor(2));
            Assert.AreEqual(GraphColor.White, algorithm.GetVertexColor(3));
        }
Esempio n. 21
0
 public static EdgeParser <E, V, W> CreateEdgeParser <E, V, W>(
     EdgeFactory <E, V, W> edgeFactory,
     string separatorBetweenEdgesAndWeightWhenSplitting,
     string separatorBetweenEdgesAndWeightWhenCreating,
     int orderForStartVertex,
     int orderForEndVertex,
     int orderForWeight
     )
     where E : EdgeGenerics <V, W>
     where V : Vertex
     where W : Weight
 {
     return(new EdgeParser <E, V, W>(
                edgeFactory,
                separatorBetweenEdgesAndWeightWhenSplitting,
                separatorBetweenEdgesAndWeightWhenCreating,
                orderForStartVertex,
                orderForEndVertex,
                orderForWeight
                ));
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="GraphBalancerAlgorithm{TVertex,TEdge}"/> class.
        /// </summary>
        /// <param name="visitedGraph">Graph to visit.</param>
        /// <param name="source">Flow source vertex.</param>
        /// <param name="sink">Flow sink vertex.</param>
        /// <param name="vertexFactory">Vertex factory method.</param>
        /// <param name="edgeFactory">Edge factory method.</param>
        /// <param name="capacities">Edges capacities.</param>
        public GraphBalancerAlgorithm(
            [NotNull] IMutableBidirectionalGraph <TVertex, TEdge> visitedGraph,
            [NotNull] VertexFactory <TVertex> vertexFactory,
            [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory,
            [NotNull] TVertex source,
            [NotNull] TVertex sink,
            [NotNull] IDictionary <TEdge, double> capacities)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (sink == null)
            {
                throw new ArgumentNullException(nameof(sink));
            }

            VisitedGraph  = visitedGraph ?? throw new ArgumentNullException(nameof(visitedGraph));
            VertexFactory = vertexFactory ?? throw new ArgumentNullException(nameof(vertexFactory));
            EdgeFactory   = edgeFactory ?? throw new ArgumentNullException(nameof(edgeFactory));

            if (!VisitedGraph.ContainsVertex(source))
            {
                throw new ArgumentException("Source must be in the graph", nameof(source));
            }
            if (!VisitedGraph.ContainsVertex(sink))
            {
                throw new ArgumentException("Sink must be in the graph", nameof(sink));
            }
            Source = source;
            Sink   = sink;

            Capacities = capacities ?? throw new ArgumentNullException(nameof(capacities));

            // Setting preflow = l(e) = 1
            foreach (TEdge edge in VisitedGraph.Edges)
            {
                _preFlow.Add(edge, 1);
            }
        }
        /// <summary>
        /// Removes the given <paramref name="vertex"/> and merges all its connection to other vertices.
        /// </summary>
        /// <param name="vertex">The vertex.</param>
        /// <param name="edgeFactory">Factory method to create an edge.</param>
        public void MergeVertex(
            TVertex vertex,
            EdgeFactory <TVertex, TEdge> edgeFactory)
        {
            if (vertex == null)
            {
                throw new ArgumentNullException(nameof(vertex));
            }
            if (edgeFactory is null)
            {
                throw new ArgumentNullException(nameof(edgeFactory));
            }

            // Storing edges (not a copy)
            // Remove vertex will delete some of these edges
            // but it will remain needed edges to perform the merge
            if (!_vertexInEdges.TryGetValue(vertex, out IEdgeList <TVertex, TEdge> inEdges))
            {
                throw new VertexNotFoundException();
            }
            IEdgeList <TVertex, TEdge> outEdges = _vertexOutEdges[vertex];

            // Remove vertex
            RemoveVertex(vertex);

            // Add edges from each source to each target
            foreach (TEdge source in inEdges)
            {
                foreach (TEdge target in outEdges)
                {
                    if (EqualityComparer <TVertex> .Default.Equals(vertex, target.Target))
                    {
                        continue;
                    }

                    // We add an new edge
                    AddEdgeInternal(edgeFactory(source.Source, target.Target));
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="GraphBalancerAlgorithm{TVertex,TEdge}"/> class.
        /// </summary>
        /// <param name="visitedGraph">Graph to visit.</param>
        /// <param name="source">Flow source vertex.</param>
        /// <param name="sink">Flow sink vertex.</param>
        /// <param name="vertexFactory">Vertex factory method.</param>
        /// <param name="edgeFactory">Edge factory method.</param>
        public GraphBalancerAlgorithm(
            IMutableBidirectionalGraph <TVertex, TEdge> visitedGraph,
            TVertex source,
            TVertex sink,
            VertexFactory <TVertex> vertexFactory,
            EdgeFactory <TVertex, TEdge> edgeFactory)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (sink == null)
            {
                throw new ArgumentNullException(nameof(sink));
            }

            VisitedGraph  = visitedGraph ?? throw new ArgumentNullException(nameof(visitedGraph));
            VertexFactory = vertexFactory ?? throw new ArgumentNullException(nameof(vertexFactory));
            EdgeFactory   = edgeFactory ?? throw new ArgumentNullException(nameof(edgeFactory));

            if (!VisitedGraph.ContainsVertex(source))
            {
                throw new ArgumentException("Source must be in the graph", nameof(source));
            }
            if (!VisitedGraph.ContainsVertex(sink))
            {
                throw new ArgumentException("Sink must be in the graph", nameof(sink));
            }
            Source = source;
            Sink   = sink;

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                // Setting capacities = u(e) = +infinity
                Capacities.Add(edge, double.MaxValue);

                // Setting preflow = l(e) = 1
                _preFlow.Add(edge, 1);
            }
        }
        public void Constructor_Throws()
        {
            var graph = new BidirectionalGraph <int, Edge <int> >();
            VertexFactory <int>            vertexFactory = () => 1;
            EdgeFactory <int, Edge <int> > edgeFactory   = (source, target) => new Edge <int>(source, target);

            // ReSharper disable ObjectCreationAsStatement
            // ReSharper disable AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, vertexFactory, edgeFactory));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(graph, null, edgeFactory));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(graph, vertexFactory, null));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, null, edgeFactory));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, vertexFactory, null));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(graph, null, null));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, null, null));

            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, null, vertexFactory, edgeFactory));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, graph, null, edgeFactory));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, graph, vertexFactory, null));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, null, null, edgeFactory));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, null, vertexFactory, null));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, graph, null, null));
            Assert.Throws <ArgumentNullException>(
                () => new MultiSourceSinkGraphAugmentorAlgorithm <int, Edge <int> >(null, null, null, null));
            // ReSharper restore AssignNullToNotNullAttribute
            // ReSharper restore ObjectCreationAsStatement
        }
Esempio n. 26
0
        public void Run(string dotSource)
        {
            var vertexFun = VertexFactory.Name;
            var edgeFun   = EdgeFactory <GraphXVertex> .Weighted(0);

            var graph = Graph.LoadDot(dotSource, vertexFun, edgeFun);

            if (!graph.Vertices.Any())
            {
                MessageBox.Show("Graph is empty.");
                return;
            }

            _graphArea.LogicCore.Graph = graph;
            _graphArea.GenerateGraph();
            _zoomControl.ZoomToFill();
            _graphVertices = _graphArea.VertexList.ToList();

            _isHamiltonian      = true;
            _currentVertexIndex = 0;
            _threshold          = graph.VertexCount / 2.0;
        }
Esempio n. 27
0
        public void EdmondsKarpMaxFlow_NotAugmented_Throws()
        {
            const int source = 1;
            const int sink   = 4;

            var graph = new AdjacencyGraph <int, TaggedEdge <int, double> >();

            // TaggedEdge.Tag is the capacity of the edge
            graph.AddVerticesAndEdgeRange(new[]
            {
                new TaggedEdge <int, double>(1, 2, 3),
                new TaggedEdge <int, double>(1, 4, 4),
                new TaggedEdge <int, double>(2, 3, -1),
                new TaggedEdge <int, double>(3, 4, 1)
            });

            EdgeFactory <int, TaggedEdge <int, double> > edgeFactory = (sourceNode, targetNode) => new TaggedEdge <int, double>(sourceNode, targetNode, 0.0);
            var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <int, TaggedEdge <int, double> >(graph, edgeFactory);
            var algorithm             = new EdmondsKarpMaximumFlowAlgorithm <int, TaggedEdge <int, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm);

            Assert.Throws <InvalidOperationException>(() => algorithm.Compute(source, sink));
        }
        public void UnBalance()
        {
            var edge12 = new Edge <int>(1, 2);
            var edge13 = new Edge <int>(1, 3);
            var edge23 = new Edge <int>(2, 3);
            var edge32 = new Edge <int>(3, 2);
            var edge34 = new Edge <int>(3, 4);
            var edge56 = new Edge <int>(5, 6);

            var graph = new BidirectionalGraph <int, Edge <int> >();

            graph.AddVerticesAndEdgeRange(new[]
            {
                edge12, edge13, edge23, edge32, edge34, edge56
            });
            int vertexID = 6;
            VertexFactory <int>            vertexFactory = () => vertexID++;
            EdgeFactory <int, Edge <int> > edgeFactory   = (source, target) => new Edge <int>(source, target);

            var algorithm = new GraphBalancerAlgorithm <int, Edge <int> >(graph, 1, 3, vertexFactory, edgeFactory);

            algorithm.Balance();

            Assert.IsTrue(algorithm.Balanced);

            algorithm.UnBalance();

            Assert.IsFalse(algorithm.Balanced);
            Assert.AreEqual(1, algorithm.Source);
            Assert.AreEqual(3, algorithm.Sink);
            CollectionAssert.IsEmpty(algorithm.SurplusVertices);
            CollectionAssert.IsEmpty(algorithm.SurplusEdges);
            CollectionAssert.IsEmpty(algorithm.DeficientVertices);
            CollectionAssert.IsEmpty(algorithm.DeficientEdges);
            Assert.AreEqual(default(int), algorithm.BalancingSource);
            Assert.AreEqual(default(Edge <int>), algorithm.BalancingSourceEdge);
            Assert.AreEqual(default(int), algorithm.BalancingSink);
            Assert.AreEqual(default(Edge <int>), algorithm.BalancingSinkEdge);
        }
Esempio n. 29
0
        private static double RunMaxFlowAlgorithmAndCheck <TVertex, TEdge>(
            [NotNull] IMutableVertexAndEdgeListGraph <TVertex, TEdge> graph,
            [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory,
            [NotNull] TVertex source,
            [NotNull] TVertex sink)
            where TEdge : IEdge <TVertex>
        {
            var reversedEdgeAugmentorAlgorithm = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>(graph, edgeFactory);

            reversedEdgeAugmentorAlgorithm.AddReversedEdges();

            double flow = graph.MaximumFlow(
                edge => 1,
                source, sink,
                out _,
                edgeFactory,
                reversedEdgeAugmentorAlgorithm);

            reversedEdgeAugmentorAlgorithm.RemoveReversedEdges();

            return(flow);
        }
        /// <summary>
        /// Removes each vertex that matches the predicate vertex and creates new edges between all the vertices
        /// that were connected to the deleted vertex.
        /// </summary>
        /// <param name="vertexPredicate">The predicate that indicates which vertices need to be removed.</param>
        /// <param name="edgeFactory">The delegate that is used to create new edges.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="vertexPredicate"/> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="edgeFactory"/> is <see langword="null" />.
        /// </exception>
        public void MergeVertexIf(VertexPredicate <TVertex> vertexPredicate, EdgeFactory <TVertex, TEdge> edgeFactory)
        {
            {
                Lokad.Enforce.Argument(() => vertexPredicate);
                Lokad.Enforce.Argument(() => edgeFactory);
            }

            var list = new List <TVertex>(VertexCount / 4);

            foreach (var vertex in this.Vertices)
            {
                if (vertexPredicate(vertex))
                {
                    list.Add(vertex);
                }
            }

            foreach (var vertex in list)
            {
                this.MergeVertex(vertex, edgeFactory);
            }
        }
		/// <summary> Creates a new simple directed graph with the specified edge factory.
		/// 
		/// </summary>
		/// <param name="ef">the edge factory of the new graph.
		/// </param>
		public SimpleDirectedGraph(EdgeFactory ef):base(ef, false, false)
		{
		}
Esempio n. 32
0
File: Node.cs Progetto: hseom/brunet
    /**
     * Create a node with a given local address and
     * a set of Routers.
     * @param addr Address for the local node
     * @param realm the Realm or Namespace this node belongs to
     */

    protected Node(Address addr, string realm)
    {
      //Start with the address hashcode:

      _sync = new Object();
      lock(_sync)
      {
        DemuxHandler = new DemuxHandler();
        /*
         * Make all the hashtables : 
         */
        _local_add = AddressParser.Parse( addr.ToMemBlock() );
        _realm = String.Intern(realm);
        
        /* Set up the heartbeat */
        _heart_period = 500; //500 ms, or 1/2 second.
        _heartbeat_handlers = new Dictionary<EventHandler, Brunet.Util.FuzzyEvent>();

        _task_queue = new NodeTaskQueue(this);
        _packet_queue = new BCon.LFBlockingQueue<IAction>();

        _running = 0;
        _send_pings = 1;
        _LOG = ProtocolLog.Monitor.Enabled;

        _connection_table = new ConnectionTable(new DefaultERPolicy(addr));
        _connection_table.ConnectionEvent += this.ConnectionHandler;
        LockMgr = new ConnectionLockManager(_connection_table);

        //We start off offline.
        _con_state = Node.ConnectionState.Offline;
        
        /* Set up the ReqrepManager as a filter */
        _rrm = new ReqrepManager(this.ToString());
        DemuxHandler.GetTypeSource(PType.Protocol.ReqRep).Subscribe(_rrm, null);
        _rrm.Subscribe(this, null);
        this.HeartBeatEvent += _rrm.TimeoutChecker;
        /* Set up RPC */
        _rpc = new RpcManager(_rrm);
        DemuxHandler.GetTypeSource( PType.Protocol.Rpc ).Subscribe(_rpc, null);
        //Add a map-reduce handlers:
        _mr_handler = new MR.MapReduceHandler(this);
        //Subscribe it with the RPC handler:
        _rpc.AddHandler("mapreduce", _mr_handler);

        /*
         * Where there is a change in the Connections, we might have a state
         * change
         */
        _connection_table.ConnectionEvent += this.CheckForStateChange;
        _connection_table.DisconnectionEvent += this.CheckForStateChange;

#if !BRUNET_SIMULATOR
        _codeinjection = new Brunet.Services.CodeInjection(this);
        _codeinjection.LoadLocalModules();
#endif
        /*
         * We must later make sure the EdgeEvent events from
         * any EdgeListeners are connected to _cph.EdgeHandler
         */
        /**
         * Here are the protocols that every edge must support
         */
        /* Here are the transport addresses */
        _remote_ta = ImmutableList<TransportAddress>.Empty;
        /*@throw ArgumentNullException if the list ( new ArrayList()) is null.
         */
        /* EdgeListener's */
        _edgelistener_list = new ArrayList();
        _co_list = new List<ConnectionOverlord>();
        _edge_factory = new EdgeFactory();
        _ta_discovery = ImmutableList<Discovery>.Empty;
        StateChangeEvent += HandleTADiscoveryState;
        
        /* Initialize this at 15 seconds */
        _connection_timeout = new TimeSpan(0,0,0,0,15000);
        //Check the edges from time to time
        IAction cec_act = new HeartBeatAction(this, this.CheckEdgesCallback);
        _check_edges = Brunet.Util.FuzzyTimer.Instance.DoEvery(delegate(DateTime dt) {
          this.EnqueueAction(cec_act);
        }, 5000, 500);
      }
    }
		/// <summary> Creates a new directed graph with the specified edge factory.
		/// 
		/// </summary>
		/// <param name="ef">the edge factory of the new graph.
		/// </param>
		public DefaultDirectedGraph(EdgeFactory ef):base(ef, false, true)
		{
		}
Esempio n. 34
0
    public static void Main(string[] args)
    {
      if (args.Length < 3) {
        Console.WriteLine("Usage: edgetester.exe " +
                          "[client|server] [tcp|udp|function] port " +
                          "localhost|qubit|cantor|starsky|behnam|kupka)");
        return;
      }

      if( args.Length >= 5) {
        delay = Int32.Parse(args[4]);
      }

      EdgeFactory ef = new EdgeFactory();
      int port = System.Int16.Parse(args[2]);

      _threads = ArrayList.Synchronized(new ArrayList());
      EdgeListener el = null;
      if( args[1] == "function" ) {
        //This is a special case, it only works in one thread
        el = new FunctionEdgeListener(port);
        el.EdgeEvent += new EventHandler(HandleEdge);
        //Start listening:
        el.Start();
        ef.AddListener(el);
        el.CreateEdgeTo(
         TransportAddressFactory.CreateInstance("brunet.function://localhost:" + port),
          ClientLoop);
      }
      else if (args[0] == "server") {
        if (args[1] == "tcp") {
          el = new TcpEdgeListener(port);
        }
        else if (args[1] == "udp") {
          el = new UdpEdgeListener(port);
        }
        else {
          el = null;
        }
        el.EdgeEvent += new EventHandler(HandleEdge);
//Start listening:
        el.Start();
        _el = el;
        Console.WriteLine("Press Q to quit");
        Console.ReadLine();
        el.Stop();
      }
      else if (args[0] == "client") {
        TransportAddress ta = null;
        if (args[1] == "tcp") {
          el = new TcpEdgeListener(port + 1);
        }
        else if (args[1] == "udp") {
          el = new UdpEdgeListener(port + 1);
        }
        else {
          el = null;
        }
        ef.AddListener(el);
        _el = el;
        string uri = "brunet." + args[1] + "://" + NameToIP(args[3]) + ":" + port;
        ta = TransportAddressFactory.CreateInstance(uri);
        System.Console.WriteLine("Making edge to {0}\n", ta.ToString());
        el.Start();
        ef.CreateEdgeTo(ta, ClientLoop);
      }
    }