示例#1
0
        public static float MaximumFlow(FlowNetwork fn, int source, int sink)
        {
            float maxFlow = 0f;

            int sourceIndex = source;
            int sinkIndex   = sink;

            foreach (FlowEdge e in fn.GetEdges())
            {
                e.CurrentFlow = 0f;
            }

            Graph g = CreateResidualNetwork(fn);

            List <Edge> augmentingPath = BreadthFirstSearch(g, sourceIndex, sinkIndex);

            while (augmentingPath != null)
            {
                float minFlow = float.MaxValue;
                //find min flow
                foreach (Edge e in augmentingPath)
                {
                    if (e.Weight < minFlow)
                    {
                        minFlow = e.Weight;
                    }
                }

                maxFlow += minFlow;

                foreach (Edge e in augmentingPath)
                {
                    //Update residual graph
                    Edge  currentForwardResid  = g.FindEdge(e);
                    Edge  currentBackwardResid = g.FindEdge(new Edge(e.GetToVertex(), e.GetFromVertex()));
                    float newForwardWeight     = currentForwardResid.Weight - minFlow;
                    if (newForwardWeight <= 0f)
                    {
                        g.RemoveEdge(currentForwardResid);
                    }
                    else
                    {
                        currentForwardResid.Weight = newForwardWeight;
                    }
                    if (currentBackwardResid != null)
                    {
                        float newBackwardWeight = currentBackwardResid.Weight + minFlow;
                        currentBackwardResid.Weight = newBackwardWeight;
                    }
                    else
                    {
                        currentBackwardResid = new Edge(e.GetToVertex(), e.GetFromVertex(), minFlow);
                        g.AddEdge(currentBackwardResid);
                    }

                    //Update flow network
                    FlowEdge fe = fn.FindEdge(new FlowEdge(e.GetFromVertex(), e.GetToVertex(), 0, 0));
                    fe.CurrentFlow = fe.CurrentFlow + minFlow;
                }

                augmentingPath = BreadthFirstSearch(g, sourceIndex, sinkIndex);
                //augmentingPath = null;
            }

            return(maxFlow);
        }