本文简单实现了最短增广路径算法

首先我们简单实现 queue(队列) 数据结构 :

local queue = {}
queue.__index = queuefunction queue:push(val)table.insert(self.data, val)
endfunction queue:pop()if #self.data > 0 thenreturn table.remove(self.data, 1)end
endfunction queue:clear()self.data = {}
endfunction queue:empty()return #self.data <= 0
endfunction queue.create()local t = { data = {} }return setmetatable(t, queue)
end

通过给定的网络结构(使用邻接表表示),生成对应的实流网络和残余网络 :

function prepare_net(define_net)if define_net thenlocal flow_net = {}local residual_net = {}-- handle flow netfor node, next_nodes in pairs(define_net) doflow_net[node] = {}for next_node, capacity in pairs(next_nodes) do-- if check for handling ill settingsif node ~= next_node and capacity > 0 thenflow_net[node][next_node] = 0endendend-- handle residual netfor node, next_nodes in pairs(define_net) doresidual_net[node] = residual_net[node] or {}for next_node, capacity in pairs(next_nodes) do-- if check for handling ill settingsif node ~= next_node and capacity > 0 thenresidual_net[node][next_node] = capacityresidual_net[next_node] = residual_net[next_node] or {}residual_net[next_node][node] = 0endendendreturn flow_net, residual_netend
end

接着就是实际的算法实现了,基本思路就是迭代查找可增广路径,并调整路径流量:

function max_flow_net(define_net, src_node, dst_node)-- ill case handlingif not define_net or src_node == dst_node thenreturnendlocal flow_net, residual_net = prepare_net(define_net)if not flow_net or not residual_net thenreturnendlocal queue_nodes = queue.create()queue_nodes:clear()queue_nodes:push(src_node)local visited_nodes = { [src_node] = true }local parent_nodes = {}while not queue_nodes:empty() dolocal cur_node = queue_nodes:pop()local next_nodes = residual_net[cur_node]for node, flow in pairs(next_nodes) doif flow > 0 and not visited_nodes[node] thenif node == dst_node then-- do net handling-- find flow pathlocal flow_path = { node }local parent_node = cur_nodewhile parent_node dotable.insert(flow_path, 1, parent_node)parent_node = parent_nodes[parent_node]end-- get min flowlocal min_flow = math.hugefor i = 1, #flow_path - 1 dolocal node_1 = flow_path[i]local node_2 = flow_path[i + 1]local edge_flow = residual_net[node_1][node_2]if edge_flow < min_flow thenmin_flow = edge_flowendend-- error handlingif min_flow >= math.huge thenprint("error to get min flow of path")returnend-- adjust residual net and flow netfor i = 1, #flow_path - 1 dolocal node_1 = flow_path[i]local node_2 = flow_path[i + 1]residual_net[node_1][node_2] = residual_net[node_1][node_2] - min_flowresidual_net[node_2][node_1] = residual_net[node_2][node_1] + min_flowif define_net[node_1][node_2] and define_net[node_1][node_2] > 0 thenflow_net[node_1][node_2] = flow_net[node_1][node_2] + min_flowelseflow_net[node_1][node_2] = flow_net[node_1][node_2] - min_flowendend-- do another round searchingqueue_nodes:clear()queue_nodes:push(src_node)visited_nodes = { [src_node] = true }parent_nodes = {}breakelsevisited_nodes[node] = trueparent_nodes[node] = cur_nodequeue_nodes:push(node)endendendendreturn flow_net
end

给出如下网络:

local define_net =
{[1] = {[2] = 12,[3] = 10,},[2] = {[4] = 8,},[3] = {[2] = 2,[5] = 13,},[4] = {[3] = 5,[6] = 18,},[5] = {[4] = 6,[6] = 4,},[6] = {},
}

对应的图形表示如下:

有兴趣的朋友可以看看以下代码的结果:

max_flow_net(define_net, 1, 6)

