笔者:白松 NPU学生。

转载请注明出处:http://blog.csdn.net/xin_jmail/article/details/32101483

本文參加了2014年CSDN博文大赛,假设您认为此文对您有所帮助。就请为我投上您宝贵的一票,不胜感激。

投票地址:http://vote.blog.csdn.net/Article/Details?articleid=32101483 

本文目的:解说并行Finding a Maximal Independent Set(寻找最大独立集问题)算法,以及在Hama平台上怎样实现该算法。该算法可方便移植到全部的Pregel-Like系统中,如Giraph、GPS (Graph Processing System)。

前言:关于Maximal Independent Set(MIS)的基础知识參考我的博客《找最大独立集问题-Finding a Maximal Independent Set》。

1. 本算法參考 Luby's classic parallel algorithm《a simple parallel algorithm for maximal independent set problem》,把顶点分为三类:

1) S:The MIS being constructed. Starts empty and grows in iterations.

     2) NotInS: Vertices that have at least one edge to a vertex in S and as a result cannot be in S.

     3) Unknown: Vertices that do not have an edge to any vertex in S but are not yet in S.

2. Hama平台下 MIS算法描写叙述。

初始时,全部顶点都在UnKnown集合中。

算法例如以下:

    1) UnKnown集合中的每一个顶点向邻接顶点发送自己的VertexID。

    2) 若顶点u的VertexID比自己全部邻接顶点都小,则该顶点进入 S 集合中,并发送neighbor-in-set 消息给全部           邻接顶点。通知它们退出Unknown集合进入到NotInS集合中,并最后把u置为InActive状态。否则。顶点u继            续保持UnKnown状态。 

    3) S集合中顶点的邻接顶点收到neighbor-in-set 消息。则该顶点进入NotInS。而且 become Inactive。回到步骤         1继续迭代,直到UnKnown集合为空。

算法分析:上述每一个步骤都是一个SuperStep,步骤间须要一次全局同步。

步骤3是收到neighbor-in-set 消息的UnKnown顶点进入NotInS集合中,而未进入NotInS集合的UnKnown顶点在下一轮迭代的步骤1向邻接顶点发送自己的VertexID。

两者互不影响,因此从能够把步骤3和步骤1合并,以此来降低全局同步次数。

3. 算法实现和源代码。

程序中依照顶点value取值不同来区分顶点的类别,关系例如以下:

1) value 等于 vertexID ,表示顶点在 Unknown 集合中;

    2) value 等于 -1 ,表示顶点在 S 集合中

    3) value 等于 -2 ,表示顶点在 NotInS 集合中。

