public Node RunUntilReached(Node target)
 {
     return(CheckTarget(dijkstra.RunUntilFixed(target)));
 }
예제 #2
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;
                }
            }
        }
예제 #3
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;
                }
            }
        }