Sweet Snippet 之 最短增广路径算法相关推荐

  1. 网络流—Edmonds-Karp 最短增广路算法(最大流)

    网络流----Edmonds-Karp 最短增广路算法 ■求最大流的过程,就是不断找到一条源到汇的路径,然后构建残余网络,再在残余网络上寻找新的路径,使总流量增加,然后形成新的残余网络,再寻找新路径- ...

  2. 网络流之 最短增广路算法模板(SAP)

    数据输入格式:首先输入顶点个数n和弧数m,然后输入每条弧的数据.规定源点为顶点0,汇点为顶点n-1.每条弧的数据格式为:u,v,w,分别表示这条弧的起点,终点,容量.顶点序号从0开始. 代码: 1 # ...

  3. 最短增广路Isap算法 网络流

    最短增广路 请先理解 bfs的求增广路的算法,再来学习Isap算法 最短增广路Isap算法 图片来源 <趣学算法>人民邮电出版社 陈小玉 /* 最短可增广路:重贴标签算法Isap 算法设计 ...

  4. SAP和ISAP(网路最大流的两个增广路算法)

    ISAP是对SAP进行优化后的算法,ISAP时间复杂度为O(V^2E),SAP的时间复杂度为O(VE^2) SAP #include <iostream> #include <alg ...

  5. 网络最大流中一般增广路算法(标号法)

    网络最大流主要有两大类求解方法:增广路算法和预流推进算法 一般增广路算法:主要分为初始流为零流和初始流为非零流的情况!后者在标号的时候注意一条边是正向连接还是反向连接:若是反向的连接,那么在调整的时候 ...

  6. 增广路算法 (最大流问题)

    Edmonds-Karp算法: 计算机科学中, Edmonds–Karp算法通过实现Ford–Fulkerson算法来计算网络中的最大流,其时间复杂度为O(V E2). 该算法由Yefim (Chai ...

  7. PRML第十一章读书笔记——Sampling Methods 拒绝采样/重要性采样/采样重要性重采样/数据增广IP算法、Metropolis算法/MH算法/吉布斯、切片采样、混合MC、估计配分函数

    (终于把第十章读完了,这一章应该相对轻松.但这两天状态有待调整,所以没咋认真读) 目录 11.1 Basic Sampling Algorithms P526 标准概率分布 P528 拒绝采样 P53 ...

  8. 青出于蓝而胜于蓝,超越MixUp、CutMix的样本混合数据增广新算法FMix

    点击我爱计算机视觉标星,更快获取CVML新技术 深度学习实践中,数据的增广有很多种方法,比如在计算机视觉任务中除了常规的对单样本进行缩放.颜色扰动.旋转.镜像等外,也可以通过对两个样本进行混合,生成新 ...

  9. 网络流 之 一般增广路算法 标号法实现

    数据输入格式:首先输入顶点个数n和弧数m,然后输入每条弧的数据.规定源点为顶点0,汇点为顶点n-1.每条弧的数据格式为:u,v,c,f,分别表示这条弧的起点,终点,容量和流量.顶点序号从0开始. 代码 ...

最新文章

  1. 23张图!万字详解「链表」,从小白到大佬!
  2. c++ 读取数字,直到输入非数字字符为止的算法(附完整源码)
  3. 探索 dotnet core 为何在 Windows7 系统需要补丁的原因
  4. html鼠标悬停盒子凸起,css3 transform动画鼠标悬停div容器凸起放大显示
  5. 国嵌c语言深度,国嵌C语言深度剖析班(第一期)-国嵌
  6. C语言的一些知识总结
  7. Android权限之sharedUserId和签名
  8. User-Agent的变迁——浏览器大战之前世今生
  9. SQL注入工具-----sqlmap
  10. 移动硬盘安装Linux ubuntu20.04.1LTS,分区详细介绍
  11. 前端工程师应该懂的ps基本操作
  12. DDWRT 下设置OPEN×××
  13. 怎么将多张图片打印在一张A4纸上?
  14. 七天引爆社交新零售(助你提高十倍业绩)——前言
  15. 在python中输入圆的半_python半圆
  16. 团队作业——Alpha冲刺 8/12
  17. STM32CUBEIDE使用说明
  18. Android studio File Explorer sdcard文件怎么访问
  19. Python实现一个简单课堂点名器
  20. MPB:南农韦中组-植物根际土壤样品的非破坏性连续采集

热门文章

  1. 拳王虚拟项目公社:有什么创业好项目?90后年赚30W逆袭案例让你读懂网络创业
  2. 前端性能优化的14个规则
  3. hdu2853 Assignment
  4. IEEE SCI期刊、会议模板下载
  5. 苹果手机悬浮窗怎么打开_怎么通过悬浮窗录音?再也不用担心文本被遮挡
  6. java原始人生存繁殖的游戏,原始人荒地求生
  7. CC1310 底噪测量以及实际意义
  8. 一个月收入多少可以达到财务自由标准?
  9. 为什么需要HTTPS
  10. 谷歌的移动互联网王国构想