当全部顶点进入S或者NotInS集合中(即没有 Unknown 顶点),就停止计算,表明已找到一个 MIS。源代码例如以下:

  1. package graph.mis;
  2.  
  3. import java.io.IOException;
  4. import java.util.Iterator;
  5.  
  6. import org.apache.hadoop.conf.Configuration;
  7. import org.apache.hadoop.fs.Path;
  8. import org.apache.hadoop.io.LongWritable;
  9. import org.apache.hadoop.io.NullWritable;
  10. import org.apache.hadoop.io.Text;
  11. import org.apache.hama.HamaConfiguration;
  12. import org.apache.hama.bsp.HashPartitioner;
  13. import org.apache.hama.bsp.TextInputFormat;
  14. import org.apache.hama.bsp.TextOutputFormat;
  15. import org.apache.hama.graph.Edge;
  16. import org.apache.hama.graph.GraphJob;
  17. import org.apache.hama.graph.Vertex;
  18. import org.apache.hama.graph.VertexInputReader;
  19.  
  20. /**
  21. * 目的:找到一个MIS。
  22. *
  23. * 方法:使用Luby's classic parallel algorithm,该算法把顶点分为三类:
  24. * 1) S:The MIS being constructed. Starts empty and grows in iterations.
  25. * 2) NotInS: Vertices that have at least one edge to a vertex in S and as
  26. * a result cannot be in S.
  27. * 3) Unknown: Vertices that do not have an edge to any vertex in S
  28. * but are not yet in S.
  29. *
  30. * 说明:程序中依照顶点value取值不同来区分顶点的类别,关系例如以下:
  31. * 1) value 等于 vertexID ,表示顶点在 Unknown 集合中。
  32. * 2) value 等于 -1 ,表示顶点在 S 集合中
  33. * 3) value 等于 -2 ,表示顶点在 NotInS 集合中。
  34.  
  35. * 当全部顶点进入S或者NotInS集合中(即没有 Unknown 顶点),就停止计算,表明已找到一个 MIS。
  36.  
  37. *
  38. *
  39. * @author 西工大-白松 (HamaWhite的博客)。2014-6-18
  40. *
  41. */
  42. public class FindMIS {
  43.  
  44. /**
  45. * VertexID设置为LongWritable是为处理上百亿的顶点.
  46. */
  47. public static class MISVertex extends
  48. Vertex<LongWritable, NullWritable, LongWritable> {
  49.  
  50. @Override
  51. public void compute(Iterator<LongWritable> messages) throws IOException {
  52. if (getSuperstepCount() == 0) {
  53. //初始第0个超步,把全部顶点的value值赋值为自己的vertexID,
  54. //表明初始全部顶点均在 UnKnown 集合中。
  55. setValue(getVertexID());
  56. //把自己的VertexID发送给邻接顶点
  57. sendMessageToNeighbors(getValue());
  58. } else {
  59. /**
  60. * 若 NotInS 集合中。则voteToHalt。
  61. * 解释:若NotInS集合中的某个顶点u的邻接顶点v在 Unknown集合中,则v会向u发送消息.
  62. * 这样u就会接到消息,被系统自己主动激活进入Active状态。若此处不做处理将会导致一直
  63. * 有活跃顶点,迭代就不会停止。
  64. */
  65.  
  66. if(getValue().get()==-2) {
  67. voteToHalt();
  68. } else {
  69. /**
  70. * recMsg用来表示顶点是否收到消息。
  71.  
  72. 该算法中存在两种消息:
  73. * (1) UnKnown集合中的顶点向邻接顶点发送,寻找顶点进入 S 中。
  74. * (2) S集合中的顶点向邻接顶点发送,通知邻接顶点进入 NotInS 集合中。
  75. *
  76. * 若某个顶点没收到消息,说明该顶点是在 UnKnown集合中。须要向外发送消息寻找。
  77. */
  78. boolean revMsg = false; //标记是否收到消息
  79. while (messages.hasNext()) {
  80. revMsg = true;
  81. long msg = messages.next().get();
  82. if (msg == -2) {
  83. //收到消息-2。表示该顶点的某个邻接顶点已进入 S 集合,
  84. //该顶点须要进入 NotInS集合中,而且voteToHalt
  85. setValue(new LongWritable(-2));
  86. voteToHalt();
  87. return;
  88. } else if (msg < getValue().get()) {
  89. //若收到的vertexID比自己大,说明该顶点不能进入 S
  90. //继续保持 UnKnown状态,參与下次迭代。
  91. return;
  92. }
  93. }
  94. if (revMsg) {
  95. //说明自身vertexID比全部邻接顶点都小。则进入 S 集合中。
  96. setValue(new LongWritable(-1)); //进入 S 集合中
  97. //用消息-2 通知自己的邻接顶点进入 NotInS 集合中
  98. sendMessageToNeighbors(new LongWritable(-2));
  99. voteToHalt(); //置为 InActive,不參与兴许计算
  100. } else {
  101. // UnKnown集合中的顶点。向外发送消息寻找顶点进入S中。
  102. sendMessageToNeighbors(getValue());
  103. }
  104. }
  105. }
  106. }
  107. }
  108.  
  109. /**
  110. * 解析输入格式,以\t间隔的邻接表形式,每行表示一个顶点.如:
  111. * 1\t2\t3
  112. * 2\t1
  113. * 3\t2
  114. * @author root
  115. *
  116. */
  117. public static class MISTextReader extends
  118. VertexInputReader<LongWritable, Text, LongWritable, NullWritable, LongWritable> {
  119.  
  120. @Override
  121. public boolean parseVertex(LongWritable key, Text value,
  122. Vertex<LongWritable, NullWritable, LongWritable> vertex)
  123. throws Exception {
  124. String[] split = value.toString().split("\t");
  125. for (int i = 0; i < split.length; i++) {
  126. if (i == 0) {
  127. vertex.setVertexID(new LongWritable(Long.parseLong(split[i])));
  128. } else {
  129. vertex.addEdge(new Edge<LongWritable, NullWritable>(
  130. new LongWritable(Long.parseLong(split[i])), null));
  131. }
  132. }
  133. return true;
  134. }
  135. }
  136.  
  137. public static void main(String[] args) throws IOException,
  138. InterruptedException, ClassNotFoundException {
  139. if (args.length < 2) {
  140. System.err.println("Usage: <input> <output>");
  141. System.exit(-1);
  142. }
  143.  
  144. HamaConfiguration conf = new HamaConfiguration(new Configuration());
  145. GraphJob pageJob = new GraphJob(conf, FindMIS.class);
  146. pageJob.setJobName("Find a MIS");
  147.  
  148. pageJob.setMaxIteration(30);
  149. pageJob.setVertexClass(MISVertex.class);
  150. pageJob.setInputPath(new Path(args[0]));
  151. pageJob.setOutputPath(new Path(args[1]));
  152.  
  153. pageJob.setVertexIDClass(LongWritable.class);
  154. pageJob.setVertexValueClass(LongWritable.class);
  155. pageJob.setEdgeValueClass(NullWritable.class);
  156.  
  157. pageJob.setInputKeyClass(LongWritable.class);
  158. pageJob.setInputValueClass(Text.class);
  159. pageJob.setInputFormat(TextInputFormat.class);
  160. pageJob.setVertexInputReaderClass(MISTextReader.class);
  161. pageJob.setPartitioner(HashPartitioner.class);
  162. pageJob.setOutputFormat(TextOutputFormat.class);
  163. pageJob.setOutputKeyClass(Text.class);
  164. pageJob.setOutputValueClass(LongWritable.class);
  165. pageJob.waitForCompletion(true);
  166. }
  167. }

