笔记(三)maxflow push relabel与图像分割

笔记(三)maxflow push relabel与图像分割

  • 1. Push-Relabel算法思想
  • 2.Push-Relabel算法原理示意图
  • 3.Push-Relabel算法具体实例
  • 4. push relabel与图割

1. Push-Relabel算法思想

对于一个网络流图: 该算法直观可以这样理解,先在源节点处加入充足的流(跟源节点 s s s相连的所有边的容量之和),然后开始按一定规则进行流渗透,一个边一个边的向汇点渗透,直到没法再渗透(类似于Ford-Fulkerson算法中找不到增广路径了),那么这时再把一些剩余的流回收到源节点 s s s就可。
主要分为两个步骤:push和relabel。push表示从所有节点找出一个存水量大于0的节点 u u u,将它所存的水尽可能推向与它相邻的节点 v v v。要实现该push的操作必须满足下面条件:该点存水量 e ( u ) > 0 e(u)>0 e(u)>0,节点 u u u的高度大于节 v v v的高度。本次推送的流值 ( u , v ) . f = min ⁡ e ( u ) , ( u , v ) . c a p a c i t y \mathbf{(u,v).f}= \min \mathbf{e(u)},\mathbf{(u,v).capacity} (u,v).f=mine(u),(u,v).capacity为边 e d g e ( u , v ) \mathbf{edge(u,v)} edge(u,v)的当前容量,这个值在推进过程中会一直变换。relabel表示某一个节点存水量大于0但水流不出去时,我们对该节点高度增加1,这就是所谓relabel操作,使得该节点的存水量流入比它低的节点。一开始的时候我们设置源节点高度为 N N N,此处 N N N为节点数,其他所有节点高度为0,并且汇节点的高度固定为0,其他节点高度在算法执行过程中高度 h h h会改变。

算法步骤:
1.初始化前置流:将与源点s相连的管道流量 f ( 0 , i ) f(0,i) f(0,i)设为该管道的容量,即 f ( 0 , i ) = c ( 0 , i ) f(0,i)=c(0,i) f(0,i)=c(0,i);将源点 s s s的高度 h ( 0 ) = V h(0)=V h(0)=V,( V V V表示图的顶点个数),其余顶点高度 h ( i ) = 0 h(i)=0 h(i)=0;将源的点余量 e ( 0 ) e(0) e(0)设为源容量减去源的流出量,即 e ( 0 ) = − ∑ f ( 0 , i ) = − ∑ c ( 0 , i ) e(0)=-∑f(0,i)=-∑c(0,i) e(0)=f(0,i)=c(0,i),与源 s s s相连的点余量设为该点的流入量 e ( i ) = c ( 0 , i ) e(i)=c(0,i) e(i)=c(0,i),其余点都为0。

2.搜索是否有节点的点余量 e ( u ) > 0 e(u)>0 e(u)>0,如果存在,表示要对该点进行操作——重标记或者压入流:检查与该点 u u u全部的相邻点 v v v,若该点比它相邻点的高度大 h ( u ) > h ( v ) h(u)>h(v) h(u)>h(v),该管道的当前容量为 c ( u , v ) c(u,v) c(u,v),将该点 u u u的余量以最大方式压入该管道 d e l t a = m i n ( e ( u ) , c ( u , v ) ) delta=min(e(u),c(u,v)) delta=min(e(u),c(u,v)),然后对节点 u u u, v v v的余量 e e e、边 ( u , v ) (u,v) (u,v)的容量进行相应的进行减加操作;如果找不到高度比自己低的相邻节点 v v v,则对节点 u u u的高度增加1,即 h ( u ) = h ( u ) + 1 h(u)=h(u)+1 h(u)=h(u)+1。如此继续进行Push操作。以上的重标记或压入流操作循环进行,直至该点的余量 e ( u ) e(u) e(u)为0。

3.重复第2步,直找不到余量大于0的节点,停止算法,最后输出汇点 t t t的余量 e ( t ) e(t) e(t),该值就是最后所求的最大流。最小割。

2.Push-Relabel算法原理示意图

给定的网络流图如下:

在这里插入图片描述
第一步:初始化操作:
在这里插入图片描述
第一次Push不成功,进行Relabel
在这里插入图片描述

第二次Push,成功

在这里插入图片描述

继续Push

在这里插入图片描述
继续Push

在这里插入图片描述
继续Push
在这里插入图片描述
至此结束。

3.Push-Relabel算法具体实例

求解下面网络流图的最大流:

在这里插入图片描述
源节点为s
,汇节点为t

具体程序实现如下:

