private void Run() { // direct all edges from the red nodes to the blue nodes RedirectedGraph redToBlue = new RedirectedGraph(Graph, x => (IsRed(Graph.U(x)) ? RedirectedGraph.Direction.Forward : RedirectedGraph.Direction.Backward)); // add a source and a target to the graph and some edges Supergraph flowGraph = new Supergraph(redToBlue); Node source = flowGraph.AddNode(); Node target = flowGraph.AddNode(); foreach (var node in Graph.Nodes()) { if (IsRed(node)) { flowGraph.AddArc(source, node, Directedness.Directed); } else { flowGraph.AddArc(node, target, Directedness.Directed); } } Arc reflow = flowGraph.AddArc(target, source, Directedness.Directed); // run the network simplex NetworkSimplex ns = new NetworkSimplex(flowGraph, lowerBound: x => (x == reflow ? MinimumMatchingSize : 0), upperBound: x => (x == reflow ? MaximumMatchingSize : 1), cost: x => (Graph.HasArc(x) ? Cost(x) : 0)); ns.Run(); if (ns.State == SimplexState.Optimal) { var matching = new Matching(Graph); foreach (var arc in ns.UpperBoundArcs.Concat (ns.Forest.Where(kv => kv.Value == 1).Select(kv => kv.Key))) { if (Graph.HasArc(arc)) { matching.Enable(arc, true); } } Matching = matching; } }
/// Reverts the solver to its initial state. public void Clear() { Dictionary <Node, long> excess = new Dictionary <Node, long>(); foreach (var n in Graph.Nodes()) { excess[n] = Supply(n); } Saturated = new HashSet <Arc>(); foreach (var arc in Graph.Arcs()) { long f = LowerBound(arc); long g = UpperBound(arc); if (g < long.MaxValue) { Saturated.Add(arc); } long flow = Flow(arc); excess[Graph.U(arc)] -= flow; excess[Graph.V(arc)] += flow; } Potential = new Dictionary <Node, double>(); MyGraph = new Supergraph(Graph); ArtificialNode = MyGraph.AddNode(); Potential[ArtificialNode] = 0; ArtificialArcs = new HashSet <Arc>(); var artificialArcOf = new Dictionary <Node, Arc>(); foreach (var n in Graph.Nodes()) { long e = excess[n]; Arc arc = e > 0 ? MyGraph.AddArc(n, ArtificialNode, Directedness.Directed) : MyGraph.AddArc(ArtificialNode, n, Directedness.Directed); Potential[n] = (e > 0 ? -1 : 1); ArtificialArcs.Add(arc); artificialArcOf[n] = arc; } Tree = new Dictionary <Arc, long>(); TreeSubgraph = new Subgraph(MyGraph); TreeSubgraph.EnableAllArcs(false); foreach (var kv in artificialArcOf) { Tree[kv.Value] = Math.Abs(excess[kv.Key]); TreeSubgraph.Enable(kv.Value, true); } State = SimplexState.FirstPhase; EnteringArcEnumerator = MyGraph.Arcs().GetEnumerator(); EnteringArcEnumerator.MoveNext(); }
public void Clear() { Dictionary <Node, long> dictionary = new Dictionary <Node, long>(); foreach (Node item in Graph.Nodes()) { dictionary[item] = Supply(item); } Saturated = new HashSet <Arc>(); foreach (Arc item2 in Graph.Arcs(ArcFilter.All)) { LowerBound(item2); long num = UpperBound(item2); if (num < 9223372036854775807L) { Saturated.Add(item2); } long num2 = Flow(item2); Node key; Dictionary <Node, long> dictionary2; (dictionary2 = dictionary)[key = Graph.U(item2)] = dictionary2[key] - num2; Node key2; (dictionary2 = dictionary)[key2 = Graph.V(item2)] = dictionary2[key2] + num2; } Potential = new Dictionary <Node, double>(); MyGraph = new Supergraph(Graph); ArtificialNode = MyGraph.AddNode(); Potential[ArtificialNode] = 0.0; ArtificialArcs = new HashSet <Arc>(); Dictionary <Node, Arc> dictionary3 = new Dictionary <Node, Arc>(); foreach (Node item3 in Graph.Nodes()) { long num3 = dictionary[item3]; Arc arc = (num3 <= 0) ? MyGraph.AddArc(ArtificialNode, item3, Directedness.Directed) : MyGraph.AddArc(item3, ArtificialNode, Directedness.Directed); Potential[item3] = (double)((num3 <= 0) ? 1 : (-1)); ArtificialArcs.Add(arc); dictionary3[item3] = arc; } Tree = new Dictionary <Arc, long>(); TreeSubgraph = new Subgraph(MyGraph); TreeSubgraph.EnableAllArcs(false); foreach (KeyValuePair <Node, Arc> item4 in dictionary3) { Tree[item4.Value] = Math.Abs(dictionary[item4.Key]); TreeSubgraph.Enable(item4.Value, true); } State = SimplexState.FirstPhase; EnteringArcEnumerator = MyGraph.Arcs(ArcFilter.All).GetEnumerator(); EnteringArcEnumerator.MoveNext(); }
private void Run() { RedirectedGraph graph = new RedirectedGraph(Graph, (Arc x) => (!IsRed(Graph.U(x))) ? RedirectedGraph.Direction.Backward : RedirectedGraph.Direction.Forward); Supergraph supergraph = new Supergraph(graph); Node node = supergraph.AddNode(); Node node2 = supergraph.AddNode(); foreach (Node item in Graph.Nodes()) { if (IsRed(item)) { supergraph.AddArc(node, item, Directedness.Directed); } else { supergraph.AddArc(item, node2, Directedness.Directed); } } Arc reflow = supergraph.AddArc(node2, node, Directedness.Directed); NetworkSimplex networkSimplex = new NetworkSimplex(supergraph, (Arc x) => (x == reflow) ? MinimumMatchingSize : 0, (Arc x) => (!(x == reflow)) ? 1 : MaximumMatchingSize, null, (Arc x) => (!Graph.HasArc(x)) ? 0.0 : Cost(x)); networkSimplex.Run(); if (networkSimplex.State == SimplexState.Optimal) { Matching matching = new Matching(Graph); foreach (Arc item2 in networkSimplex.UpperBoundArcs.Concat(from kv in networkSimplex.Forest where kv.Value == 1 select kv.Key)) { if (Graph.HasArc(item2)) { matching.Enable(item2, true); } } Matching = matching; } }
public Preflow(IGraph graph, Func <Arc, double> capacity, Node source, Node target) { Graph = graph; Capacity = capacity; Source = source; Target = target; flow = new Dictionary <Arc, double>(); // calculate bottleneck capacity to get an upper bound for the flow value Dijkstra dijkstra = new Dijkstra(Graph, a => - Capacity(a), DijkstraMode.Maximum); dijkstra.AddSource(Source); dijkstra.RunUntilFixed(Target); double bottleneckCapacity = -dijkstra.GetDistance(Target); if (double.IsPositiveInfinity(bottleneckCapacity)) { // flow value is infinity FlowSize = double.PositiveInfinity; Error = 0; for (Node n = Target, n2 = Node.Invalid; n != Source; n = n2) { Arc arc = dijkstra.GetParentArc(n); flow[arc] = double.PositiveInfinity; n2 = Graph.Other(arc, n); } } else { // flow value is finite if (double.IsNegativeInfinity(bottleneckCapacity)) { bottleneckCapacity = 0; // Target is not accessible } U = Graph.ArcCount() * bottleneckCapacity; // calculate other upper bounds for the flow double USource = 0; foreach (var arc in Graph.Arcs(Source, ArcFilter.Forward)) { if (Graph.Other(arc, Source) != Source) { USource += Capacity(arc); if (USource > U) { break; } } } U = Math.Min(U, USource); double UTarget = 0; foreach (var arc in Graph.Arcs(Target, ArcFilter.Backward)) { if (Graph.Other(arc, Target) != Target) { UTarget += Capacity(arc); if (UTarget > U) { break; } } } U = Math.Min(U, UTarget); Supergraph sg = new Supergraph(Graph); Node newSource = sg.AddNode(); artificialArc = sg.AddArc(newSource, Source, Directedness.Directed); CapacityMultiplier = Utils.LargestPowerOfTwo(long.MaxValue / U); if (CapacityMultiplier == 0) { CapacityMultiplier = 1; } var p = new IntegerPreflow(sg, IntegralCapacity, newSource, Target); FlowSize = p.FlowSize / CapacityMultiplier; Error = Graph.ArcCount() / CapacityMultiplier; foreach (var kv in p.NonzeroArcs) { flow[kv.Key] = kv.Value / CapacityMultiplier; } } }
public Preflow(IGraph graph, Func <Arc, double> capacity, Node source, Node target) { Graph = graph; Capacity = capacity; Source = source; Target = target; flow = new Dictionary <Arc, double>(); Dijkstra dijkstra = new Dijkstra(Graph, (Arc a) => 0.0 - Capacity(a), DijkstraMode.Maximum); dijkstra.AddSource(Source); dijkstra.RunUntilFixed(Target); double num = 0.0 - dijkstra.GetDistance(Target); if (double.IsPositiveInfinity(num)) { FlowSize = double.PositiveInfinity; Error = 0.0; Node node = Target; Node invalid = Node.Invalid; while (node != Source) { Arc parentArc = dijkstra.GetParentArc(node); flow[parentArc] = double.PositiveInfinity; invalid = Graph.Other(parentArc, node); node = invalid; } } else { if (double.IsNegativeInfinity(num)) { num = 0.0; } U = (double)Graph.ArcCount(ArcFilter.All) * num; double num2 = 0.0; foreach (Arc item in Graph.Arcs(Source, ArcFilter.Forward)) { if (Graph.Other(item, Source) != Source) { num2 += Capacity(item); if (num2 > U) { break; } } } U = Math.Min(U, num2); double num3 = 0.0; foreach (Arc item2 in Graph.Arcs(Target, ArcFilter.Backward)) { if (Graph.Other(item2, Target) != Target) { num3 += Capacity(item2); if (num3 > U) { break; } } } U = Math.Min(U, num3); Supergraph supergraph = new Supergraph(Graph); Node node2 = supergraph.AddNode(); artificialArc = supergraph.AddArc(node2, Source, Directedness.Directed); CapacityMultiplier = Utils.LargestPowerOfTwo(9.2233720368547758E+18 / U); if (CapacityMultiplier == 0.0) { CapacityMultiplier = 1.0; } IntegerPreflow integerPreflow = new IntegerPreflow(supergraph, IntegralCapacity, node2, Target); FlowSize = (double)integerPreflow.FlowSize / CapacityMultiplier; Error = (double)Graph.ArcCount(ArcFilter.All) / CapacityMultiplier; foreach (KeyValuePair <Arc, long> nonzeroArc in integerPreflow.NonzeroArcs) { flow[nonzeroArc.Key] = (double)nonzeroArc.Value / CapacityMultiplier; } } }