4. 执行过程分析。输入为无向图,測试图例如以下:

以下分析S集合中的顶点用红色标注。NotInS集合用灰色,UnKnown集合用白色标注。S集合和NotInS集合中的顶点均是InActive状态。UnKnown集合中的顶点是Active状态。

(1) 步骤1:在SuperStep 0。每一个顶点把自己的VertexID发送给邻接顶点,,如顶点1发送消息1到顶点2、13、7;顶点2发送消息2到顶点1、9、13。顶点15发送消息15到顶点9和14。其它顶点类似。

(2)步骤2:在SuperStep 1,每一个顶点收到邻接顶点发送的消息,如顶点1收到消息2、13、7,;顶点2收到消息1、13、9。顶点0收到消息3、6、7、9、13。

仅仅有顶点0、1、4、5比邻接顶点都小,故该四个顶点进入S 集合。用红色标注。

其它顶点继续在UnKnown集合中。

(3).步骤3和步骤1(步骤1属于第二轮), 在SuperStep2中,顶点0、1、4、5的邻接顶点收到neighbor-in-set 消息(源代码中用-2表示)进入NotInS集合中。即顶点2、13、7、3、10、6、8、11、12、9共10个顶点进入NotInS集合中,变为InActive状态。同一时候顶点14和15依旧是UnKnown状态,14和15分别向邻接顶点发送消息,顶点14向6、12、15发送消息(15)。顶点15向9、14发送消息。

(4) .步骤2(第二轮):在SuperStep 3中,NotInS集合中的顶点6、9和12收到消息后被系统自己主动激活变为Active状态。所以程序中对此情况有所处理。把顶点6、9、12直接置为Inactive状态,不做兴许处理。

顶点14收到消息15比自身大。则14进入S集合中。而顶点15则相反继续在UnKnown集合中。顶点14向邻接顶点6、12、15发送neighbor-in-set消息。

(5) 步骤3(第二轮):在SuperStep 4中。顶点6和顶点12同(4)步处理同样。顶点15收到neighbor-in-set 消息后进入 NotInS集合中。因为UnKnown集合中已没有顶点。不会再向外发送消息。

(6) SuperStep 5中,发现已没有活跃顶点且没有消息在传递。故结束计算。

5. 实验结果。

执行结果例如以下:

HDFS的输出结果例如以下(-2表示NotInS,-1表示在S集合中):

8            -2

10          -2

12          -2

14          -1

0            -1

2            -2

4            -1

6            -2

9            -2

11          -2

13          -2

15          -2

1            -1

3            -2

5            -1

7            -2

本文參加了2014年CSDN博文大赛。假设您认为此文对您有所帮助。就请为我投上您宝贵的一票。不胜感激。

投票地址:

articleid=32101483">http://vote.blog.csdn.net/Article/Details?articleid=32101483 

完!

版权声明:本文博客原创文章,博客,未经同意,不得转载。