/****************************************************
Description:Push-Relabel算法求解网络最大流
Author:Robert.TY
Date:2016.12.10 
****************************************************/ 
#include<iostream>
#include<limits>
#include<iomanip> 
using namespace std;
struct Point{char ch;//节点标识 int e;//存货量int h;//高度 
};    
Point point[6];               
int graph[6][6]={{0,10,10,0,0,0},{0,0,2,8,4,0},{0,0,0,9,0,0},{0,0,0,0,9,10},{0,0,0,0,0,10},{0,0,0,0,0,0}} ;        
int Push_Relabel(int s, int t,int n); //参数为 起点  端点  节点数 int main(){  int  n=6;  point[0].ch='s';  point[0].e=0; point[0].h=0; point[1].ch='u';  point[1].e=0; point[1].h=0; point[2].ch='v';  point[2].e=0; point[2].h=0; point[3].ch='a';  point[3].e=0; point[3].h=0; point[4].ch='b';  point[4].e=0; point[4].h=0; point[5].ch='t';  point[5].e=0; point[5].h=0; cout<<"原始网络图邻接矩阵:"<<endl;for(int i=0;i<=5;i++){for(int j=0;j<=5;j++){cout<<setw(6)<<graph[i][j]<<" ";}cout<<endl;} cout<<"max_flow="<<Push_Relabel(0, n-1,n)<<endl; cout<<"graph流图矩阵:"<<endl;for(int i=0;i<=5;i++){for(int j=0;j<=5;j++){cout<<setw(6)<<graph[i][j]<<" ";}cout<<endl;} return 0;  
} int Push_Relabel(int s, int t,int n)  
{  int  max_flow;point[s].h = n;  //起始点高度置为n 最高//初始化 将start点的库存 流出去 update剩余图 for (int u = 1; u <= t; u++) {  if (graph[s][u] > 0) {  point[u].e = graph[s][u];  point[s].e -= graph[s][u];  graph[u][s] = graph[s][u];  graph[s][u] = 0;  }   }while(1) {  int finishflag = 1;  for (int u = s+1; u < t; u++) {  //搜索除  节点s 节点t以外的节点 if (point[u].e > 0) {  //发现库存量大于0的节点 u  进行push finishflag = 0;  int relabel = 1;   //先假设顶点u需要relabel  提高高度h for (int v = s; v <= t && point[u].e > 0; v++) {   //搜索能push的顶点   if (graph[u][v] > 0 && point[u].h >point[v].h) {  //发现节点v relabel = 0;  //顶点u不需要relabelint bottleneck = min(graph[u][v], point[u].e);  point[u].e -= bottleneck; //u节点库存量减少 point[v].e += bottleneck; //v节点库存量减少graph[u][v] -= bottleneck;  graph[v][u] += bottleneck;  }  }  if (relabel==1) {  //没有可以push的顶点,u节点需要relabel 提高高度point[u].h += 1;   }  }  }  if (finishflag==1) { // 除源点和汇点外,每个顶点的e[i]都为0 max_flow = 0;  for (int u = s; u <= t; u++) {  if (graph[t][u] > 0) {  max_flow += graph[t][u];  }  }  //cout<<"max_flow="<<max_flow<<endl;break;  }  }  return max_flow;  
}  

结果如下:

原始网络图邻接矩阵:0     10     10      0      0      00      0      2      8      4      00      0      0      9      0      00      0      0      0      9     100      0      0      0      0     100      0      0      0      0      0
max_flow = 19
graph 流图矩阵:0      0      1      0      0      010      0      2      2      0      09      0      0      0      0      00      6      9      0      4      00      4      0      5      0      10      0      0     10      9      0--------------------------------
Process exited after 0.04971 seconds with return value 0Press ANY key to exit...

最大流可以通过最后一行的数值得到,即与t直接相关联的流量。

参考:最大流网络之Push-Relabel算法

4. push relabel与图割

Push-relabel算法是一种用于求解最大流问题的算法,也可以应用于图像分割领域。下面是将Push-relabel算法应用于图像分割的基本步骤:

构建图:首先,将输入图像转换为图的形式。每个像素被表示为一个节点,每个相邻的像素之间存在一条边,边的权重可以表示像素之间的差异或相似度。
初始化:对图进行初始化,通常将每个节点的标签初始化为一个唯一的整数。
推送流:从源节点开始,通过不断地推送流和重新标签化的操作,将流从源节点推送到汇节点。在这个过程中,Push-relabel算法会尝试将更多的流推送到已经饱和的节点,直到无法再推送更多的流为止。
重新标签:在推送流的过程中,当一个节点接收到的流超过其容量时,该节点会变得“饱和”。Push-relabel算法会为这个节点分配一个新的标签,并将这个节点与新标签之间的边进行更新。
更新残量网络:在推送流和重新标签的过程中,Push-relabel算法会不断更新残量网络,即还没有被推送到的边的集合。
判断终止条件:如果无法再找到新的增广路径(即无法再推送更多的流),则算法终止。
后处理:在得到最大流后,需要将结果映射回原始的图像。通常,可以将每个节点的标签映射为其所属的集合(即分割结果),或者将每个边的流量映射为边缘检测结果。
输出结果:最后,根据映射后的结果进行适当的后处理,如去除小面积的区域、平滑边缘等,以提高分割的质量。
通过以上步骤,可以使用Push-relabel算法进行图像分割。需要注意的是,Push-relabel算法通常会得到多解,因此需要进行合适的后处理和参数调整,以获得最佳的分割结果。

