分布式找环算法

分布式找环算法

参考

https://www.researchgate.net/publication/283642998_Distributed_cycle_detection_in_large-scale_sparse_graphs

  1. 从每个起点出发,将自己身上的id发给邻居;
  2. 将自己上一轮收到的点id并加上自己的点id,将此路径继续发送给邻居;
  3. 不断的将上一轮收到的路径加上自己的点id,将此路径继续发送给邻居;
  4. 每一轮中,没有收到路径的节点,将此节点删除;
  5. 当某一点收到的路径中包含自己的id,则判断此点id是否为路径中的最小值,若是,则计一环;
  6. 当某一点收到的路径中包换自己的id,此路径就会被砍掉,不再继续传递。

paper

参考这篇分布式找环算法的论文,其中主要方法是用 bfs 把每个点当前点存储的路径发送给邻居,在分布式的情况下需要通过文件传输给邻居。主要针对的是稀疏图,所以对我们资金链路图(点:边=1:1000)、社交图(1:30)并不合适,并且此方法会造成环重复记录。通过此论文,我们进行一些改进找到适合的方式进行找环。

剪枝方式

避免在找环过程中走了重复的路径,所以在论文的基础上,提出了一些剪枝的方式。

拓扑排序

假如点的出度或者入度为0,则此点肯定不能成环,所以可以将这类点从起点中排除掉,因此在去掉此点的过程中也会出现新的出度或入度为0的点。可以迭代将此类点都去掉。

拓扑排序

起点id最小

由于每个点都会作为起点,并且每个环都会被环上的每个点找一遍,所以就会造成重复找环的问题。

可以采用当起点出发,每传递到下一个节点的时候,就判断是否起点比当前点小,如果不是,则这条路径砍掉。按照这样子的方式最后找到的环就会是此环上id最小的点找到的。

起点id最小

起点的前驱id比起点id大

在上条起点id最小的情况下,其实走到最后一步是不允许起点的前驱id比起点id小,所以与其走到最后一步判断出来,可以提前在选起点的时候就先判断起点的前驱,这样子可以排除掉一些起点,提高效率。

起点的前驱id比起点大

此方法不能以起点就作为环上的一点,不然会丢失一些环。

起点不一定在环上

因此遇到与路径中有相同点的时候,即成环,会有一些重复记录的环。

重复情况

优点:减少起点的个数,提高效率

缺点:无法判断成环是否唯一,所以会重复计环

算法执行

结合以上三种剪枝方式,可按照bfsdfs实现找环

BFS

传路径

按照论文中的方法结合以上三种剪枝方式,传路径属于容易理解且好实现的方法,但是问题在于每次存储的路径量为n*e^d(n:起点个数、e:平均边数、d:深度),会随着找环深度,路径会时平均边数的指数倍增加。因此此方法适合平均边数小于等于1的稀疏图。

在1400点 196w边的图中(2台128g的机器)进行分布式执行,其中按照拓扑排序过滤掉185个起点

根据以下结果可以看出到深度为4时,存储量就过大导致程序无法执行。

深度 过程文件大小 总环数 时间
2 1MB 6.1w 1.5s
3 343MB 1270w 86s
4 75GB
传起点

传起点会大大减少存储和传输的量,此方法适用于记录每个点的成环个数,被短路的环不会被记录在内。

在1400点 196w边的图中(2台128g的机器)进行分布式执行,其中按照拓扑排序过滤掉185个起点

根据以下结果可以看出到深度为4时,由于被短路的问题,使其环数已达到平稳

深度 环数最多的点id 环数最多的点的环数 时间
2 1275 600 10s
3 937 3.44w 43s
4 937 3.45w 48s
5 937 3.45w 48s

DFS

按照dfs的方式并结合以上三种剪枝方式,每次只存储当前的路径,执行完成之后再回退,所以不会造成存储和传输上的压力,但是轮次也会随着边的数量而增加,尤其是在分布式的情况下,每执行一个点就要去传输一次文件,会造成大量小文件并发传输,端口不足,效率比bfs低。

发布了9 篇原创文章 · 获赞 11 · 访问量 916

猜你喜欢

转载自blog.csdn.net/superice_/article/details/103963732