前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图论-网络流

图论-网络流

作者头像
温安适
发布2018-05-17 17:02:34
1.2K0
发布2018-05-17 17:02:34
举报
文章被收录于专栏:温安适的blog温安适的blog

前言

大家好,祝大家2017年身体健康,万事如意,开年第一篇blog网路流,希望大家指正。

网路流问题介绍

描述

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

性质

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

实际应用举例

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

二分匹配问题定义

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

图解说明

生活中二分匹配问题举例

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

如何转换问题

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

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

网络流问题算法实现

语言描述

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

图例说明最大网络流算法

代码示例

代码语言:javascript
复制
/**
	 * 获取从起点到终点的最大网络流
	 * @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.获取当前最短路径的最大流

代码语言:javascript
复制
	/**
	 * 获取当前最短路径的最大流
	 * @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.修改原图为残余图保留当前网络流

代码语言:javascript
复制
	/**
	 * 为网络流图赋值,修剪原图
	 * 如果原图中有一条边修剪后权为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);
		}
	}

完整代码地址

[码云地]址:单击跳转](https://git.oschina.net/WLjava/DataStructuresAndAlgorithm/blob/master/src/main/java/chapter9/maxflow/MaxWebFlow.java?dir=0&filepath=src%2Fmain%2Fjava%2Fchapter9%2Fmaxflow%2FMaxWebFlow.java&oid=14cc06fb68373aefc0ec65af571112ac8019f81a&sha=2e3d013f5808da536adc100c90d5a246b9562a28)

github地址:单击跳转

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 网路流问题介绍
    • 描述
      • 性质
      • 实际应用举例
        • 二分匹配问题定义
          • 图解说明
            • 生活中二分匹配问题举例
            • 如何转换问题
        • 网络流问题算法实现
          • 语言描述
            • 图例说明最大网络流算法
              • 代码示例
              • 完整代码地址
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档