伪代码:

Push-relabel算法的伪代码如下:初始化:对于每个节点u,设置low_water_mark[u] = 0和high_water_mark[u] = INF(一个很大的数)
对于每个节点u,设置label[u] = 0和delta[u] = 0
对于每条边(u,v),设置residual_capacity[u,v] = capacity[u,v],residual_flow[u,v] = 0
while there is a path from source to sink in the residual graph:从源节点开始,使用DFS或BFS等搜索算法搜索增广路径
在搜索过程中,维护一个当前节点的集合C和一条从源节点到集合C的最小割
对于每个节点u,如果u不在C中且delta[u] > 0,执行push操作:
从集合C中选择一个节点v,使得(u,v)在residual_graph中且residual_capacity[u,v] > 0
将流从u推送到v,即令delta[v] = delta[v] + delta[u],residual_flow[u,v] = residual_flow[u,v] + delta[u],residual_capacity[u,v] = residual_capacity[u,v] - delta[u]
将low_water_mark[v]更新为low_water_mark[u] + delta[v],high_water_mark[v]更新为high_water_mark[u] + delta[v],label[v]更新为label[u] + delta[v]
将low_water_mark[u]更新为max(low_water_mark[u], high_water_mark[v]),high_water_mark[u]更新为max(high_water_mark[u], label[v]),label[u]更新为label[v] - delta[u]
输出结果:将每个节点的标签映射为其所属的集合(即分割结果),或者将每个边的流量映射为边缘检测结果。需要注意的是,Push-relabel算法通常会得到多解,因此需要进行合适的后处理和参数调整,以获得最佳的分割结果。

参考:
参考:
参考:

参考:
参考:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/172860.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【经验分享】开发问题记录总结(持续更新)

目录 工具开发 界面类继承某自定义界面类时&#xff0c;出现布局混乱或者所有控件集中在左上角&#xff1f; 在继承自定义界面之后&#xff0c;以诸如 on_xxx_clicked() 模式设计的槽函数失效了? 使用pugi接口取出文本数据后&#xff0c;为什么该变量无法进行字符串比较&…

Flask WTForms 表单插件的使用

在Web应用中&#xff0c;表单处理是一个基本而常见的任务。Python的WTForms库通过提供表单的结构、验证和渲染等功能&#xff0c;简化了表单的处理流程。与此同时&#xff0c;Flask的扩展Flask-WTF更进一步地整合了WTForms&#xff0c;为开发者提供了更便捷、灵活的表单处理方式…

【STM32单片机】简易计算器设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器&#xff0c;使用动态数码管模块、矩阵按键、蜂鸣器模块等。 主要功能&#xff1a; 系统运行后&#xff0c;数码管默认显示0&#xff0c;输入对应的操作数进行四则运…

Echarts 设备状态 甘特图

在做工厂智能化生产看板时&#xff0c;绝对会有设备状态看板&#xff0c;展示设备当天或者当前状态&#xff0c;设备状态数据一般是有mes 系统设备管理模块对设备信息进行采集&#xff0c;一般包括过站数据&#xff0c;设备当前状态&#xff0c;是否在线是否故障、检修、待生产…

【计算机网络笔记】多路访问控制(MAC)协议——轮转访问MAC协议

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

树状数组 / pbds解法 E2. Array Optimization by Deque

Problem - 1579E2 - Codeforces Array Optimization by Deque - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 树状数组解法 将 a i a_i ai​插入到队头&#xff0c;贡献为&#xff1a;原队列中所有比 a i a_i ai​小的数的数量将 a i a_i ai​插入到队尾&#xff0c;贡献为&a…

极客时间:使用本地小型语言模型运行网页浏览器应用程序。

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

二进制编辑器hexedit的安装及使用

Hexedit 同时以 ASCII 和十六进制显示文件 安装 终端输入hexedit回车&#xff0c;如果没安装&#xff0c;会提示让输入 sudo apt-get install hexedit 照着输入命令&#xff0c;安装。安装完成后&#xff0c;cd到一个有二进制文件的目录下&#xff0c;输入hexedit命令回车 再…

集线器-交换机-路由器

