コード例 #1
0
        /// <summary>
        /// 是否存在一个增广路径
        /// </summary>
        /// <param name="G"></param>
        /// <param name="s">st图的起点</param>
        /// <param name="t">汇点</param>
        /// <returns></returns>
        private bool HasAugmentingPath(FlowNetwork G, int s, int t)
        {
            marked = new bool[G.V];
            edgeTo = new FlowEdge[G.V];
            Queue <int> q = new Queue <int>();

            marked[s] = true;
            q.Enqueue(s);
            while (q.Count > 0 && !marked[t])
            {
                int v = q.Dequeue();
                foreach (FlowEdge e in G.GetEdge(v))//类似于 BFS 探测。
                {
                    int w = e.Other(v);
                    if (!marked[w] && e.ResidualCapacityTo(w) > 0) // w点没有访问,同时返回从 v-> w 的剩余流量(容量-当前的流量)
                    {
                        //在剩余网络中,对于任意一条连接到一个未被标记的顶点的边
                        edgeTo[w] = e;
                        marked[w] = true;
                        q.Enqueue(w);
                    }
                }
            }
            return(marked[t]);
        }
コード例 #2
0
        private double Excess(FlowNetwork G, int v)
        {
            double excess = 0.0;

            foreach (FlowEdge e in G.GetEdge(v))
            {
                if (v == e.Src)
                {
                    excess -= e.Flow();
                }
                else
                {
                    excess += e.Flow();
                }
            }
            return(excess);
        }
コード例 #3
0
        /// <summary>
        /// 检查顶点 v 的局部平衡
        /// </summary>
        /// <param name="G"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        private bool LocalEq(FlowNetwork G, int v)
        {
            double netflow = 0.0;//净流量

            foreach (FlowEdge e in G.GetEdge(v))
            {
                if (v == e.Src)
                {
                    netflow -= e.Flow();//流出的流量
                }
                else
                {
                    netflow += e.Flow();//流入的流量
                }
            }
            return(Math.Abs(netflow) < FLOATING_POINT_EPSILON);
        }
コード例 #4
0
 private bool IsFeasible(FlowNetwork G, int s, int t)
 {
     for (int v = 0; v < G.V; v++)
     {
         foreach (FlowEdge e in G.GetEdge(v))
         {
             if (e.Flow() < 0.0 || e.Flow() > e.Capacity) // 必须满足限制
             {
                 //JAVA : System.err.println("Edge does not satisfy capacity constraints: " + e);
                 return(false);
             }
         }
     }
     //检查每个顶点的局部平衡
     for (int v = 0; v < G.V; v++)
     {
         if (v != s && v != t && !LocalEq(G, v))
         {
             return(false);
         }
     }
     return(true);
 }
コード例 #5
0
        public static void Main(String[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("<digraph file>");
                return;
            }
            FlowNetwork   flowNetwork = new FlowNetwork(System.IO.File.OpenText(args[0]));
            int           s = 0, t = flowNetwork.V - 1;
            FordFulkerson maxFlow = new FordFulkerson(flowNetwork, s, t);

            Console.WriteLine("最大流 从{0} 到 {1}", s, t);
            for (int v = 0; v < flowNetwork.V; ++v)
            {
                foreach (FlowEdge edge in flowNetwork.GetEdge(v))
                {
                    if (v == edge.Src && edge.Flow() > 0)
                    {
                        Console.WriteLine("\t" + edge);
                    }
                }
            }
            Console.WriteLine("最大的流:{0}", maxFlow.Value);
        }
コード例 #6
0
 public FordFulkerson(FlowNetwork G, int s, int t)
 {
     if (!IsFeasible(G, s, t))
     {
         Console.WriteLine("网络配置不可行!");
         return;
     }
     Value = 0.0;
     while (HasAugmentingPath(G, s, t))
     {
         //利用所有存在的增广路径,计算瓶颈容量
         double bottle = double.PositiveInfinity;
         for (int v = t; v != s; v = edgeTo[v].Other(v))
         {
             bottle = Math.Min(bottle, edgeTo[v].ResidualCapacityTo(v));
         }
         //增大流量
         for (int v = t; v != s; v = edgeTo[v].Other(v))
         {
             edgeTo[v].AddResidualFlowTo(v, bottle);//这个需要判断是否是逆路径
         }
         Value += bottle;
     }
 }