算法导论 CLRS 第26章 最大流 Maximum flow C#

2021/11/26

第六部分 图算法

第22章 基本的图算法
图数据结构设计
出度、入度和度
有向图
出度≠入度
先初始化出度,再初始化入度,u.入度=u.AdjList.length-u.out_degree.length
无向图
出度=入度
因此使用in_degree同时表示其出度与入度

2021/11/25

重新修改整体框架
1.最大流问题的解释
a.最大流
b.残存网络
c.增广路径
d.最小切割
e.最大流最小切割定理
2.最大流算法
a.基于增广路径的
FoldFulkeson方法
Edmonds Karp 算法
Dinitz/Dinic算法
b.基于推送重贴标签的
前置推送重贴标签算法
3.实现
a.测试数据
b.C#实现
4.应用
a.最大二分匹配

2021/11/08

〇、输入


图的输入以txt表示,格式为

顶点个数
边个数
顶点索引u 顶点索引v 权重
...

所有输入图皆取自于CLRS和数据结构与算法分析(Java语言描述)

1.Inputs G-CLRS Chapter 26

6
9
0 1 16
0 2 13
1 3 12
2 1 4
2 4 14
3 2 9
3 5 20
4 3 7
4 5 4

2.AdjList表示,双引号中的* *为出边,其余边为入边。

0:  *1, 2*
1:  *3,* 0, 2
2:  *1, 4*, 0, 3
3: *2, 5,* 1, 4
4: *3, 5,* 2
53, 4

3.Output : MaximumFlow :23

u   v   f
0   1   12
0   2   11
1   3   12
2   1   0
2   4   11
3   2   0
3   5   19
4   3   7
4   5   4

4.网络流数据结构设计

一、流的定义与理解
对于流网络,将流理解为从源点s发出的所有流的总和
二、流网络与残存网络数据结构
FlowNetwork:
邻接链表表示的有向加权图

ResidualNetwork:
邻接链表表示的无向加权图

在查找增广路径时,记录找到的顶点在对应的邻接链表中的索引:

//v_u_f:在v的邻接链表中查找u对应的流值f
//u_v_c_f:在u的邻接链表中查找v对应的残存容量。
//当(u,v)∈E时,有u_v_f=u_v_c_f,否则有v_u_f=v_u_c_f

只需要查找一次顶点在邻接链表中的索引
在流网络与残存网络中,对于流网络中的出边,在流网络中其索引与之对应,对于入边,则存储在出边之后,因此可以通过对比结点u的邻接链表中v的索引u_v_c_f与结点u的出度,可快速判断残存网络中的边(u,v)是否属于G.E,如果是,则需查找结点v的邻接链表中u的索引,此时应该v的出度至v.c_f.count之间进行查找。反之亦然。如果在构造邻接链表时对出边和入边分别按结点的编号进行排序,则使用二分查找能使结点索引查找更为高效。

2021/11/18
1.将之前设计在ResidualGraph中的out_degree移除,在基类Graph中添加in_degree和out_degree属性和初始化方法;
2.修改WeightedUndirectedGraph中邻接链表的初始化方法,使得先加入出边,在所有出边初始化完成后,再初始化所有入边;
3.修改FlowNetwork的基类为WeightedDirectedGraph,修改ResidualNetwork的基类为WeightedUndirectedGraph,从而使得FlowNetwork中的出边和ResidualNetwork中边形成对应,从而基于out_degree快速判断边(u,v)是否属于FlowNetwork,查找顶点u在顶点v的邻接链表中的索引(c或cf)。
三、Ford-Fulkerson方法

主要是通过在增广路径中增加流来得到最大流,理论依据是最大流-最小切割定理;

四、Edmonds Karp算法
五、Dinitz/Dinic算法

Implement of DA by Cherkassky
/*Input*/
	a flow network G=(V,E,c,s,t)
	a feasible flow f, in G(equal to zero, by defautl)
Initialization:
	compute ∀e∈E:cf(e)-c(e)-f(e)
/*Phase Loop*/
	dowhile
	begin
		compute ∀ v∈V:rank(v)=dist(v,t),by BFS from t on edges with cf>0, in the inverse edge direction
		if rank(s)=then begin f←c-cf;
			return f;
		end
		while DFS from s do
		begin
			/*P denotes the current path and x the current vertex of DFS*/
			any edge(x,y) s.t.cf(x,y)=0 or rank(y)≠rank(x)-1 is skipped;
			if x=t then
			begin
				ε←min{cf(e):e∈P};
				for	edges (v,u) of P,from t downto s do
				begin
					cf(v,u)←cf(v,u);
					cf(u,v)←cf(u,v)if cf(u,v)=0 then x←u;
				end;
			/continue DFS from x*/
		end;
	end;
end;

阻塞流是由至少为一条的跳数相同的最短路径组成,阻塞流的值则由所有最短路径的关键边共同决定
2021/11/18
1.blocking flow
阻塞流vs块流
组成阻塞流的从源点s到汇点t的最短路径集合中的关键边阻塞了该路径上从s往t发送更多的流量。

六、推送-重贴标签算法
2021/11/18
引理 26.20 设G=(V,E)是源结点为s汇点为t的一个流网络,在G上执行算法,GenericPushRelabel过程中的任意时刻,对于所有结点u∈V,u.h≤2|V|-1。
证明略:
证明理解,对于残存网络Gf存在从任意结点u到s的一条简单路径,当该结点为连接t的结点时,此种情况下,在Gf中,cf(u,t)=0,因此需要将结点u上溢出的流沿着从u到s的简单路径推送到源结点s。在流网络为一条从s到t的简单路径时,在算法运行的过程中,需要将流沿着该路径一点逐渐推向t,而当连接t的前一个结点为关键边时,有需要从u将流逐渐推向s。
七、前置重贴标签算法

你可能感兴趣的:(数据结构与算法,Unity,3D与编程语言,算法导论)