public int GreedyGrow(int maxImprovements = int.MaxValue) { int num = 0; List <Node> list = new List <Node>(); foreach (Node unmatchedRedNode in unmatchedRedNodes) { foreach (Arc item in Graph.Arcs(unmatchedRedNode, ArcFilter.All)) { Node node = Graph.Other(item, unmatchedRedNode); if (matching.HasNode(node)) { continue; } matching.Enable(item, true); list.Add(unmatchedRedNode); num++; if (num < maxImprovements) { break; } goto IL_00ce; } } goto IL_00ce; IL_00ce: foreach (Node item2 in list) { unmatchedRedNodes.Remove(item2); } return(num); }
/// Grows the current matching greedily. /// Can be used to speed up optimization by finding a reasonable initial matching. /// \param maxImprovements The maximum number of arcs to grow the current matching with. /// \return The number of arcs added to the matching. public int GreedyGrow(int maxImprovements = int.MaxValue) { int result = 0; List <Node> matchedRedNodes = new List <Node>(); foreach (var x in unmatchedRedNodes) { foreach (var arc in Graph.Arcs(x)) { Node y = Graph.Other(arc, x); if (!matching.HasNode(y)) { matching.Enable(arc, true); matchedRedNodes.Add(x); result++; if (result >= maxImprovements) { goto BreakAll; } break; } } } BreakAll: foreach (var n in matchedRedNodes) { unmatchedRedNodes.Remove(n); } return(result); }
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; } }
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; } }