专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

图论-网络流

网路流问题介绍

描述

设给定有向图G=(V,E),其边的容量为cvw.(这些容量可以代表通过一个管道的水的流量或者马路上的交通流量) s为发点,t为收点,最大网络流问题是求从s到t可以通过的最大流量。

性质

在既不是发点s,也不是收点t的任意顶点v,总的进入流必须等于总的发出流。

实际应用举例

最大网络流可以解决二分匹配问题.

二分匹配问题定义

找出E的最大子集E`使得没有顶点含在多于一条的边中。

图解说明

68_1.png

生活中二分匹配问题举例

有一组老师,有一些课,以及每位老师有资格教授的课程表,如果每位老师最多只能开设一门课,那么最多可以开设几门课?

如何转换问题

1、 以老师(例如下图绿色),课程(下图蓝色)为节点。
2、 以课程列表中的老师与课程关系构建图,并将每条边的权赋值为1
3、 创建虚拟节点s,t。s到每个老师有一条权为1的边,每个课程有一条权为1到t的边。

如下图所示:该问题实际为从s到t的最大网络流 。

68_2.png

网络流问题算法实现

语言描述

1、 以Dijkstra算法,求解从s到t的赋权最短路径。
2、 找到当前最短路径上的最小权,即为当前最大网络流。
3、 以当前最短路径和当前最大网络流,修改原图为残余图,保存当前最大网络流。
4、 以残余图继续执行1,2,3步,直到s和t不连通为止。

图例说明最大网络流算法

68_3.png68_4.png68_5.png68_6.png

代码示例

/**
     * 获取从起点到终点的最大网络流
     * @param start 起点
     * @param end   终点
     * @return 从起点到终点的最大网络流
     */
    public  Integer getMaxFlow(Vertex start,Vertex end){
        int maxFlow=0;
        while (true) {
            dijkstra(start, end);//找到从起点到终点的最短路径
            if(end.dist==Integer.MAX_VALUE){
                break;
            }
            printPath(end);//打印路径便于观察
            int currentMaxFlow = getCurrentMaxFlow(end);//得到当前路径的最大网络流
            //修建原图
            changeGraphWeightAndSetMaxFlow(end, currentMaxFlow, maxFlowGraph);
            maxFlow+=currentMaxFlow;//记录最大网络流
            //打印当前最大网络流图,以便追踪是否正确
            System.out.println();
            for (Vertex v : maxFlowGraph.values()) {
                System.out.println(v);
            }
        }
        return maxFlow;
    }

1、获取当前最短路径的最大流

    /**
     * 获取当前最短路径的最大流
     * @param end 终点
     * @return 从起点到终点的当前最大流
     */
private  Integer getCurrentMaxFlow(Vertex end) {
    if (end.getPath() != null) {
        Integer parentcwv = 0;
        if (end.getPath() != null) {
            parentcwv = getCurrentMaxFlow(end.getPath());
        }
        Integer cwv = end.getPath().getAdj().get(end);
            return Math.min(cwv, parentcwv);
        } else {
            return Integer.MAX_VALUE;
        }

    }

2、修改原图为残余图保留当前网络流

    /**
     * 为网络流图赋值,修剪原图
     * 如果原图中有一条边修剪后权为0,去掉该边
     * @param end 终点
     * @param currentMaxFlow 当前最大流
     * @param maxFlowGraph 网络流结果图
     */
public  void changeGraphWeightAndSetMaxFlow(Vertex end, Integer currentMaxFlow, Map<String, Vertex> maxFlowGraph) {
        if (end.getPath() != null) {
            int oldCwv = end.getPath().getAdj().get(end);
            if (oldCwv - currentMaxFlow > 0) {
                end.getPath().getAdj().put(end, oldCwv - currentMaxFlow);
            } else if (oldCwv - currentMaxFlow == 0) {
                end.getPath().getAdj().remove(end);
            }
            String startName=end.getPath().name;
            Integer oldcvw=maxFlowGraph.get(startName).adj.get(maxFlowGraph.get(end.name));
            maxFlowGraph.get(startName).adj.put(maxFlowGraph.get(end.name), oldcvw+currentMaxFlow);
            maxFlowGraph.get(end.name).setPath(maxFlowGraph.get(startName));
            changeGraphWeightAndSetMaxFlow(end.getPath(), currentMaxFlow, maxFlowGraph);
        }
    }

完整代码地址

[码云地]址:单击跳转](git.oschina.net/WLjava/Data…)

github地址:单击跳转

文章永久链接:https://tech.souyunku.com/35826

未经允许不得转载:搜云库技术团队 » 图论-网络流

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们