出处: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. Git之(五)远程管理

    开篇就提到过,Git是一个分布式版本管理系统.但是到现在为止,我们所有的演练都是在本地Git仓库.如果想与他人合作,还需要一个远程的 Git 仓库.尽管技术上可以从个人的仓库里推送和拉取修改内容,但我 ...

  2. post插件

    分享牛系列,分享牛专栏,分享牛.在项目开发中,http请求方式是最常见的了.怎么模拟http请求呢?方法有很多种,可以使用httpclient直接模拟请求,也可以使用火狐post插件方式,这个章节主要 ...

  3. 使用Dialog实现全局Loading加载框

    Dialog实现全局Loading加载框 很多人在实现Loading加载框的时候,都是在当前的页面隐藏一个Loading布局,需要加载的时候,显示出来,加载完再隐藏 使用Dialog实现Loading ...

  4. NSDictionary writeToFile:atomically: 时失败

    一.现象:如下图,当NSDictionary调用 writeToFile:atomically: 时,如果容器里面包含的对象(即通过 objectForKey: 拿到的对象),为非property l ...

  5. activiti 动态配置 activiti 监听引擎启动和初始化(高级源码篇)

    1.1.1. 前言 用户故事:现在有这样一个需求,第一个需求:公司的开发环境,测试环境以及线上环境,我们使用的数据库是不一样的,我们必须能够任意的切换数据库进行测试和发布,对数据库连接字符串我们需要加 ...

  6. actionbar详解(二)

    经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对较为深刻的理解了.唯一欠缺的是,前面我们都只是学习了理论知识而已,虽然知识点已经掌握了,但是真正投入到项目实战当中时会不会掉链子还很 ...

  7. [ExtJS5学习笔记]第二十七节 CMD打包错误 Error C2009: YUI Parse Error (identifier is a reserved word => debugger;)

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/41242993 本文作者:sushengmiyan ------------------ ...

  8. Struts 1 之配置文件

    web.xml中配置Struts的入口Servlet--ActionServlet,ActionServlet不负责任何的业务处理,它只是查找Action名单,找到path属性与URL属性一致的Act ...

  9. 一个简单程序快速入门JDBC

    首先创建jdbc的库,再在这个库里面创建一张users表. drop database if exists jdbc; create database if not exists jdbc; use ...

  10. iOS隐藏键盘的几种方式

    因为开发中经常要用到textField和textView,在某些情形下隐藏键盘很有必要,而隐藏键盘有多种方式,在合适的场景下用合适的方式隐藏就显得很重要,我也老是记不起来有哪些方法,这里就记录一下,以 ...