예제 #1
0
        // Returns a negative cycle on the graph, if it exists.
        // Judicious choice of this cycle is the main way to get asymptotic speed-up.
        // Current implementation: Application of Bellman-Ford shortest path algorithm.
        public static Tuple <List <Edge>, long> FindNegativeCycle(CirculationGraph graph)
        {
            // First reset the metadata associated with this algorithm.

            foreach (Node n in graph.Nodes)
            {
                n.MetaData = new NodeMetaData();
            }
            // Decide which edges should even be considered for increasing flow by those with positive Free space.

            List <Edge> viableEdges = new List <Edge>();

            foreach (Edge e in graph.Edges)
            {
                if (e.Free > 0)
                {
                    viableEdges.Add(e);
                }
            }

            // Iterate Bellman-Ford n-1 times.
            for (int i = 0; i < graph.Nodes.Count - 1; i++)
            {
                foreach (Edge e in viableEdges)
                {
                    if (e.Target.MetaData.Distance > e.Source.MetaData.Distance + e.Cost)
                    {
                        e.Target.MetaData.Distance = e.Source.MetaData.Distance + e.Cost;
                        e.Target.MetaData.PredEdge = e;
                    }
                }
            }
            // Iterate over all edges one last time to find negative cycles.

            foreach (Edge e in viableEdges)
            {
                if (e.Target.MetaData.Distance > e.Source.MetaData.Distance + e.Cost)
                {
                    return(FindBellmanFordCycle(e.Source));
                }
            }
            // Return a null cycle if no negative cycles are found; signals that there are no more negative cycles.

            return(Tuple.Create <List <Edge>, long>(null, 0));
        }
예제 #2
0
        // Changes graph state into a minimum-cost circulation, if it exists.
        public static void FindMinCostCirculation(CirculationGraph graph, int smoothingIterations = -1)
        {
            int numIterations = 0;

            // Represent a cycle as a tuple of the edges on the cycle and the minimum free capacity.
            Tuple <List <Edge>, long> cycle = FindNegativeCycle(graph);

            while (cycle.Item1 != null && numIterations != smoothingIterations)
            {
                // Force flow equal to the minimum free capacity through all the edges on the negative cycle.
                foreach (Edge e in cycle.Item1)
                {
                    e.AddFlow(cycle.Item2);
                }

                // Ensure that our new flow does not violate any flow conditions.
                graph.CheckConsistentCirculation();
                cycle = FindNegativeCycle(graph);
                numIterations++;
            }
        }