Graphx图算法【5】连通分量 ConnectedComponents

Graphx的ConnectComponent求解图中的连通体,在图中任意两个顶点之间存在路径可达,则该图是连通图,对应的极大连通子图即该算法要求的连通体。

5.1 简介

Graphx用图中顶点的id来标识节点所属的连通体,同一个连通体的编号是采用该联通体中最小的节点id来标识的。

5.2 算法场景

(一)社交网络的社区发现

(二)测试机器的连通性或进行网络连接的判断

5.3 算法流程

核心思想: 用图中节点的id来表示连通分量,将自身id传递给邻居节点,能够发送消息的必然是在同一个连通分量中。
这里进行消息传送是从将id节点的id发送给有着更大id的节点。这样最后一个联通分支中的所有节点的分支id将会是该分支中最小的节点id。(消息发送不分方向,既可以沿着出边发送也可以沿着入边发送)

计算步骤:

  1. 首先初始化图,将图中顶点id作为顶点的属性,开始状态是每个节点单独作为一个连通分量,分量id是节点id;
  2. 对于每条边,如果边两端节点属性相同(说明两个节点位于同一连通分量中),不需要发送消息,否则将较小的属性发送给较大属性的节点;
  3. 同一个节点对于收到的多个消息,只接收最小的消息;
  4. 节点将自身属性记录的id与收到的消息中的id进行比较,采用最小的id更新自己的属性。
   
  不断迭代上述2,3,4步。

5.4 源码分析

object ConnectedComponents {
  /**
   *  返回图,图中节点的属性是当前连通分量中最小的顶点id
   * */
  def run[VD: ClassTag, ED: ClassTag](graph: Graph[VD, ED],
                                      maxIterations: Int): Graph[VertexId, ED] = {
    require(maxIterations > 0, s"Maximum of iterations must be greater than 0," +
      s" but got ${maxIterations}")

    // 初始化图:将图中顶点的id作为顶点属性
    val ccGraph = graph.mapVertices { case (vid, _) => vid }
    // 边上两个顶点,将id较小的顶点的属性发送给id较大的顶点(使得最终连通分支的id是分支上最小的节点id)
    // 如果边的两个顶点属性相同,则说明已经在同一个连通分支,不需要发送消息
    def sendMessage(edge: EdgeTriplet[VertexId, ED]): Iterator[(VertexId, VertexId)] = {
      if (edge.srcAttr < edge.dstAttr) {
        Iterator((edge.dstId, edge.srcAttr))
      } else if (edge.srcAttr > edge.dstAttr) {
        Iterator((edge.srcId, edge.dstAttr))
      } else {
        Iterator.empty
      }
    }
    // 初始化消息,因为节点在处理消息时接收最小的id更新自己的属性,所以初始时给每个节点发送一个超大的值
    val initialMessage = Long.MaxValue
    val pregelGraph = Pregel(ccGraph, initialMessage,
      maxIterations, EdgeDirection.Either)(
      vprog = (id, attr, msg) => math.min(attr, msg), // 取当前属性和收到消息的最小者更新属性
      sendMsg = sendMessage,
      mergeMsg = (a, b) => math.min(a, b))            // 接收多个消息中的最小者
    ccGraph.unpersist()
    pregelGraph
  } // end of connectedComponents


  def run[VD: ClassTag, ED: ClassTag](graph: Graph[VD, ED]): Graph[VertexId, ED] = {
    run(graph, Int.MaxValue)
  }
}

你可能感兴趣的:(Graphx图算法【5】连通分量 ConnectedComponents)