spark从复杂的不清晰的关系网络中区分出一个个孤立的关系网络图

1 篇文章 0 订阅
1 篇文章 0 订阅

关系数据为 from -> to 的 边

设定数据格式为Long

spark计算关系网络 由于数据量过大 某些算法无法实现或实现代价太大

为了降低计算压力或优化计算方法 将整个关系网络中的孤立的,不与其他节点相连的数据关系区分出来,形成一个个小的关系网络图

实现方法:

( 用 图id 来标识每个关系网络图)

初始状态下 不知道每个节点所属网络图 
将每个节点的 id 设为他自己所在网络的 图id(Long)
    
通过groupBykey() 聚合方法 找到节点所有的连通的节点(只包含自己的图)
将所有的图中 ,图id最小的(也可以最大,用来防止死循环)一个 图id 设为自己的图id
    
可以获得一个 (节点id ,图id )的 节点所属关系网络图 数据集
    
将该数据集通过 join 的方式赋给原始的关系数据
得到数据结构为 (from:Long, 图id_1 :Long )-> (to : Long , 图id_2 : Long)  的新的关系数据
    
过滤出其中: 图id_1 != 图id_2 的数据 进行下一次迭代
    
多次迭代后,每个节点的 图id 为该节点所在关系网络图中节点id最小的值,该值即为节点所属关系网络图的图id

 

代码实现:

val edgerdd = **** // (from ,to)结构的关系数据,无向图

 
var graphIdRdd = edgerdd.reduceByKey((a, b) => if (a < b) a else b)
.map(a=>if (a._1<a._2) (a._1,a._1) else a) //compare with itself

graphIdRdd.count() 

var count = 1
   
while (count != 0) {
   
   //give nodeid a graphid
   val edge_rdd_need_deal = edgerdd.leftOuterJoin(graphIdRdd) //give fromnode a graphId
        .map(a => {
          val from = a._1
          val to = a._2._1
          val fromgraphId = a._2._2.get
          (to, (from, fromgraphId))
        })
        .leftOuterJoin(graphIdRdd)   //give tonode a graphId
        .map(a => {
          val to = a._1
          val from_graphId = a._2._1
          val tographId = a._2._2.get
          (from_graphId, tographId)
        })
        .filter(a => a._1._2 != a._2) // filter the relation which is not changed

      count = edge_rdd_need_deal.count().toInt 

     
      val new_graphIdRdd = edge_rdd_need_deal
        .reduceByKey((a, b) => if (a < b) a else b) //get the neighbors' min graphid
        .map(a => {
          val from = a._1._1
          val from_graphId = a._1._2
          val new_graphId = a._2
          (from, if (from_graphId < new_graphId) from_graphId else new_graphId)
        })     // get the new graphid ,small than the old one

      new_graphIdRdd.count()

      // union the don't be changed node
      graphIdRdd = graphIdRdd.union(new_graphIdRdd).reduceByKey((a, b) => if (a < b) a else b).repartition(300)
      graphIdRdd.count() 

    }
    println("all is ok")

 (根据需要来缓存数据)

 

仅供参考

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值