需求:若是一個用戶使用了某個手機,這個手機上登陸過其餘的用戶,那麼這些用戶是有關係的,一樣用戶關聯到的用戶又能夠經過手機關聯到其餘用戶 這樣就構成了一個強大的關係網。如今給出用戶與手機登陸關係表,請找出全部的用戶是有關係的。微信
整個用戶手機關係網拓撲圖以下圖所示:
從圖中能夠發現,找到有關係的關聯的用戶,就是要找出上面無向圖的全部聯通分支。好比上圖有兩個聯通分支。機器學習
對應上圖,測試數據集合以下:分佈式
#user_id,phone_id 001,01 002,01 003,01 004,01 005,01 004,02 006,02 007,02 008,02 009,03 010,03 011,03
但願的輸出結果爲全部關聯的用戶對應同一個ID。ide
val rootDir = "datas" def main(args: Array[String]) { val conf = new SparkConf().setAppName("SparkInAction").setMaster("local") val sc = new SparkContext(conf) val userPhoneRS = sc.textFile(rootDir + "/user_phone.relationship") # 生成用戶對應的點 val users: RDD[(VertexId, (String))] = userPhoneRS.map(_.split(",")(0)).distinct() .map(userId => (userId.toLong, ("TEST_USER"))) # 生成手機對應的點,爲了防止手機ID和用戶ID重複,使用了一個小技巧,就是手機ID = 最大的用戶ID + 手機ID val maxUserId = users.max()._1 val phones: RDD[(VertexId, (String))] = userPhoneRS.map(_.split(",")(1)).distinct() .map(phoneId => (phoneId.toLong + maxUserId, ("TEST_PHONE"))) # 生成全部的點 val vertices = users.union(phones) # 生成全部的邊 val edges: RDD[Edge[String]]= userPhoneRS.map { line => val up = line.split(",") Edge(up(0).toLong, up(1).toLong + maxUserId, "TEST_EDGE") } # 生成圖 val default = ("Missing") val graph = Graph(vertices, edges, default) graph.vertices.collect().foreach(println) graph.edges.collect().foreach(println) # 找到全部的聯通分支 val graph2 = graph.connectedComponents() # 結果展現 graph2.vertices.filter(_._1 <= maxUserId).collect().foreach(println) }
運行結果:學習
(4,1) (6,1) (8,1) (10,9) (2,1) (11,9) (1,1) (3,1) (7,1) (9,9) (5,1)
能夠發現,結果正如咱們所料。測試
基於 Spark GraphX 能夠作不少圖計算方面的事情,並且是分佈式,速度比單機處理快,值得好好研究。 下面推薦一下好的資料:大數據
歡迎關注本人微信公衆號,會定時發送關於大數據、機器學習、Java、Linux 等技術的學習文章,並且是一個系列一個系列的發佈,無任何廣告,純屬我的興趣。
ui