【图论】网络流——最大流和最小费用流

这篇具有很好参考价值的文章主要介绍了【图论】网络流——最大流和最小费用流。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【图论】网络流——最大流和最小费用流

1. 最大流问题

主要解决系统中的流量问题:如公路系统中的车辆流、物资调配系统中的物资流、金融系统中的现金流等。

这些问题都可以归结为网络流问题,如何安排使流量最大即最大流问题


什么是最大流?

如左图能输送两份的水,是最大流;右图只能输送一份的水,不是最大流

【图论】网络流——最大流和最小费用流

1.1 基本概念

网络:图 D = ( V , A , C ) D=(V,A,C) D=(V,A,C)

  • V V V :点集。其中 v s v_s vs 为发点,只有发出的弧; v t v_t vt 为收点,该点只有进入的弧;其余的点为中间点;
  • A A A: 弧集。对于每一条弧 ( v i , v j ) ∈ A (v_i,v_j)\in A (vi,vj)A
  • C C C:容量集。每一条弧的容量 c ( v i , v j ) > = 0 c(v_i,v_j)>=0 c(vi,vj)>=0(或简记为 c i j c_{ij} cij),其中 C = { c i j } C=\{c_{ij}\} C={cij}
  • f = { f i j } = { f ( v i , v j ) } f=\{f_{ij}\}=\{f(v_i,v_j)\} f={fij}={f(vi,vj)}:弧 ( v i , v j ) (v_i,v_j) (vi,vj)上的流量

可行流:

(1) 容量限制条件: 0 ≤ f i j ≤ c i j 0\leq f_{ij} \leq c_{ij} 0fijcij

(2) 平衡条件:

  • 中间点:流出量 = 流入量   ∑ j : ( v i , v j ) ∈ A f i j − ∑ k : ( v k , v i ) ∈ A f k i = 0 ; \sum_{j:\left(v_{i}, v_{j}\right) \in A} f_{i j}-\sum_{k:\left(v_{k}, v_{i}\right) \in A} f_{k i}=0 ; j:(vi,vj)Afijk:(vk,vi)Afki=0;
  • 发点: ∑ j : ( v s , v j ) ∈ A f s j = v \sum_{j:\left(v_{s}, v_{j}\right) \in A} f_{s j}=v j:(vs,vj)Afsj=v
  • 收点: ∑ k : ( v k , v t ) ∈ A f k t = v \sum_{k_{:}\left(v_{k}, v_{t}\right) \in A} f_{k t}=v k:(vk,vt)Afkt=v

式中:v称为这个可行流的流量,即发点的净输出量。


最大流问题可以写为如下的线性规划模型:

