GPS-Graph Processing System Graph Coloring算法分析 (三)
HamaWhite 原创,转载请注明出处!欢迎大家增加Giraph
技术交流群: 228591158
Graph coloring is the problem of assigning a color to each vertex of an undirected graph such that no two adjacent vertices have the same color. We implement the greedy algorithm from Scalable parallel graph coloring algorithms. The algorithm
iteratively finds a maximal independent set (MIS) of vertices, i.e., a maximal set of vertices such that no pair of vertices are adjacent. The algorithm assigns the vertices in each MIS a new
color, then removes them from the graph, until there are no vertices left in the graph.
注:Maximal Independent Set參考 《找最大独立集问题-Finding a Maximal Independent Set》
1. 顶点状态分为五种:COLORED、IN_SET、NOT_IN_SET、SELECTED_AS_POSSIBLE_IN_SET 和 UNDECIDED。
COLORED:表示已染色;
IN_SET:增加到MIS中;
NOT_IN_SET:至少存在一条边指向 IN_SET 中的顶点。
SELECTED_AS_POSSIBLE_IN_SET:有可能(尝试性)地增加到 IN_SET 中,依据概率来选择。
UNDECIDED:不存在指向 IN_SET 中随意顶点的边,且不在IN_SET中。
2. 消息分为三种类型: NeighborSelectedAsPossibleMessage、RemoveNeighborMessage 和 DecrementNumNeighborsMessage。
3. 顶点的Value有三部分:1) color:存储顶点的颜色,初始为null。2)type:存储顶点的状态。3)numRemainingNeighbors:剩余的出度大小,初始为顶点的出度大小
4. 计算分为五个阶段:MIS_1、MIS_2、MIS_3、MIS_4 和 COLORING。
MIS_1 :选择阶段。仅仅有UNDECIDED 状态的顶点參与。
每一个UNDECIDED 状态的顶点v依照1/(2* degree(v))的概率进入SELECTED_AS_POSSIBLE_IN_SET状态。若顶点的numRemainingNeighbors大于0。则向邻接顶点发送 NeighborSelectedAsPossibleMessage类型的消息,该消息中包括顶点ID。
概率选择详细实现:依据每一个顶点剩余的出度计算出概率。然后产生一随机数。该随机数若小于等于概率,则向邻接顶点发送消息。源代码例如以下:
// NOT_IN_SET和IN_SET状态的顶点不參与计算,直接返回
if (ColoringVertexType.NOT_IN_SET == value.type
|| ColoringVertexType.IN_SET == value.type) {
return;
}
//计算顶点的增加概率
double probability = getNeighborsSize() > 0 ? 1.0 /
((double) 2*value.numRemainingNeighbors) : 1;
//生成的随机数若小于概率,则进入SELECTED_AS_POSSIBLE_IN_SET状态
if (Math.random() <= probability) {
value.type = ColoringVertexType.SELECTED_AS_POSSIBLE_IN_SET;
//后面的MIS_3阶段会降低numRemainingNeighbors的值,此处推断主要是为了降低不必要的消息发送。
//假如顶点u的出度仅仅有v和w,顶点u的numRemainingNeighbors初始值为2.当v和w都进入NOT_IN_SET
//状态时,会向顶点u发送DecrementNumNeighborsMessage消息,在MIS_3阶段会把
//numRemainingNeighbors减为0,此时顶点u就不必向v和w发送消息.
if (value.numRemainingNeighbors > 0) {
ColoringMessage newSelectedAsPossibleMessage = ColoringMessage
.newNeighborSelectedAsPossibleMessage(getId());
for (int neighborId : getNeighborIds()) {
//因后面删除顶点时。仅仅是把neighborId置为-1,并未真正删除.后面发送消息均有推断.
if (neighborId >= 0) {
sendMessage(neighborId, newSelectedAsPossibleMessage);
}
}
}
}
MIS_2 :冲突解决阶段,仅仅有SELECTED_AS_POSSIBLE_IN_SET状态的顶点參与。顶点接受MIS_1阶段发送的NeighborSelectedAsPossibleMessage消息,若顶点 v 收到的顶点ID都比顶点v自身大。则顶点v进入IN_SET状态。然后向邻接顶点发送removeNeighborMessage 消息(包括顶点ID),告诉邻接顶点删除指向该顶点的边;否则。v 又一次置为 UNDECIDED状态。
代码例如以下:
//仅仅有SELECTED_AS_POSSIBLE_IN_SET状态的顶点參与
if (ColoringVertexType.SELECTED_AS_POSSIBLE_IN_SET != value.type) {
break;
}
for (ColoringMessage message : messageValues) {
//收到的消息值若比自身的VertexId小,则置为UNDECIDED状态。
if (message.int1 < getId()) {
value.type = ColoringVertexType.UNDECIDED;
//numEdgesOfPotentiallyActiveVertices是为了推断找一个MIS
//是否结束(由Master全局推断)
numEdgesOfPotentiallyActiveVertices.value += getNeighborsSize();
return;
}
}
//收到的顶点ID都比自身大,则该顶点进入IN_SET状态,然后向邻接顶点
//发送removeNeighborMessage消息(消息包括顶点ID)
setValueToInSetAndNotifyNeighbors();
private void setValueToInSetAndNotifyNeighbors() {
for (int neighborId : getNeighborIds()) {
if (neighborId >= 0) {
sendMessage(neighborId, ColoringMessage.removeNeighborMessage(getId()));
}
}
value.type = ColoringVertexType.IN_SET;
}
MIS_3 :NOT_IN_SET发现和度数调整-1阶段。IN_SET状态的顶点不參与,UNDECIDED状态和NOT_IN_SET状态的顶点收到RemoveNeighborMessage 消息后删除指向IN_SET状态顶点的边。
UNDECIDED状态的顶点进入NOT_IN_SET状态,然后向邻接顶点发送DecrementNumNeighborsMessage消息(不包括顶点ID)。
//IN_SET状态的顶点不參与
if (ColoringVertexType.IN_SET == value.type) {
return;
}
//删除指向IN_SET顶点的边,并把UNDECIDED状态的顶点置为NOT_IN_SET
removeNeighborsAndPossiblySetTypeToNotInSet(messageValues);
private void removeNeighborsAndPossiblySetTypeToNotInSet(Iterable<ColoringMessage> messageValues) {
if (messageValues.iterator().hasNext()) {
//NOT_IN_SET和UNDECIDED状态的顶点删除指向IN_SET顶点的边
removeNeighbors(messageValues);
//把UNDECIDED状态的顶点置为NOT_IN_SET状态。并向邻接顶点发送DecrementNumNeighborsMessage
if (value.type == ColoringVertexType.UNDECIDED) {
value.type = ColoringVertexType.NOT_IN_SET;
for (int neighborId : getNeighborIds()) {
if (neighborId >= 0) {
sendMessage(neighborId,
ColoringMessage.newDecrementNumNeighborsMessage());
}
}
}
}
}
private void removeNeighbors(Iterable<ColoringMessage> messageValues) {
removedNeighbors.clear();
for (ColoringMessage message : messageValues) {
removedNeighbors.add(message.int1);
}
int numNeighborsRemoved = 0;
int neighborIdIndex = 0;
for (int neighborId : getNeighborIds()) {
if (neighborId >= 0 && removedNeighbors.contains(neighborId)) {
numNeighborsRemoved++;
//并未真正删除。仅仅是把邻接顶点的值改动为-1
relabelIdOfNeighbor(neighborIdIndex, -1);
}
neighborIdIndex++;
}
//降低numRemainingNeighbors的值
value.numRemainingNeighbors -= numNeighborsRemoved;
}
MIS_4 :度数调整-2阶段。仅仅有UNDECIDED 状态的顶点參与。每一个UNDECIDED 状态的顶点把自己的numRemainingNeighbors降低收到的消息数目。
假设还有UNDECIDED顶点,Master会告诉有Worker进入MIS_1 阶段。进行迭代;否则。一个MIS构造完毕,Master通知全部Worker进入COLORING 阶段。
思考:进入IN_SET状态的顶点。会发送removeNeighborMessage 消息给邻接顶点。邻接顶点无论是NOT_IN_SET还是UNDECIDED状态,都会删除指向IN_SET顶点的边,即IN_SET顶点已处理完,无需与外界联系。
某顶点进入NOT_IN_SET状态时,会告诉自己邻接的UNDECIDED顶点降低自己的 numRemainingNeighbors值(而不是删除),在下次迭代的MIS_1阶段,若顶点的numRemainingNeighbors小于0。说面其邻接顶点都进入NOT_IN_SET状态,无需向邻接顶点发送消息,降低了消息传递量。
if (ColoringVertexType.IN_SET == value.type
|| ColoringVertexType.NOT_IN_SET == value.type) {
return;
}
for (ColoringMessage message : messageValues) {
value.numRemainingNeighbors--;
}
COLORING :染色阶段。
进入此阶段已没有UNDECIDED状态的顶点。故仅仅有IN_SET和NOT_IN_SET状态的顶点參与。IN_SET状态的顶点染色。变成Inactive状态。
把全部NOT_IN_SET状态的顶点置为UNDECIDED状态。并又一次计算numRemainingNeighbors值。
if (value.type == ColoringVertexType.IN_SET) {
value.color = latestColor;
value.type = ColoringVertexType.COLORED;
removeEdges();
voteToHalt();
} else {
value.type = ColoringVertexType.UNDECIDED;
//GOBJ_NUM_NOT_COLORED_VERTICES用于推断染色是否结束
getGlobalObjectsMap().putOrUpdateGlobalObject(ColoringOptions.GOBJ_NUM_NOT_COLORED_VERTICES,
new IntSumGlobalObject(1));
getGlobalObjectsMap().putOrUpdateGlobalObject(
ColoringOptions.GOBJ_NUM_EDGES_OF_NOT_COLORED_VERTICES,
new IntSumGlobalObject(value.numRemainingNeighbors));
value.numRemainingNeighbors = countNumRemainingNeighbors();
}
完!
GPS-Graph Processing System Graph Coloring算法分析 (三)的更多相关文章
- 《Wonderland: A Novel Abstraction-Based Out-Of-Core Graph Processing System》章明星
在2018年3月28日于美国弗吉尼亚州威廉斯堡结束的ACM ASPLOS 2018会议上,计算机系高性能所师生发表了两篇长文.一篇是我系博士生章明星为第一作者,导师武永卫为通讯作者的“Wonderla ...
- 转债---Pregel: A System for Large-Scale Graph Processing(译)
转载:http://duanple.blog.163.com/blog/static/70971767201281610126277/ 作者:Grzegorz Malewicz, Matthew ...
- Pregel: A System for Large-Scale Graph Processing(译)
[说明:Pregel这篇是发表在2010年的SIGMOD上,Pregel这个名称是为了纪念欧拉,在他提出的格尼斯堡七桥问题中,那些桥所在的河就叫Pregel.最初是为了解决PageRank计算问题,由 ...
- 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (三)
本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolutio ...
- GPS-Graph Processing System 改动源代码经验总结 (四)
HamaWhite原创,转载请注明出处.欢迎大家增加Giraph 技术交流群: 228591158 本文目的:在改动GPS源代码后,具体描写叙述怎样编译和分发到各Worker节点上. 以下以Graph ...
- 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一)
本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolutio ...
- ORA-01078:failure in processing system parameters
一.使用环境操作系统:rhel 6.5 x64数据库:Oracle 11.2.0.1.0数据库主目录:/u01/app/oracle/product/11.2.0/ 二.问题描述用sys用户登录sql ...
- 启动Oracle时提示:ORA-01078:failure in processing system parameters
一.使用环境操作系统:CentOS release 6.2 (Final) 数据库:Oracle 12g数据库主目录:/ora12/product/product/12.1.0/db_1 二.问题描述 ...
- 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (二)
本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolutio ...
随机推荐
- google Chrome打开多个网站时等待可用的套接字,怎么加大连接数量提升速度
这是因为Chrome对同一个域名的sockets连接数作了限制,或者你访问的网站经常被墙的原因.打开Chrome的Sockets:chrome://net-internals/#sockets 点击里 ...
- Shiro官方快速入门10min例子源码解析框架1-初始化
Shiro,一个易用的Java安全框架,主要集合身份认证.授权.加密和session管理的功能. 这系文章主要简介Shiro架构,并通过官方的quickstart例程分析最简实现下Shiro的工作流程 ...
- eclipse中编写运行c/c++
注意:此过程有点复杂 准备:1.MinGW:c/c++运行环境: 2.CDT 1.MinGW:安装程序:http://sourceforge.net/projects/mingw/?source=ty ...
- Dubbo 体验(一)
最近新加入一个项目组,所使用的是Dubbo,采用的架构是分布式架构,数据库采用MySQL分片.之前也接触过一下,但为了能更好融入团队,所以找Dubbo官网看文档. 才发现Dubbo的官网已搬去apac ...
- 理解webpack4.splitChunks之cacheGroups
cacheGroups其实是splitChunks里面最核心的配置,一开始我还认为cacheGroups是可有可无的,这是完全错误的,splitChunks就是根据cacheGroups去拆分模块的, ...
- Django请求生命周期之响应内容
Django请求生命周期: 1.发送http请求2.服务器接受,根据请求头中的url在路由关系表中进行匹配(从上到下)3.匹配成功后,执行指定的views函数 URL -> 函数 ==>F ...
- 【源代码R3】移植一份LARGE_INTEGER转时间的代码
本代码来自ReactOS-0.4.0\lib\rtl\time.c中的函数RtlTimeToTimeFields(IN PLARGE_INTEGER Time, OUT PTIME_FIELDS Ti ...
- 基于Vue的WebApp项目开发(六)
实现商品购买列表页面 步骤一:新建goodslist.vue文件 <template> <div id="tml"> <!--利用mui中的图文表格组 ...
- php foreach 报 “Cannot create references to elements of a temporary array expression”
今天在项目中用php foreach数据库查询结果时,为了方便没有判断数据是否存在,直接用(array)强制转换数据时,刚开始网页始终打不开,就报502,一头懵,突然间php报“Cannot crea ...
- GitHub初步探索-1-使用本地代码管理工具,简化上传的过程
使用GitHub对于我们写Java的同志们来说是一个非常好的代码存储的方式,但是因为是全英文的,操作起来有一点复杂,所以我不是经常使用 ,但是最近代码越敲越多,再加上老师要求,希望使用比较简单的方法来 ...