private void AddReversedEdges([NotNull, ItemNotNull] IEnumerable <TEdge> notReversedEdges) { foreach (TEdge edge in notReversedEdges) { if (ReversedEdges.ContainsKey(edge)) { continue; } // Already been added if (FindReversedEdge(edge, out TEdge reversedEdge)) { ReversedEdges[edge] = reversedEdge; continue; } // Need to create one reversedEdge = EdgeFactory(edge.Target, edge.Source); if (!VisitedGraph.AddEdge(reversedEdge)) { throw new InvalidOperationException("Cannot add the reversed edge, this should not arrive..."); } _augmentedEdges.Add(reversedEdge); ReversedEdges[edge] = reversedEdge; ReversedEdges[reversedEdge] = edge; OnReservedEdgeAdded(reversedEdge); } }
/// <summary> /// Creates and adds an augmented edge between <paramref name="source"/> and <paramref name="target"/>. /// </summary> /// <param name="source">Source vertex.</param> /// <param name="target">Target vertex.</param> protected void AddAugmentedEdge([NotNull] TVertex source, [NotNull] TVertex target) { Debug.Assert(source != null); Debug.Assert(target != null); TEdge edge = EdgeFactory(source, target); _augmentedEdges.Add(edge); VisitedGraph.AddEdge(edge); OnEdgeAdded(edge); }
/// <inheritdoc /> protected override void InternalCompute() { foreach (DataTable table in DataSet.Tables) { VisitedGraph.AddVertex(table); } foreach (DataRelation relation in DataSet.Relations) { VisitedGraph.AddEdge(new DataRelationEdge(relation)); } }
/// <summary> /// Creates and adds an augmented edge between <paramref name="source"/> and <paramref name="target"/>. /// </summary> /// <param name="source">Source vertex.</param> /// <param name="target">Target vertex.</param> protected void AddAugmentedEdge([NotNull] TVertex source, [NotNull] TVertex target) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } TEdge edge = EdgeFactory(source, target); AugmentedEdges.Add(edge); VisitedGraph.AddEdge(edge); OnEdgeAdded(edge); }
private void GenerateFromTransitionFactory( [NotNull] TVertex current, [NotNull] ITransitionFactory <TVertex, TEdge> transitionFactory) { if (current == null) { throw new ArgumentNullException(nameof(current)); } if (transitionFactory is null) { throw new ArgumentNullException(nameof(transitionFactory)); } if (!transitionFactory.IsValid(current)) { return; } foreach (TEdge transition in transitionFactory.Apply(current)) { if (!AddVertexPredicate(transition.Target) || !AddEdgePredicate(transition)) { OnEdgeSkipped(transition); continue; } bool backEdge = VisitedGraph.ContainsVertex(transition.Target); if (!backEdge) { OnVertexDiscovered(transition.Target); } VisitedGraph.AddEdge(transition); if (backEdge) { OnBackEdge(transition); } else { OnTreeEdge(transition); } } }
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 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> /// Runs the graph balancing algorithm. /// </summary> /// <exception cref="InvalidOperationException">If the graph is already balanced.</exception> public void Balance() { if (Balanced) { throw new InvalidOperationException("Graph already balanced."); } // Step 0 // Create new balancing source and sink BalancingSource = VertexFactory(); VisitedGraph.AddVertex(BalancingSource); OnBalancingSourceAdded(); BalancingSink = VertexFactory(); VisitedGraph.AddVertex(BalancingSink); OnBalancingSinkAdded(); // Step 1 // Link balancing source to the flow source BalancingSourceEdge = EdgeFactory(BalancingSource, Source); VisitedGraph.AddEdge(BalancingSourceEdge); Capacities.Add(BalancingSourceEdge, double.MaxValue); _preFlow.Add(BalancingSourceEdge, 0); OnEdgeAdded(BalancingSourceEdge); // Link the flow sink to the balancing sink BalancingSinkEdge = EdgeFactory(Sink, BalancingSink); VisitedGraph.AddEdge(BalancingSinkEdge); Capacities.Add(BalancingSinkEdge, double.MaxValue); _preFlow.Add(BalancingSinkEdge, 0); OnEdgeAdded(BalancingSinkEdge); // Step 2 // For each surplus vertex v, add (source -> v) foreach (TVertex vertex in VisitedGraph.Vertices.Where(v => !IsSourceOrSink(v))) { int balancingIndex = GetBalancingIndex(vertex); if (balancingIndex == 0) { continue; } if (balancingIndex < 0) { // Surplus vertex TEdge edge = EdgeFactory(BalancingSource, vertex); VisitedGraph.AddEdge(edge); _surplusEdges.Add(edge); _surplusVertices.Add(vertex); _preFlow.Add(edge, 0); Capacities.Add(edge, -balancingIndex); OnSurplusVertexAdded(vertex); OnEdgeAdded(edge); } else { // Deficient vertex TEdge edge = EdgeFactory(vertex, BalancingSink); _deficientEdges.Add(edge); _deficientVertices.Add(vertex); _preFlow.Add(edge, 0); Capacities.Add(edge, balancingIndex); OnDeficientVertexAdded(vertex); OnEdgeAdded(edge); } } Balanced = true; #region Local function bool IsSourceOrSink(TVertex v) { return(v.Equals(BalancingSource) || v.Equals(BalancingSink) || v.Equals(Source) || v.Equals(Sink)); } #endregion }