예제 #1
0
        public static Graph CreateResidualNetwork(FlowNetwork fn)
        {
            FlowNetwork copy = new FlowNetwork();

            fn.CopyTo(copy);

            Graph g = new Graph();

            g.Directed = true;

            for (int i = 0; i < copy.GetVertices().Count; i++)
            {
                Vertex v = copy.GetVertices()[i];
                v.Tag = i;
                v.RemoveAllEdges();
                g.AddVertex(v);
            }

            foreach (FlowEdge e in copy.GetEdges())
            {
                float backflow    = e.CurrentFlow;
                float capacity    = e.Capacity;
                float forwardFlow = capacity - backflow;

                Vertex fromVertex = e.GetFromVertex();
                Vertex toVertex   = e.GetToVertex();
                int    fromIndex  = (int)fromVertex.Tag;
                int    toindex    = (int)toVertex.Tag;

                Vertex newTo   = g.GetVertices()[toindex];
                Vertex newFrom = g.GetVertices()[fromIndex];

                if (backflow > 0)
                {
                    Edge backEdge = new Edge(newTo, newFrom, backflow);
                    g.AddEdge(backEdge);
                }

                if (forwardFlow > 0)
                {
                    Edge forwardEdge = new Edge(newFrom, newTo, forwardFlow);
                    g.AddEdge(forwardEdge);
                }
            }

            return(g);
        }
예제 #2
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;
        }
예제 #3
0
        public static Graph CreateResidualNetwork(FlowNetwork fn)
        {
            FlowNetwork copy = new FlowNetwork();
            fn.CopyTo(copy);

            Graph g = new Graph();

            g.Directed = true;

            for (int i = 0; i < copy.GetVertices().Count; i++)
            {
                Vertex v = copy.GetVertices()[i];
                v.Tag = i;
                v.RemoveAllEdges();
                g.AddVertex(v);
            }

            foreach (FlowEdge e in copy.GetEdges())
            {
                float backflow = e.CurrentFlow;
                float capacity = e.Capacity;
                float forwardFlow = capacity - backflow;

                Vertex fromVertex = e.GetFromVertex();
                Vertex toVertex = e.GetToVertex();
                int fromIndex = (int)fromVertex.Tag;
                int toindex = (int)toVertex.Tag;

                Vertex newTo = g.GetVertices()[toindex];
                Vertex newFrom = g.GetVertices()[fromIndex];

                if (backflow > 0)
                {
                    Edge backEdge = new Edge(newTo, newFrom, backflow);
                    g.AddEdge(backEdge);
                }

                if (forwardFlow > 0)
                {
                    Edge forwardEdge = new Edge(newFrom, newTo, forwardFlow);
                    g.AddEdge(forwardEdge);
                }
            }

            return g;
        }
예제 #4
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);
        }