예제 #1
0
        /// 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();
        }
예제 #2
0
        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()
        {
            // 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;
            }
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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;
                }
            }
        }
예제 #6
0
        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;
                }
            }
        }