图与网络分析
图的基本概念与模型
P.S. 只列一些陌生概念(为什么图的概念会有这么多版本😅无语住了)
- 次:与某一个点 vi 相关联的边的数目称为点 vi 的次(degree),也叫做 度,记作 d(vi)
- 部分图:G1={V1,E1},G2={V2,E2},若有 V1=V2,E1⊑E2,则称 G1 是 G2 的部分图。注意:部分图也是子图,子图不一定是部分图。(子图:V1⊑V2,E1⊑E2)
- 链、路:图中存在点和边交替序列 μ={v0,e1,v1,⋯,ek,vk},若其中各边 e1,e2,⋯ek 各不相同,且对任意的 1≤t≤k 有,vt−1 和 vt 相邻,则称 μ 为 链。如果链中所有顶点 v0,v1,⋯vk 也互不相同,则称这样的链为 路。
树和图的最小部分树
最小部分树就是最小生成树
树的性质
- 任何树中必定存在度为 1 的点
- 具有 n 个顶点的树的边树恰好等于 (n−1)
- 任何具有 n 个点、(n-1) 条边的连通图是树
以上性质说明:
- 树是无圈连通图中边数最多,即在树上只要任意再加上一条边就一定会出现圈。
- 由于树是无圈的连通图,即图的任意两个点之间有且仅有一条唯一通路。因此树也是最脆弱的连通图,只要从树中取走任意一条边,图就不连通了。因此一些重要的网络不能按照树的结构设计。
图的最小部分树
定义:
如果 G1 是 G2 的部分图,同时又是树,则称 G1 是 G2 的部分树。在所有部分树中树枝总长度最小的部分树,称为该图的最小部分树(也称为最小支撑树)。
定理:
图中任意一点 i,若 j 是与 i 相邻点中距离最近的,则边 [i,j] 一定> 含在该图的最小部分树内。
避圈法和破圈法
两种方法寻找图的最小部分树
避圈法:
- 从图中任选一点 vi,使得 vi∈V,图中其余点均包含在 V 中
- 从 V、V 的连线中找出最小边,这条边一定包含在最小部分树内。不妨设最小边为 [vi,vj],将其加粗,用以标记该边是最小部分树内的边。
- 令 V∪vi⟹V,V\vi⟹V
- 重复 2、3 两步,直至图中所有点均包含在 V 中为止。
破圈法:
- 从网络图 N 中任意取一条回路
- 去掉这个回路中权数最大的一条边,得到一个子网络 N1.
- 在 N1 中再任取一回路,再去掉回路中权数最大的一条边,得到 N2
- 如此继续下去,一直到剩下的子图中不再含回路为止。得到的子图就是 N 的最小部分树。
最短路问题
Dijkstra 算法(求指定两点之间最短距离)
用 dij 表示图中两相邻点 i 与 j 的距离,若 i 与 j 不相邻,令 dij=∞,显然 dii=0,若用 Lsi 表示从 s 点到 i 点的最短距离,现要求从 s 点到某一点 t 的最短距离,用 Dijkstra 算法步骤如下:
- 从点 s 出发,因为 Lss=0,将此值标注在 s 旁的小方框内,表示 s 点已标号;
- 从 s 点出发,找出与 s 相邻的点中距离最小的一个,设为 r,将 Lsr=Lss+dsr 的值标注在 r 旁的小方框内,表明点 r 也已经标号;
- 从已标号的点出发,找出与这些点相邻的所有未标号的点 p,若有 Lsp=min(Lss+dsp;Lsr+drp),则对 p 点标号,并将 Lsp 的值标注在 p 点旁的小方框内;
- 重复前三步骤,一直到 t 点得到标号为止
Floyd 算法(求任意两点之间的最短距离)
要点:以每一个顶点为中转站,刷新所有入度和出度的距离
因此需要:遍历每一个点顶点 --> 遍历每一个顶点的入度 --> 遍历每一个顶点的出度,以这个点为中转站,距离更短就刷新距离
核心代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| for (int i = 0; i < graph.length; i++) { for (int j = 0; j < graph.length; j++) { for (int k = 0; k < graph[j].length; k++) { if (graph[j][i] != -1 && graph[i][k] != -1) { int newDistance = graph[j][i] + graph[i][k]; if (newDistance < graph[j][k] || graph[j][k] == -1) { graph[j][k] = newDistance; path[j][k] = i; } } } } }
|
网络的最大流
相关概念
有向图与容量网络
研究流量问题时候常常在有向图中进行。有向图上的有规定指向的连线称作 弧。弧的代号是 (vi,vj), 有向图是点与弧的集合,记作 D(V,A)。
容量网络是指每条弧 (vi,vj) 都给出一个最大的通过能力,称为该弧的容量,记为 c(vi,vj) 或简写成 cij。容量网路中规定一个发点(也称为源点,记作 s)和一个收点(也称汇点,记作 t),其他点称为中间点。
网络的最大流是指网络中从发点到收点之间允许通过的最大流量
流与可行流
所谓流是指加在网络上各条弧上的一组负载量。对加在弧 (vi,vj) 上的负载量记作 f(vi,vj) 或简写成 fij。若网络上所有的 fij=0,这个流成为零流。
称在容量网络上满足条件 (1.1)、(1.2) 的一组流为可行流
- 容量限制条件,对所有弧有
0≤f(vi,vj)≤c(vi,vj)(1. 1)
- 中间点平衡条件
∑f(vi,vj)−∑f(vj,vi)=0(i=s,t)(1. 2)
若以 v(f) 表示网络中 s→t 的流量,则有
v(f)=j∑f(vs,vj)+j∑f(vj,vt)(1. 3)
任何网络一定存在可行流,因零流是可行流。求网络最大流是指,满足容量限制条件和中间点平衡条件下,使 f(v) 值达到最大。
割和流量
割是指将容量网络中的发点和收点分割开,并使 s→t 的流中断的一组弧的集合,
最大流最小割定理
增广链
如果在网络的发点和收点之间能找出一条链,在这条链上所有指向为 s→t 的弧(称 前向弧,记作 μ+),存在 f<c;所有指向为 t→s 的弧(称 后向弧,记作 μ−),存在 f>0,这样的链称 增广链。
当有增广链存在时找出
θ=min{(ci−fi),对μ+fi , 对μ−(θ>0)
再令
f′=⎩⎨⎧fi+θ,对所有μ+fi−θ,对所有μ−fi , 对非增广链上的弧
显然 f′ 仍是一个可行流,但较之原来的可行流 f,这时网络中从 s→t 的流量增大了一个 θ,因此 只有当网络图中找不到增广链时,s→t 的流才不可能进一步增大。
定理:
在网络中 s→t 的最大流量等于它的最小割集的容量,即
v∗(f)=c∗(V,V)
求网络最大流的标号算法
又称 Ford−Fulkerson 标号算法
算法实质是判断是否有增广链存在 并设法吧增广链找出来
标号算法步骤:
- 首先给发点 s 标号 (0,ε(s))。括弧中第一个数字是使这个点得到标号的前一个点的标号,因 s 是发点,故记作 0;第二个数字 ε(s) 表示从上一个标号点到这个标号点的流量最大允许调整值,s 为发点,不限允许调整量,故 ε(s)=∞。
- 列出与已标号点相邻的所有未标号点:
- 考虑从标号点 i 出发的弧 (i,j),如果有 fij=cij,不给点 j 标号;若有 fij<cij,则对点 j 标号,记为 (i,ε(j)),括弧中 i 表示点 j 的标号是从点 i 延伸过来的,ε(j)=min{ε(i),(cij−fij)};
- 考虑所有指向标号点 i 的弧 (h,i),如果有 fhi=0,对 h 点不标号;若有 fhi>0,则对点 h 标号,记为 (h,ε(h)),其中,ε(h)=min{ε(h),fhi};
- 如果某为标号点 k 有两个以上相邻的标号点,为了减少迭代次数,可按前两步中所述规则分别计算出 ε(k) 的值,并取其中最大的一个标记。
- 重复第2步,可能出现以下两种结局:
- 标号过程中断,t 得不到标号,说明该网络中不存在增广链,给定的流量即为最大流。记已标号点的集合为 V,未标号点集合为 V,(V,V),为网络的最小割;
- t 得到标号,这时可用反向追踪法在网络中找出一条从 s→t 的由标号点及相应的弧连接而成的增广链。
- 修改流量,设图中原有可行流为 f,令
f′=⎩⎨⎧f+ε(t),对增广链上所有前向弧f−ε(t),对增广链上所有后向弧f , 对所有非增广链上的弧
这样又得到网络上的一个新的可行流 f′.
- 抹掉图上所有标号,重复一至四步,直至图中找不到任何增广链,即出现第三步的第一个结局为止,这是网络图中的流量即为最大流。
最小费用流
最小费用流问题描述:
设网络有 n 个点,fij 为弧 (i,j) 上的流量,cij 为该弧的容量,bij 为在弧 (i,j) 上通过单位流量时的费用,si 代表第 i 点的可供量或需求量,当 i 为发点时,si>0,i 为收点时,si<0,i 为中转点时,si=0。当网络供需平衡,即 i∑si=0 时,将各发点物资调运到各收点(或从各发点按最大流量调运到各收点),使总掉运费用最小的问题,可归结为如下线性规划模型:
min z=i=1∑nj=1∑nbijfijs.t.⎩⎨⎧j=1∑nfij−k=1∑nfki=si(i=1,⋯,n)0≤fij≤cij(对弧(i,j))
最小费用流问题解题步:
- 从零流 f0 开始。f0 是可行流,也是相应的流量为零时费用最小的
- 对可行流 fk 构造加权网络 W(fk),方法是:
- 对 0<fij<cij 的弧 (i,j),当其为正向弧时,通过单位流的费用为 bij,当其为反向弧时,相应费用 bji=−bij。故在 i 和 j 点之间分别给出弧 (i,j) 和 (j,i) ,其权数分别为 bij 和 −bij。
- 对 fij=cij 的弧 (i,j),因为该弧流量已饱和,在增广链中只能作为反向弧。故在 W(jk) 中只画出弧 (j,i),其权数值为 −bij。
- 对 fij=0 的弧 (i,j),在增广链中只能为正向弧,故在 W(jk) 中只画出弧 (i,j),其权数值为 bij。
- 在加权网络 W(fk) 中,寻找费用最小的增广链,也即求从 s→t 的最短路,并将该增广链上流量调整至允许的最大值,得到一个新的流量 fk+1(>fk)。
- 重复第二、三两步,直至网络 W(fk+m) 中找不到增广链(也即找不出最短路)时,fk+ 即为要寻找的最小费用流。