中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Ford-Fulkerson 最大流算(suan)法

流網絡(Flow Networks)指的(de)(de)(de)是一(yi)個有向(xiang)圖 G = (V, E),其中每條邊 (u, v) ∈ E 均(jun)(jun)有一(yi)非負容量 c(u, v) ≥ 0。如果 (u, v) ? E 則可以規定(ding) c(u, v) = 0。流網絡中有兩個特殊的(de)(de)(de)頂點(dian):源點(dian) s (source)和(he)匯(hui)點(dian) t(sink)。為方便(bian)起見(jian),假定(ding)每個頂點(dian)均(jun)(jun)處于(yu)從源點(dian)到匯(hui)點(dian)的(de)(de)(de)某條路(lu)(lu)徑上,就是說,對每個頂點(dian) v ∈ E,存在一(yi)條路(lu)(lu)徑 s --> v --> t。因此,圖 G 為連通(tong)圖,且 |E| ≥ |V| - 1。

下圖展(zhan)示了一個流網絡(luo)實例。

設 G = (V, E) 是一(yi)個流網絡,其(qi)容量(liang)函數為(wei) c。設 s 為(wei)網絡的源點,t 為(wei)匯點。G 的流的一(yi)個實值(zhi)函數 f:V×V → R,且(qie)滿足下列(lie)三個性(xing)質(zhi):

  • 容量限制(Capacity Constraint):對所有頂點對 u, v ∈ V,要求 f(u, v) ≤ c(u, v)。
  • 反對稱性(Skew Symmetry):對所有頂點對 u, v ∈ V,要求 f(u, v) = - f(v, u)。
  • 流守恒性(Flow Conservation):對所有頂點對 u ∈ V - {s, t},要求 Σv∈Vf(u, v) = 0。

f(u, v) 稱為從頂點 u 到頂點 v 的流,流的值定義為:|f| =Σv∈Vf(s, v),即從源點 s 出發的總(zong)流。

最大流問題(ti)(Maximum-flow problem)中(zhong),給出源點 s 和匯點 t 的(de)流網(wang)絡 G,希(xi)望找出從(cong) s 到 t 的(de)最大值流。

滿足流網絡(luo)的(de)性質的(de)實際上定義了問題(ti)的(de)限制(zhi):

  • 經過邊的流不能超過邊的容量;
  • 除了源點 s 和匯點 t,對于其它所有頂點,流入量與流出量要相等;

上面的圖中(zhong)描述的流網絡可(ke)簡化為下(xia)圖,其中(zhong)源點 s = 0,匯(hui)點 t = 5。

上圖(tu)(tu)的最(zui)大流為(wei) 23,流向如下圖(tu)(tu)所示。

Ford-Fulkerson 算法是一種(zhong)(zhong)解(jie)決最大流(liu)的方法,其依(yi)賴于三種(zhong)(zhong)重要思(si)想:

  1. 殘留網絡(Residual networks)
  2. 增廣路徑(Augmenting paths)
  3. 割(Cut)

這些思想是最大流(liu)最小割定理的(de)(de)精髓(sui),該定理用流(liu)網絡的(de)(de)割來描(miao)述最大流(liu)的(de)(de)值。

最大流最小割定理

如果 f 是具有源點 s 和匯點 t 的(de)流網絡 G = (V, E) 中的(de)一個流,則下列條件是等價的(de):

  1. f 是 G 的一個最大流。
  2. 殘留網絡 Gf 不包含增廣路徑。
  3. 對 G 的某個割 (S, T),有 |f| = c(S, T)。

Ford-Fulkerson 算法(fa)是(shi)一(yi)(yi)種迭(die)代(dai)方法(fa)。開(kai)始(shi)時,對所有 u, v ∈ V 有 f(u, v) = 0,即初始(shi)狀態時流的值為(wei) 0。在(zai)每次迭(die)代(dai)中,可通過尋找一(yi)(yi)條增廣(guang)路(lu)徑(jing)來增加流值。增廣(guang)路(lu)徑(jing)可以看做是(shi)從源(yuan)點 s 到匯點 t 之間的一(yi)(yi)條路(lu)徑(jing),沿該路(lu)徑(jing)可以壓入(ru)更多(duo)的流,從而增加流的值。反復進行這一(yi)(yi)過程,直至增廣(guang)路(lu)徑(jing)都被找出(chu)為(wei)止。最(zui)大(da)流最(zui)小割定理將(jiang)說明在(zai)算法(fa)終止時,這一(yi)(yi)過程可產生(sheng)出(chu)最(zui)大(da)流。

1 FORD-FULKERSON-METHOD(G, s, t)
2   initialize flow f to 0
3   while there exists an augmenting path p
4     do augment flow f along p
5   return f

上述偽碼實現的時間復雜度為 O(max_flow * E)。

