spark從複雜的不清晰的關係網路中區分出一個個孤立的關係網路圖
阿新 • • 發佈:2018-12-19
關係資料為 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) 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 ,less 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) } println("all is ok")
(根據需要來快取資料)