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); }
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; } } }
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); }
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 }
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); }
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 }
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); }
/// <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)); }
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); } } }
/// <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); }
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)); } } }
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); }
/// <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)); } } }
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)); }
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 }
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; }
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); }
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) { }
/** * 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) { }
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); } }