出处:http://blog.csdn.net/euler1983/article/details/5959622

算法优化algorithmgraphtree任务

这篇文章说的是Yuri Boykov and Vladimir Kolmogorov在2004年提出的一种基于增广路径的求解最大流最小割的算法,号称大部分情况下会很快。而且在算完之后,会自动完成最小割集的构造。

作者写了一个C的实现:http://vision.csd.uwo.ca/code/maxflow-v3.01.zip

文章参考:《GRAPH BASED ALGORITHMS FOR SCENE RECONSTRUCTION FROM TWO OR MORE VIEWS》这是作者的博士论文,在最后的一章节里详细提到了这种算法的思路。

这个算法的思路并不难懂,但是看起来有点难度。文中充满了q is children of p之类的表述,看着看着就混淆了。而且代码里的变量命名也很随意,花了3,4天的时间,终于搞定。

算法的直观理解

第一个改进:

首先算法采用了两条增广路径,分别从source和sink出发,边搜索边标号,这样当所有的点都被搜索并标号后,最小割集也就形成了。

所有在最前沿的点称为active node,这些点的任务是去发展新的node。而被active node包围起来的那些点,则称之为passive node。

而没有被发掘出来的点则称之为free node。

第二个改进:

基于增广路径的算法都是遵循:找出一个可行流----》更新残留网络----》然后再找下一个可行流。

此算法需要不断地去找可行流,而每次找都得从源点重新开始进行一个广度遍历或者深度遍历直到找到汇点。这篇文章的算法正是基于此来进行改进。

找到一个可行流后,要进行augmention,然后必然会出现饱和的边,比如这样的一条路中:p1----->p2---->p3----->p4,p2->p3这条边饱和了。如果我们不管他,还是继续遍历去寻找汇点,那么当你再次找到一条路后,那么这条路中就有可能包含一些已经饱和路径,那就没法进行增广了。所以,我们必须要去调整那些饱和的边,使得在已经构建的路径中不存在饱和的边。在本例中,p3称之为orphan(孤点),那么接下来就得做一个adopt orphan的操作,呵呵,名字起得很有意思(养育孤儿),意思就是说给每个p3这样的孤儿点找一个新的parent,养育完就没有orphan存在了。方法如下:

检查p3的neighbors,看看有没有一个neighbor, let's say node q,s.t.

(1). q->p3满足容量大于0

(2). q是已经被搜过的点,也就是说q已经在我们的span tree了,in another word,当我们沿着汇点逆流而上搜索到q时,可以顺利地找到q的father,从而最终可以顺藤摸瓜摸到source上。

(3). 通过q最终能到达source或者sink这样的终点。这是因为有可能顺着q走着走着,最终走到一个free node去了。或者走到一个orphan去了,而这个orphan最终也无人抚养而变成free node。

那么如果找不到这样的q,那么p3就不得不变成free node。然后再做以下两个调整:

(4). 对于p3的邻居pk,如果pk到p3的边(pk-->p3)的容量大于0, 则将pk设为active。

(5). 对于p3的邻居ph,如果p3=parent(ph),那么把ph也设置为orphan,加入到orphan集合里。

这是因为当有一条路从sink走到ph的时候,会发现无路可走了,因为parent(ph)是一个free node!

所以我们必须对ph也做相同的处理,要么找一个新的parent,要么您老人家变成free node,先一边凉快会!

orphan集合中在增广时建立,每次更新一个边后,如果发现改变后的边的残留流量=0,则把边指向的那个点加入orphan set。

在adoption阶段,反复从orphan set中取点,每取出一个孤儿,首先看看能不能找到一个新的parent,如果找不到则令其变成free node,并把他的child变成orphan,加入到orphan集合中。循环往复,直到orphan set = 空集。

细节:

对上述的(3)可以进行优化。

优化一:不必每次要追溯到source/sink才罢休。

因为对于orphan的每一个邻居进行判断其是否originate from TERMINATE node时,都要逆流追溯至source / sink点。那么其中的一些点可能要被追溯多次,那么这是一个重复的操作。如果一个点,已经被证明了,他是可以到达source / sink的,那么下次当有点经过他的时候,他就可以直接告诉该点,OK,哥们歇歇吧,你是valid的,通过我可以追溯到source/sink。这就是在algorithm tunning里提到的mark的意思。

优化二:选择离source/sink最近的那个neighbor,作为orphan的新parent.

要实现这个优化,必须给每个节点附加一个属性:该节点到source/sink的最短距离。

并且在growth阶段,当一个active node q1 遇到另一个active node q2时,要比较一下是否把parent(q2)=q1后,q2到source/sink的距离更短,如果是,那么就调整下q2,使得它变成q1的child。正所谓:

人往高处走,水往低处流,节点都往终点凑!

