Chaos is a ladder.|

West11

园龄:11个月粉丝:1关注:1

网络最大流量问题

网络最大流量问题

啥叫流量?上网用的?

网络的流量,顾名思义就像我们用手机上网时所说的流量一样,是用来描述网络中的支路上通过的量的大小。

比如你使用了10G的流量,就说明有10G的数据通过手机和服务器之间的支路进行了传输。

在图论中,设有向图 D=(V,A,C) , V是点集,A是边集,C是容量集。

https://picx.zhimg.com/80/v2-a9bce782dfae7721ff27b03465f97e9b_1440w.png?source=d16d100b

添加图片注释,不超过 140 字(可选)

ViVj 的容量为Cij≥0,CijC . 通过这条支路的流量就为 xij .

一张流量图包含发点,收点,中间点

  • 发电:仅有出弧的点
  • 收点:仅有入弧的点
  • 中间点:出发点与收点的其他点

可行流

一个流量图的可行流满足如下条件

  1. 容量条件: 0xijCij
  2. 平衡条件:
    1. 发点的净输出量=收点的净输入量
    2. 中间点的输入量=中间点输出量(有基尔霍夫定律的感觉有没有)

增广链

根据可行流的平衡条件,如果某些节点(比如发点)多发一些流量,那么这条链接下来的中间点收到的流量都会增大,这样的链叫增广链。注意流量不能超过容量。

对于每一条弧:1. 前向弧(向下一个节点发流量):找那些可以增加流量的弧。

  1. 反向弧(向上一个节点发流量):找那些可以减小流量的弧。

所有前向流的流量+1,反向流的流量相应地-1.

Ford Fulkerson算法

该算法分为标号和增流过程,标号过程找到一条可增广的弧,增流过程算出最大的流量。

https://picx.zhimg.com/80/v2-9859b106757208a93fa94aa6b548275c_1440w.png?source=d16d100b

添加图片注释,不超过 140 字(可选)

https://picx.zhimg.com/80/v2-4bffe410c3eb3945da02e518031afb8c_1440w.png?source=d16d100b

添加图片注释,不超过 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函数为老版本,新版本不再使用。

详细函数情况:图中的最大流 - MATLAB maxflow - MathWorks 中国

本文作者:West11

本文链接:https://www.cnblogs.com/cxy1114blog/p/18288100

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   West11  阅读(28)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起