网络最大流量问题
网络最大流量问题
啥叫流量?上网用的?
网络的流量,顾名思义就像我们用手机上网时所说的流量一样,是用来描述网络中的支路上通过的量的大小。
比如你使用了10G的流量,就说明有10G的数据通过手机和服务器之间的支路进行了传输。
在图论中,设有向图 D=(V,A,C) , V是点集,A是边集,C是容量集。
添加图片注释,不超过 140 字(可选)
一张流量图包含发点,收点,中间点
- 发电:仅有出弧的点
- 收点:仅有入弧的点
- 中间点:出发点与收点的其他点
可行流
一个流量图的可行流满足如下条件
- 容量条件:
- 平衡条件:
- 发点的净输出量=收点的净输入量
- 中间点的输入量=中间点输出量(有基尔霍夫定律的感觉有没有)
增广链
根据可行流的平衡条件,如果某些节点(比如发点)多发一些流量,那么这条链接下来的中间点收到的流量都会增大,这样的链叫增广链。注意流量不能超过容量。
对于每一条弧:1. 前向弧(向下一个节点发流量):找那些可以增加流量的弧。
- 反向弧(向上一个节点发流量):找那些可以减小流量的弧。
所有前向流的流量+1,反向流的流量相应地-1.
Ford Fulkerson算法
该算法分为标号和增流过程,标号过程找到一条可增广的弧,增流过程算出最大的流量。
添加图片注释,不超过 140 字(可选)
添加图片注释,不超过 140 字(可选)
function [max_flow, flow] = ford_fulkerson(G, source, sink)
% G 是一个邻接矩阵,表示图的边和容量
% source 是源点
% sink 是汇点
% 初始化流矩阵
flow = zeros(size(G));
max_flow = 0;
% 标记数组,记录是否访问过
visited = false(size(G, 1), 1);
% 寻找增广路径
while true
% 重置访问标记
visited = false;
% BFS 寻找从源点到汇点的增广路径
path = bfs(G, source, sink, visited, flow);
% 如果没有找到增广路径,退出循环
if isempty(path)
break;
end
% 计算增广路径上的最小容量
path_flow = inf;
for i = 1:length(path) - 1
edge = [path(i), path(i + 1)];
path_flow = min(path_flow, G(edge(1), edge(2)));
end
% 更新流矩阵
for i = 1:length(path) - 1
edge = [path(i), path(i + 1)];
flow(edge(1), edge(2)) = flow(edge(1), edge(2)) + path_flow;
flow(edge(2), edge(1)) = flow(edge(2), edge(1)) - path_flow;
end
% 更新最大流
max_flow = max_flow + path_flow;
end
end
function path = bfs(G, source, sink, visited, flow)
% 使用广度优先搜索寻找增广路径
path = [];
parent = [];
queue = [source];
while ~isempty(queue)
u = queue(1);
queue(1) = [];
if u == sink
break;
end
for v = 1:length(G)
if ~visited(v) && G(u, v) - flow(u, v) > 0
queue = [queue, v];
parent = [parent, u];
visited(v) = true;
end
end
end
% 回溯找到路径
if ~isempty(parent)
path = [sink];
while path(end) ~= source
path = [parent(path(end)), path];
end
path = [source, path];
end
end
Matlab工具库
[flowValue, flowMatrix] = maxflow (G, s, t);
%G:这是一个graph对象,表示图的结构。graph对象可以通过graph函数创建,并通过addnode和addedge等函数添加节点和边。
%s:这是源节点的索引,表示流开始的节点。在图的上下文中,节点通常由整数索引标识,源节点是指定从哪个节点开始计算流。
%t:这是汇节点的索引,表示流结束的节点。与源节点类似,汇节点指定了流的终点。
%maxflow函数返回的值是:flowValue:这是一个数值,表示从源节点到汇节点可以流动的最大流量。
% 可以在最后加算法参数
%'searchtrees'(默认值)使用博伊科夫-科尔莫戈洛夫算法。通过构造与节点 s 和 t 相关联的两个搜索树,计算最大流。
%'augmentpath' 使用 Ford-Fulkerson 算法。通过求残差有向图中的增广路径,以迭代方式计算最大流。有向图中相同的两个节点之间不能有相反方向的任何平行边,除非这些边中某条边的权重为零。因此,如果图包含边 [i j],则仅当 [i j] 的权重为零和/或 [j i] 的权重为零时,它才能包含反向边 [j i]。
%'pushrelabel' 通过将某节点的余流推送到其相邻节点并为该节点重新添加标签,计算最大流。有向图中相同的两个节点之间不能有相反方向的任何平行边,除非这些边中某条边的权重为零。因此,如果图包含边 [i j],则仅当 [i j] 的权重为零和/或 [j i] 的权重为零时,它才能包含反向边 [j i]。
注意:graphmaxflow函数为老版本,新版本不再使用。
本文作者:West11
本文链接:https://www.cnblogs.com/cxy1114blog/p/18288100
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步