关于Yuri Boykov and Vladimir Kolmogorov 于2004年提出的max flow / min cut的算法的详解的更多相关文章

  1. vs2015+opencv3.3.1+ maxflow-v3.01 c++实现Yuri Boykov 的Interactive Graph Cuts

    出的结果不理想. 感觉是tlink的权重的计算有问题,以及参数的设置.三个可设置参数是后面的 i j k  .如果你找到了一组好参数请告诉我. 下载地址 http://download.csdn.ne ...

  2. GrabCut in One Cut(基于图割算法grabcut的一次快速图像分割的OpenCV实现)----目前效果最好的图割

     One cut in grabcut(grabcut算法的非迭代实现?) 本文针对交互式图像分割中的图割算法,主要想翻译一篇英文文献.不足之处请大家指正. 这是博主近期看到的效果最好,实现最简单 ...

  3. GraphCuts算法解析,Graphcuts算法求最大流,最小割实例

    图割论文大合集下载: http://download.csdn.net/detail/wangyaninglm/8292305 代码: /* graph.h */ /* Vladimir Kolmog ...

  4. 图像分割之(四)OpenCV的GrabCut函数使用和源码解读

    图像分割之(四)OpenCV的GrabCut函数使用和源码解读         分类:            图像处理            计算机视觉             2013-01-23 ...

  5. 第八节、图片分割之GrabCut算法、分水岭算法

    所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出相似性,而在不同区域间呈现出明显的差异性.我们先对目前主要的图像分割方法做个概述,后面再 ...

  6. 图片分割之GrabCut算法、分水岭算法

    https://www.cnblogs.com/zyly/p/9392881.html 所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出 ...

  7. 两种Python基于OpenCV的固定位置半透明水印去除方案

    1. 基于 inpaint 方法(网上的方法,处理质量较低) 算法理论:基于Telea在2004年提出的基于快速行进的修复算法(FMM算法),先处理待修复区域边缘上的像素点,然后层层向内推进,直到修复 ...

  8. python利用opencv去除水印方法

    OpenCV(Open Source Computer Vision Library)是一个跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法 在python中可以利用opencv来去除 ...

  9. Http协议详解(转)>>>写的很好

    声明:本片文章非原创,仅供自己学习并分享 内容来源于博客园作者MIN飞翔的HTTP协议详解地址http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html ...

随机推荐

  1. markdown绘图插件----mermaid简介

    作者:黄永刚 mermaid简介 当撰写文档的时候,对于流程图的生成大多使用Visio等繁重的工具,没有一种轻便的工具能够画图从而简化文档的编写,就像markdown那样. mermaid解决这个痛点 ...

  2. Swift基础之两种选择星星的评价样式并获取星星的索引值

    想练练手,所以封装了一个两种选择星星的评价样式的Demo,并且可以获取到点击的星星的索引值,方便记录值,上传数据时使用 首先创建View类,设计初始化方法,并且用到了枚举类型和代理方法 方式一:默认的 ...

  3. Android 使用DownloadManager进行版本更新的完整方案

    在Android App都会有版本更新的功能,以前我们公司是用友盟SDK更新功能,自己服务器没有这样的功能.版本检测.Apk下载都是使用友盟.最近看到友盟的版本更新SDK文档:十月份更新功能将会停止服 ...

  4. [Flask]学习杂记一 Hello程序

    这几天买了本  <Flask Web开发:基于Python的Web应用开发实战>,之前也用过flask 但是不怎么系统,有时候需要搭建一些临时的测试服务,用falsk比较方面,一个文件就可 ...

  5. 关于activitygroup过时,用frament替换操作

    现在Fragment的应用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时候,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上, ...

  6. shell的数值计算,小数计算

    shell脚本中,可以进行数值计算, 如加减乘除,通过expr.let.(())等完成,文章介绍:http://blog.csdn.net/longshenlmj/article/details/14 ...

  7. 基于V4L2摄像头采集图片程序设计

    #ifndef __COMMON_H #define __COMMON_H //该头文件定义的是摄像头在屏幕上显示的宽度和高度 #include<stdio.h> #include< ...

  8. 【unix网络编程第三版】阅读笔记(四):TCP客户/服务器实例

    本篇博客主要记录一个完整的TCP客户/服务器实例的编写,以及从这个实例中引发的对僵死进程的处理等问题. 1. TCP客户/服务器功能需求 本实例完成以下功能: (1) 客户从标准输入读入一行文本,并写 ...

  9. 【Android 应用开发】 Android 相关代码规范 更新中 ...

    . 简介 : Android 常用的代码结构, 包括包的规范, 测试用例规范, 数据库模块常用编写规范; 参考 : 之前写的一篇博客 [Android 应用开发] Application 使用分析 ; ...

  10. Caffe框架,图像数据转换成LMDB数据格式

    小码农最近在研究深度学习,对所学知识做点记录,以供以后翻阅.在Caffe框架中,数据的格式都是LMDB的,如何将图像数据转换成这个格式呢? 首先,将图像数据和标签生成txt文档,执行一下代码: fin ...