美文网首页大数据Spark在简书
Graphx图算法【1】三角形TriangleCount

Graphx图算法【1】三角形TriangleCount

作者: 汤圆毛毛 | 来源:发表于2019-10-29 09:21 被阅读0次

Graphx的数三角形算法TriangleCount用于统计每个顶点所在的三角形个数。

1.1 简介

对网络图中进行三角形个数计数可以根据三角形数量反应网络中的稠密程度和质量。

1.2 应用场景

(一)用于社区发现

如微博中你关注的人也关注你,大家的关注关系中有很多三角形,说明社区很强很稳定,大家联系比较紧密;如果一个人只关注了很多人,却没有形成三角形,则说明社交群体很小很松散。

(二)衡量社群耦合关系的紧密程度

通过三角形数量来反应社区内部的紧密程度,作为一项参考指标。

1.3 算法思路

计算规则:

如果一条边的两个顶点有共同的邻居,则这三个点构成三角形。

计算步骤:

   1.  为每个节点计算邻居集合
   2.  对于每条边,计算两端节点邻居集合的交集,将交集中元素个数告知两端节点,
       该个数即对应着节点关联的三角形数。
   3.  对每个节点合并三角形数目统计总数,由于三角形中一个顶点关联两条边,所以
       对于同一个三角形而言,一个顶点计算了两次,故最终结果需要除以2。

1.4 源码解析


object TriangleCount {

  def run[VD: ClassTag, ED: ClassTag](graph: Graph[VD, ED]): Graph[Int, ED] = {
    // Transform the edge data something cheap to shuffle and then canonicalize
    //得到的是一个无自连边且无重复边的、边是从小id指向大id的图
    val canonicalGraph = graph.mapEdges(e => true).removeSelfEdges().convertToCanonicalEdges()
    // Get the triangle counts
    val counters = runPreCanonicalized(canonicalGraph).vertices
    // Join them bath with the original graph
    graph.outerJoinVertices(counters) { (vid, _, optCounter: Option[Int]) =>
      optCounter.getOrElse(0)
    }
  }


  def runPreCanonicalized[VD: ClassTag, ED: ClassTag](graph: Graph[VD, ED]): Graph[Int, ED] = {
    // 构建邻居集合
    val nbrSets: VertexRDD[VertexSet] =
      // 收集邻居节点,边方向为Either,保证点的入边和出边连接的邻居点都会被收集
      graph.collectNeighborIds(EdgeDirection.Either).mapValues { (vid, nbrs) =>
        val set = new VertexSet(nbrs.length)
        var i = 0
        while (i < nbrs.length) {
          // prevent self cycle
          if (nbrs(i) != vid) {
            set.add(nbrs(i))
          }
          i += 1
        }
        set
      }

    // 更新图中顶点的属性为邻居点集合
    val setGraph: Graph[VertexSet, ED] = graph.outerJoinVertices(nbrSets) {
      (vid, _, optSet) => optSet.getOrElse(null)
    }

    def edgeFunc(ctx: EdgeContext[VertexSet, ED, Int]) {
      // 在边上操作源点和终点的邻居集合是,遍历较小的集合,加快遍历速度
      val (smallSet, largeSet) = if (ctx.srcAttr.size < ctx.dstAttr.size) {
        (ctx.srcAttr, ctx.dstAttr)
      } else {
        (ctx.dstAttr, ctx.srcAttr)
      }
      val iter = smallSet.iterator
      var counter: Int = 0
      while (iter.hasNext) {
        val vid = iter.next()
        if (vid != ctx.srcId && vid != ctx.dstId && largeSet.contains(vid)) {
          counter += 1
        }
      }
      ctx.sendToSrc(counter)
      ctx.sendToDst(counter)
    }

    // 沿着图中的边计算两个顶点的邻居集合的交集,并为每个顶点合并消息(消息为三角形个数)
    val counters: VertexRDD[Int] = setGraph.aggregateMessages(edgeFunc, _ + _)
    graph.outerJoinVertices(counters) { (_, _, optCounter: Option[Int]) =>
      val dblCount = optCounter.getOrElse(0)
      // 算法为每个三角形计算了两次,所以结果是偶数
      require(dblCount % 2 == 0, "Triangle count resulted in an invalid number of triangles.")
      dblCount / 2        //注意最后需要除以2,每个三角形被计算了两遍
    }
  }
}

相关文章

  • Graphx图算法【1】三角形TriangleCount

    Graphx的数三角形算法TriangleCount用于统计每个顶点所在的三角形个数。 1.1 简介 对网络图中进...

  • Graphx图算法介绍

    本文介绍的Graphx的图上算法都是基于Pregel模型实现的。 用户图计算的场景: 1. 数三角形 Grap...

  • GraphX之Connected Components

    在Spark Graphx的org.apache.spark.graphx.lib包中有一些常用的图算法,其中一个...

  • neo4j之图计算

    如何通过neo4j做图计算 spark中graphx对neo4j的数据进行读取,然后通过graphx的相关算法进行...

  • Spark GraphX

    Spark GraphX概述 GraphX是Spark的一个组件,专门用来表示图以及进行图的并行计算。GraphX...

  • Graphx图算法【4】最短路径 ShortestPaths

    Graphx的最短路径算法只针对非带权图(即边的权重相等),采用迪杰斯特拉算法。 4.1 简介 最短路径算法用来计...

  • Graphx图算法【2】PageRank

    PageRank是谷歌提出的用于解决链接分析中网页排名问题的算法,目的是为了对互联网中数以亿计的网页进行排名。 2...

  • 使用GraphX计算粉丝平均年龄

    本文通过GraphX的aggregateMessages方法计算社交网络中某个人的所有粉丝的平均年龄 算法过程 图...

  • Spark GraphX图计算框架原理概述

    【转载】原文地址:原文地址 概述   GraphX是Spark中用于图和图计算的组件,GraphX通过扩展Spar...

  • Spark GraphX

    Spark GraphX GraphX简介 主要特点 演化过程 应用场景 分布式图计算处理技术介绍 下面分别从图数...

网友评论

    本文标题:Graphx图算法【1】三角形TriangleCount

    本文链接:https://www.haomeiwen.com/subject/pvcsvctx.html