基于Hama并联平台Finding a Maximal Independent Set 设计与实现算法的更多相关文章

  1. 软工之词频统计器及基于sketch在大数据下的词频统计设计

    目录 摘要 算法关键 红黑树 稳定排序 代码框架 .h文件: .cpp文件 频率统计器的实现 接口设计与实现 接口设计 核心功能词频统计器流程 效果 单元测试 性能分析 性能分析图 问题发现 解决方案 ...

  2. C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理

    在现今很多网站里面,都使用了微信开放平台的扫码登录认证处理,这样做相当于把身份认证交给较为权威的第三方进行认证,在应用网站里面可以不需要存储用户的密码了.本篇介绍如何基于微信开放平台的扫码进行网站的登 ...

  3. 基于 Node.js 平台,快速、开放、极简的 web 开发框架。

    资料地址:http://www.expressjs.com.cn/ Express 基于 Node.js 平台,快速.开放.极简的 web 开发框架. $ npm install express -- ...

  4. 基于微信公众平台的开发(清华大学第二讲)_Alien的笔记

    基于微信公众平台的开发(清华大学第二讲)_Alien的笔记 基于微信公众平台的开发(清华大学第二讲)

  5. IOS基于新浪微博开放平台微博APP

    1.基于新浪微博开放平台APP源码 2.gitHub源代码下载地址 https://github.com/whzhaochao/SinaWeiBoOpen 3.用到的第三放开源库 3.1  RTLab ...

  6. 亚马逊AWS在线系列讲座——基于AWS云平台的高可用应用设计

    设计高可用的应用是架构师的一个重要目标,可是基于云计算平台设计高可用应用与基于传统平台的设计有很多不同.云计算在给架构师带来了很多新的设计挑战的时候,也给带来了很多新的设计理念和可用的服务.怎样在设计 ...

  7. 分享一下我的部分毕设内容:基于Windows Phone平台的污染源管理应用

    原文:分享一下我的部分毕设内容:基于Windows Phone平台的污染源管理应用 毕业半年,又总结了一下之前的工作,发现很多知识不复习都忘记了.最近新闻总是报道北京的空气污染,各种雾霾,各种PM X ...

  8. KoaHub.js是基于 Koa.js 平台的 Node.js web 快速开发框架

    koahubjs KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Function, Class, A ...

  9. 基于 Koa.js 平台的 Node.js web 快速开发框架KoaHub.js demo 可安装

    KoaHub.js demo KoaHub.js KoaHub.js -- 基于 Koa.js 平台的 Node.js web 快速开发框架.可以直接在项目里使用 ES6/7(Generator Fu ...

随机推荐

  1. 1.网络工具:ifconfig,ping,netstate,Redhat命令和图形化设置ip,finger,nslookup

     1 ip ad查看网卡编号 2.ifconfig查看网卡信息 3.关闭网卡 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcX ...

  2. 文件搜索神器 Everything

    Everything 是一款 NTFS 磁盘格式下的文件搜索工具,1月5日发布测试版本 1.3.0.631b Beta,增加文件列表.收藏夹.自定义快捷键.高级搜索等功能,取消了比较实用的 etp/f ...

  3. Visual Studio 2012中使用Zen Coding,写html的神器!

    点工具 -扩展和更新的联机库中 找到以下俩插件 安装后重新启动 新建一个html文件.将下行代码拷贝到页面里. div>(header>div)+(section>ul>li. ...

  4. ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...

  5. ACdream: ACfun

    ACfun Time Limit: 2000/1000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisti ...

  6. CocoStudio学习资源

    CocoStudio安装包及实例project:http://www.cocoachina.com/bbs/read.php?tid=154886 CocoStudio视频教程系列:http://mo ...

  7. HDU 3415 Max Sum of Max-K-sub-sequence(单调队列)

    转载请注明出处:http://blog.csdn.net/u012860063 Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java ...

  8. SQL SERVER中XML查询:FOR XML指定PATH

    SQL SERVER中XML查询:FOR XML指定PATH 前言 在SQL SERVER中,XML查询能够指定RAW,AUTO,EXPLICIT,PATH.本文用一些实例介绍SQL SERVER中指 ...

  9. Chrome 扩展 最近的历史 HistoryBar v1.1

    说明 以前用过一段时间傲游浏览器,渐渐的习惯了它的鼠标手势和一些细微的人性化的功能.比方地址栏左边的"近期訪问的页面"button.能够方便的找到近期 20 条历史记录. wate ...

  10. C语言求素数的算法

    前言 最后一次是出了素数的问题C语言解决题目(面试),当时用了最粗暴的算法.回来细致參考资料,事实上答案有非常多种: 1,小学生版本号: 推断 x 是否为质数,就从 2 一直算到 x-1. stati ...