C# 代碼(ma)實現如下(xia):

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 
  5 namespace GraphAlgorithmTesting
  6 {
  7   class Program
  8   {
  9     static void Main(string[] args)
 10     {
 11       Graph g = new Graph(6);
 12       g.AddEdge(0, 1, 16);
 13       g.AddEdge(0, 2, 13);
 14       g.AddEdge(1, 2, 10);
 15       g.AddEdge(1, 3, 12);
 16       g.AddEdge(2, 1, 4);
 17       g.AddEdge(2, 4, 14);
 18       g.AddEdge(3, 2, 9);
 19       g.AddEdge(3, 5, 20);
 20       g.AddEdge(4, 3, 7);
 21       g.AddEdge(4, 5, 4);
 22 
 23       Console.WriteLine();
 24       Console.WriteLine("Graph Vertex Count : {0}", g.VertexCount);
 25       Console.WriteLine("Graph Edge Count : {0}", g.EdgeCount);
 26       Console.WriteLine();
 27 
 28       int maxFlow = g.FordFulkerson(0, 5);
 29       Console.WriteLine("The Max Flow is : {0}", maxFlow);
 30 
 31       Console.ReadKey();
 32     }
 33 
 34     class Edge
 35     {
 36       public Edge(int begin, int end, int weight)
 37       {
 38         this.Begin = begin;
 39         this.End = end;
 40         this.Weight = weight;
 41       }
 42 
 43       public int Begin { get; private set; }
 44       public int End { get; private set; }
 45       public int Weight { get; private set; }
 46 
 47       public override string ToString()
 48       {
 49         return string.Format(
 50           "Begin[{0}], End[{1}], Weight[{2}]",
 51           Begin, End, Weight);
 52       }
 53     }
 54 
 55     class Graph
 56     {
 57       private Dictionary<int, List<Edge>> _adjacentEdges
 58         = new Dictionary<int, List<Edge>>();
 59 
 60       public Graph(int vertexCount)
 61       {
 62         this.VertexCount = vertexCount;
 63       }
 64 
 65       public int VertexCount { get; private set; }
 66 
 67       public IEnumerable<int> Vertices
 68       {
 69         get
 70         {
 71           return _adjacentEdges.Keys;
 72         }
 73       }
 74 
 75       public IEnumerable<Edge> Edges
 76       {
 77         get
 78         {
 79           return _adjacentEdges.Values.SelectMany(e => e);
 80         }
 81       }
 82 
 83       public int EdgeCount
 84       {
 85         get
 86         {
 87           return this.Edges.Count();
 88         }
 89       }
 90 
 91       public void AddEdge(int begin, int end, int weight)
 92       {
 93         if (!_adjacentEdges.ContainsKey(begin))
 94         {
 95           var edges = new List<Edge>();
 96           _adjacentEdges.Add(begin, edges);
 97         }
 98 
 99         _adjacentEdges[begin].Add(new Edge(begin, end, weight));
100       }
101 
102       public int FordFulkerson(int s, int t)
103       {
104         int u, v;
105 
106         // Create a residual graph and fill the residual graph with
107         // given capacities in the original graph as residual capacities
108         // in residual graph
109         int[,] residual = new int[VertexCount, VertexCount];
110 
111         // Residual graph where rGraph[i,j] indicates 
112         // residual capacity of edge from i to j (if there
113         // is an edge. If rGraph[i,j] is 0, then there is not) 
114         for (u = 0; u < VertexCount; u++)
115           for (v = 0; v < VertexCount; v++)
116             residual[u, v] = 0;
117         foreach (var edge in this.Edges)
118         {
119           residual[edge.Begin, edge.End] = edge.Weight;
120         }
121 
122         // This array is filled by BFS and to store path
123         int[] parent = new int[VertexCount];
124 
125         // There is no flow initially
126         int maxFlow = 0;
127 
128         // Augment the flow while there is path from source to sink
129         while (BFS(residual, s, t, parent))
130         {
131           // Find minimum residual capacity of the edhes along the
132           // path filled by BFS. Or we can say find the maximum flow
133           // through the path found.
134           int pathFlow = int.MaxValue;
135           for (v = t; v != s; v = parent[v])
136           {
137             u = parent[v];
138             pathFlow = pathFlow < residual[u, v]
139               ? pathFlow : residual[u, v];
140           }
141 
142           // update residual capacities of the edges and reverse edges
143           // along the path
144           for (v = t; v != s; v = parent[v])
145           {
146             u = parent[v];
147             residual[u, v] -= pathFlow;
148             residual[v, u] += pathFlow;
149           }
150 
151           // Add path flow to overall flow
152           maxFlow += pathFlow;
153         }
154 
155         // Return the overall flow
156         return maxFlow;
157       }
158 
159       // Returns true if there is a path from source 's' to sink 't' in
160       // residual graph. Also fills parent[] to store the path.
161       private bool BFS(int[,] residual, int s, int t, int[] parent)
162       {
163         bool[] visited = new bool[VertexCount];
164         for (int i = 0; i < visited.Length; i++)
165         {
166           visited[i] = false;
167         }
168 
169         Queue<int> q = new Queue<int>();
170 
171         visited[s] = true;
172         q.Enqueue(s);
173         parent[s] = -1;
174 
175         // standard BFS loop
176         while (q.Count > 0)
177         {
178           int u = q.Dequeue();
179 
180           for (int v = 0; v < VertexCount; v++)
181           {
182             if (!visited[v]
183               && residual[u, v] > 0)
184             {
185               q.Enqueue(v);
186               visited[v] = true;
187               parent[v] = u;
188             }
189           }
190         }
191 
192         // If we reached sink in BFS starting from source, 
193         // then return true, else false
194         return visited[t] == true;
195       }
196     }
197   }
198 }

運行結果如下:

參考資料

本篇文章《Ford-Fulkerson 最大流算法》由 Dennis Gao 發表自博客園,未經作者本人同意禁止任何形式的轉載,任何自動或人為的爬蟲轉載行為均為耍流氓。

posted @ 2015-02-06 03:32  sangmado  閱讀(47127)  評論(7)    收藏  舉報