1.集线器(Hub) 集线器就是将网线集中到一起的机器&#xff0c;也就是多台主机和设备的连接器。集线器的主要功能是对接收到的信号进行同步整形放大&#xff0c;以扩大网络的传输距离&#xff0c;是中继器的一种形式&#xff0c;区别在于集线器能够提供多端口服务&#xff0c;也…

从0开始学习JavaScript--构建强大的JavaScript图片库

在现代Web开发中&#xff0c;图像是不可或缺的一部分&#xff0c;而构建一个强大的JavaScript图片库能够有效地管理、展示和操作图像&#xff0c;为用户提供更丰富的视觉体验。本文将深入探讨构建JavaScript图片库的实用技巧&#xff0c;并通过丰富的示例代码演示如何实现各种功…

透过对话聊天聊网络tcp三次握手四次挥手

序 说起来网络&#xff0c;就让我想起的就是一张图。我在网上可以为所欲为&#xff0c;反正你又不能顺着网线来打我。接下来我们来详细说一下网络到底是怎么连接的。 TCP三次打招呼 首先我会用男女生之间的聊天方式&#xff0c;来举一个例子。 从tcp三次握手来说&#xff0c;…

基于Loki + Promtail + Grafana 搭建 Nginx 日志监控

文章目录 引言第一部分&#xff1a;Loki 简介与安装1.1 Loki 简介1.2 Loki 安装1.2.1 下载 Loki1.2.2 安装 Loki 1.3 启动 Loki 第二部分&#xff1a;Promtail 简介与安装2.1 Promtail 简介2.2 Promtail 安装2.2.1 下载 Promtail2.2.2 安装 Promtail 2.3 启动 Promtail 第三部分…

231126 刷题日报

1. 高楼扔鸡蛋 O(N*logN) 2. 698. 划分为k个相等的子集 没做出来&#xff0c;和划分两个子集不同 3. 300. 最长递增子序列 LIS petencie sorting 没看懂&#xff0c;明天看吧 4. 518. 零钱兑换 II 完全背包问题&#xff1a;每个物品数量是无限的 注意&#xff1a;dp的定义…

使用不平衡数据集练习机器学习

一、介绍 在当今世界&#xff0c;机器学习和人工智能几乎被广泛应用于每个领域&#xff0c;以提高绩效和结果。但如果没有数据&#xff0c;它们还有用吗&#xff1f;答案是否定的。机器学习算法严重依赖我们提供给它们的数据。我们提供给算法的数据质量在很大程度上决定了机器学…

2023年第十六届山东省职业院校技能大赛中职组“网络安全”赛项竞赛正式试题

第十六届山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题 目录 一、竞赛时间 二、竞赛阶段 三、竞赛任务书内容 &#xff08;一&#xff09;拓扑图 &#xff08;二&#xff09;A模块基础设施设置/安全加固&#xff08;200分&#xff09; &#xff08;三&#xf…

Centos 7.9 Install Docker Insecure Registry

文章目录 1. 镜像存储规划2. 安装定制 docker3. 部署 registry4. 验证镜像仓库 1. 镜像存储规划 linux LVM /dev/sdb mount dir /data【linux LVM 磁盘挂载目录】 创建两个目录 一个 docker 数据存储目录 &#xff1a;/data/docker&#xff0c;默认一般为linux为 /var/lib/d…

boomYouth

周一&#xff1a; 1. action异步写法&#xff1a; <script setup> import sonCom1 from /components/sonCom1.vue import sonCom2 from /components/sonCom2.vue import {useCountStore} from /store/counter import {useChannelStore} from /store/channel const count…

1、nmap常用命令

文章目录 1. 主机存活探测2. 常见端口扫描、服务版本探测、服务器版本识别3. 全端口&#xff08;TCP/UDP&#xff09;扫描4. 最详细的端口扫描5. 三种TCP扫描方式&#xff08;1&#xff09;TCP connect 扫描&#xff08;2&#xff09;TCP SYN扫描&#xff08;3&#xff09;TCP …

PTA-7-55 判断指定字符串是否合法

题目&#xff1a; 输入一个字符串&#xff0c;判断指定字符串是否合法&#xff0c;要求字符串由7个字符组成&#xff0c;并且第一位必须是大写字母&#xff0c;2-4为必须是小写字母&#xff0c;后3为必须是数字字符&#xff0c;要求使用正则表达式来实现。 根据题目要求&#x…

防火墙命令行基础配置实验(H3C模拟器)

嘿&#xff0c;这里是目录&#xff01; ⭐ H3C模拟器资源链接1. 实验示意图2. 要求3. 当前配置3.1 PC配置3.2 FW配置&#xff08;防火墙&#xff09;[^7][^8]3.2.1 FW1配置3.2.2 FW2配置 3.3 R配置3.3.1 R1配置3.3.2 R2配置 3.4 SW配置3.4.1 SW1配置3.4.2 SW2配置3.4.3 SW3配置…