max ⁡ v ,  s. t.  { ∑ j : ( v s , v j ) ∈ A f s j = v , ∑ j : ( v i , v j ) ∈ A f i j − ∑ k : ( v k , v i ) ∈ A f k i = 0 , i ≠ s , t , ∑ k : ( v k , v t ) ∈ A f k t = v , 0 ⩽ f i j ⩽ c i j , ∀ ( v i , v j ) ∈ A . \begin{array}{l} \max v, \\ \text { s. t. }\left\{\begin{array}{ll} \sum_{j:\left(v_{s}, v_{j}\right) \in A} f_{s j}=v, \\ \sum_{j:\left.(v_i, v_{j}\right)\in A} f_{i j}-\sum_{k:\left(v_{k}, v_{i}\right) \in A} f_{k i}=0, & i \neq s, t, \\ \sum_{k:\left(v_{k}, v_{t}\right) \in A} f_{k t}=v, & \\ 0 \leqslant f_{i j} \leqslant c_{i j}, & \forall\left(v_{i}, v_{j}\right) \in A . \end{array}\right. \end{array} maxv, s. t.  j:(vs,vj)Afsj=v,j:(vi,vj)Afijk:(vk,vi)Afki=0,k:(vk,vt)Afkt=v,0fijcij,i=s,t,(vi,vj)A.



1.2 寻求最大流的算法(Ford-Fulerson)

步骤:

  1. 建立残差图, 将残差图的容量初始化

  2. 当增广路径可以被找到时一直循环以下步骤:

    a. 在残差图上一直寻找增广路径
    b. 在增广路径上找到容量最小值 x x x
    c. 更新残差图上的容量: 增广路径上的容量 = 增广路径上的容量 − x 增广路径上的容量 =增广路径上的容量 - x 增广路径上的容量=增广路径上的容量x
    d. 添加反向路径。(沿着增广路径的反方向,所有边的权重为x。)

示例:

  1. 初始化: 左图为原图,右图为构建的与原图一致的残差图。

【图论】网络流——最大流和最小费用流


  1. 第一轮循环:

① 找到如图红线的增广路径

② 可以看到整条路上容量的最大值为3,因此将路径上所有边的容量减去3

③ 去除容量为0的边,并添加值为3的反向路径
【图论】网络流——最大流和最小费用流


  1. 第二轮循环

① 找到如图红线的增广路径

② 可以看到整条路上容量的最大值为1,因此将路径上所有边的容量减去1

③ 去除容量为0的边,并添加值为1的反向路径

【图论】网络流——最大流和最小费用流

④ 合并反向路径的容量值

【图论】网络流——最大流和最小费用流

  1. 第三轮循环

① 找到如图的增广路径 (注意:这里就体现了增加的反向边的重要性了,如果没有反向边,是找不到从起点到终点的增广路径的

② 可以看到整条路上容量的最大值为1,因此将路径上所有边的容量减去1

③ 去除容量为0的边,并添加值为1的反向路径

【图论】网络流——最大流和最小费用流

④ 合并反向路径的容量值

【图论】网络流——最大流和最小费用流

  1. 第四轮循环

发现没有水流流入 v 3 v_3 v3,因此没有水流从起点到终点,循环终止。

【图论】网络流——最大流和最小费用流

  1. 计算容量

最大流 = 3 + 1 + 1 = 5 最大流=3+1+1=5 最大流=3+1+1=5

代码

import copy
from collections import deque


def hasPath(Gf, s, t, path):
    # BFS algorithm
    V = len(Gf)
    visited = list(range(V))
    for i in range(V):
        visited[i] = False
    visited[s] = True
    queue = deque([s])	# 起点入队
    while queue:
        temp = queue.popleft()	# 队头元素
        if temp == t:	# 如果到达了终点
            return True
        for i in range(V):	# 遍历队头元素的每个邻点
        	# 如果零点没有被访问且流量为正向
            if not visited[i] and (Gf[temp][i] > 0):
                queue.append(i)
                visited[i] = True
                path[i] = temp   # 节点i的父节点为temp
    return visited[t]


def max_flow(graph, s, t):
    maxFlow = 0
    Gf = copy.deepcopy(graph)
    V = len(Gf)
    path = list(range(V))
    # 只要有增广路径就一直循环
    while hasPath(Gf, s, t, path):
        min_flow = float('inf')

        # 不断利用道路上的父节点回溯,找到增广路径上的容量最小值
        v = t
        while v != s:	
            u = path[v]
            min_flow = min(min_flow, Gf[u][v])
            v = path[v]
        print(min_flow)

        # 增广路径上的容量减去最小值,并添加反向路径
        v = t
        while v != s:
            u = path[v]
            Gf[u][v] -= min_flow
            Gf[v][u] += min_flow
            v = path[v]

        maxFlow += min_flow
    return maxFlow

M=0
capacity = [
[0,16,13,M,M,M],
[M,0,10,12,M,M],
[M,4,0,M,14,M],
[M,M,9,0,M,20],
[M,M,M,7,0,4],
[M,M,M,M,M,0]
]

flow = max_flow(capacity, 0, 5)
print("flow =", flow)

1.3 matlab求最大流

如图求①到⑧的最大流
【图论】网络流——最大流和最小费用流

a=zeros(8);a(1,[2:4])=[6,4,5];
a(2,[3,5,6])=[3,9,9];
a(3,[4:7])=[5,6,7,3];
a(4,[3,7])=[2,5];
a(5,8)=12;
a(6,[5,8])=[8,10];
a(7,[6,8])=[4,15];
G=digraph(a);
H=plot(G,'EdgeLabel',G.Edges.Weight);
[M,F]=maxflow(G,1,8);
F.Edges,highlight(H,F);

【图论】网络流——最大流和最小费用流


2. 最小流问题

2.1 基本概念

在许多实际问题中,往往还要考虑网络流上的费用问题。例如在运输问题中,人们总是希望在完成运输任务时,寻求一个运输费用最小的方案。

最小流问题可以写为如下的线性规划模型:

b i j b_{ij} bij为弧 ( v i , v j ) (v_i,v_j) (vi,vj)上的单位费用

min ⁡ ∑ j : ( v i , v j ) ∈ A f i j b i j  s. t.  { ∑ j : ( v s , v j ) ∈ A f s j = v , ∑ j : ( v i , v j ) ∈ A f i j − ∑ k : ( v k , v i ) ∈ A f k i = 0 , i ≠ s , t , ∑ k : ( v k , v t ) ∈ A f k t = v , 0 ⩽ f i j ⩽ c i j , ∀ ( v i , v j ) ∈ A . \begin{array}{l} \min \sum_{j:\left(v_{i}, v_{j}\right) \in A} f_{i j}b_{ij} \\ \text { s. t. }\left\{\begin{array}{ll} \sum_{j:\left(v_{s}, v_{j}\right) \in A} f_{s j}=v, \\ \sum_{j:\left.(v_i, v_{j}\right)\in A} f_{i j}-\sum_{k:\left(v_{k}, v_{i}\right) \in A} f_{k i}=0, & i \neq s, t, \\ \sum_{k:\left(v_{k}, v_{t}\right) \in A} f_{k t}=v, & \\ 0 \leqslant f_{i j} \leqslant c_{i j}, & \forall\left(v_{i}, v_{j}\right) \in A . \end{array}\right. \end{array} minj:(vi,vj)Afijbij s. t.  j:(vs,vj)Afsj=v,j:(vi,vj)Afijk:(vk,vi)Afki=0,k:(vk,vt)Afkt=v,0fijcij,i=s,t,(vi,vj)A.

v = 最大流 v m a x v=最大流v_{max} v=最大流vmax时,本问题就是最小费用最大流问题;如果 v > v m a x v>v_{max} v>vmax,则本问题无解

2.2 求最小流的迭代算法

(1)求出从出发点到收点的最小费用流 μ ( v x , v t ) \mu (v_x,v_t) μ(vx,vt)。(类似求最短路)

(2)对该通路 μ ( v x , v t ) \mu (v_x,v_t) μ(vx,vt)分配可能的最大流量 f ˉ = min ⁡ ( v i , v j ) ∈ μ ( v s , v t ) { c i j } \bar f=\min_{(v_i,v_j)\in \mu(v_s,v_t)}\{c_{ij}\} fˉ=min(vi,vj)μ(vs,vt){cij},并让通路上所有边的容量对应减少 f ˉ \bar f fˉ。并将通路上的饱和边的单位费用改为 ∞ \infty .

(3)作该通路 μ ( v s , v t ) \mu (v_s,v_t) μ(vs,vt)所有边 ( v i , v j ) (v_i,v_j) (vi,vj)的反向边 ( v j , v i ) (v_j,v_i) (vj,vi)。令 c j i = f ˉ , b j i = − b i j c_{ji}=\bar f,b_{ji}=-b_{ij} cji=fˉbji=bij

(4)重复(1)~(3),直到发点到收点的全部流量等于 v v v为止,或找不到增广路到 v v v


2.3 matlab 求最大费用最小流

如图带有运费的网络,求从 v s v_s vs v t v_t vt的最小费用最大流,其中弧上权重的第1个数字是网络的容量,第2个数字是网络的单位运费。

【图论】网络流——最大流和最小费用流

NN = cellstr(strcat('v',int2str([2:5]')));  % 构造中间节点
NN = {'vs',NN{:},'vt'}; % 添加发点和收点
L ={'vs','v2',5,3;'vs','v3',3,6;'v2','v4',2,8;'v3','v2',1,2;
    'v3','v5',4,2;'v4','v3',1,1;'v4','v5',3,4;'v4','vt',2,10;
    'v5','vt',5,2};
G=digraph;G=addnode(G,NN);
G1=addedge(G,L(:,1),L(:,2),cell2mat(L(:,3)));
[M,F]=maxflow(G1,'vs','vt');    % 求最大流


G2=addedge(G,L(:,1),L(:,2),cell2mat(L(:,4)));
c = full(adjacency(G1,'weighted'));
b = full(adjacency(G2,'weighted'));
f = optimvar('f',6,6,'LowerBound',0);
prob=optimproblem;
prob.Objective = sum(sum(b.*f));
con1 = [sum(f(1,:))==M
    sum(f(:,[2:end-1]))'==sum(f([2:end-1],:),2)
    sum(f(:,end))==M];
prob.Constraints.con1=con1;
prob.Constraints.con2=f<=c;
[sol,fval,flag,out ] = solve(prob);
ff=sol.f;   % 显示最小费用最大流对应的矩阵

图中对应的就是最小费用最大流:

【图论】网络流——最大流和最小费用流

学习对象:【13-2: Ford-Fulkerson Algorithm 寻找网络最大流】文章来源地址https://www.toymoban.com/news/detail-514812.html

到了这里,关于【图论】网络流——最大流和最小费用流的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数学建模十大算法04—图论算法(最短路径、最小生成树、最大流问题、二分图)

    一、最短路径问题 从图中的某个顶点出发,到达另一个顶点的 所经过的边的权重之和最小 的一条路径。 1.1 两个指定顶点之间的最短路径 问题如下:给出了一个连接若干个城镇的铁路网络,在这个网络的两个指定城镇间,求一条最短铁路线。 1.1.1 Dijkstra算法 迪杰斯特拉(D

    2024年02月02日
    浏览(71)
  • 32.利用fmincon 解决 最小费用问题(matlab程序)

    1. 简述        fmincon函数非线性约束下的最优化问题 fmincon函数,既是求最小约束非线性多变量函数 该函数被用于求如下函数的最小值 语法如下: x = fmincon(fun,x0,A,b) x = fmincon(fun,x0,A,b,Aeq,beq) x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub) x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon) x = fmincon(fun,x0,A,b,Aeq,

    2024年02月14日
    浏览(41)
  • 382. K取方格数(图论,费用流,拆点,上下界可行流,网格图模型)

    在一个 N×N 的矩形网格中,每个格子里都写着一个非负整数。 可以从左上角到右下角安排 K 条路线,每一步只能往下或往右,沿途经过的格子中的整数会被取走。 若多条路线重复经过一个格子,只取一次。 求能取得的整数的和最大是多少。 输入格式 第一行包含两个整数

    2024年04月28日
    浏览(24)
  • 图论- 最小生成树

    一幅图可以有很多不同的生成树,比如下面这幅图,红色的边就组成了两棵不同的生成树: 对于加权图, 每条边都有权重(用最小生成树算法的现实场景中,图的边权重一般代表成本、距离这样的标量),所以每棵生成树都有一个权重和。 比如上图,右侧生成树的权重和显

    2024年04月25日
    浏览(34)
  • 图论——最小生成树

    想了解最小生成树,首先得明白什么是生成树。 生成树的概念: 包含连通图中所有的顶点,且任意两顶点之间有且仅有一条通路。 那什么是最小生成树? 最小生成树(Minimum Spanning Trees)的概念:连通图的一颗生成树(Spanning Tree)是包含图的所有顶点的连通无环子图(也就是一棵

    2023年04月13日
    浏览(32)
  • 算法提高-图论- 最小生成树

    和上题一摸一样,但是题意要求的out看起来需要特别处理,其实只要想清楚kruskal的性质就好 题意就是求最小生成树,因为边权都是正数,那么我们多选一条边必然会导致我们的代价增大 但如果题目说了边权为正或者负数,那么就不是最小生成树了,极端一点所有边都是负的

    2024年02月16日
    浏览(43)
  • 图论--EK求最大流

    描述 给定 n 个点,m 条边,给定每条边的容量,求从点 s 到点 t 的最大流。 输入描述 第一行 4 个整数 n,m,s,t (1≤n≤100 ; 1≤m≤5000 ; 0≤c≤231−1 ; s=t) 。 接下来的 m 行,每行 3 个整数 u,v,c 表示 u 到 v ,流量为 c 的一条边。 输出描述 点 s 到点 t 的最

    2024年02月13日
    浏览(38)
  • 【图论】最小生成树的应用

    P1550 [USACO08OCT] Watering Hole G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 1.我们是要使所有的农场都要有水 2.可以从起点引水,也可以互相引水。 3.费用要最小 这时我们可以想到最小生成树,建立一个虚拟节点即可。思路一目了然。 当看到这些条件,可以想到最小生成树 1.涉及

    2024年02月10日
    浏览(40)
  • 图论05-岛屿的最大面积(Java)

    5.岛屿的最大面积 题目描述 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0 (代表水)包围着。 岛屿的面积是岛上值为 1 的单元

    2024年03月25日
    浏览(38)
  • 【图论】最小生成树(python和cpp)

    本帖持续更新中 如有纰漏望指正! (a)点云建立的k近邻图 (b)k近邻图上建立的最小生成树 最小生成树 (Minimum Spanning Tree,简称 MST) 是一种在带权无向图中的树,它连接了图中所有节点并且总权重最小。在最小生成树中,任意两个节点之间有且仅有一条路径,同时这些路径

    2024年02月05日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包