private void OnVertexDiscovered([NotNull] TVertex vertex) { Debug.Assert(vertex != null); VisitedGraph.AddVertex(vertex); _unExploredVertices.Enqueue(vertex); DiscoverVertex?.Invoke(vertex); }
/// <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)); } }
/// <inheritdoc /> protected override void InternalCompute() { if (Augmented) { throw new InvalidOperationException("Graph already augmented."); } SuperSource = VertexFactory(); VisitedGraph.AddVertex(SuperSource); OnSuperSourceAdded(SuperSource); SuperSink = VertexFactory(); VisitedGraph.AddVertex(SuperSink); OnSuperSinkAdded(SuperSink); AugmentGraph(); Augmented = true; }
/// <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 }