spark-GraphX 圖像的聚合操作aggregate (計算圖中各節點到根節點的最遠距離)

import org.apache.spark.graphx.{Edge, EdgeContext, Graph, VertexRDD}
import org.apache.spark.{SparkConf, SparkContext}

方法一:join 

object aggregate_demo2 {

  //數據發送   [Int, String, Int]分別代表:[頂點的數據集(初始化完成之後就是距離的數據集),邊的數據集(兩頂點的關係的名稱), 發送的消息的數據類型]
 
    def sendMsg(ec:EdgeContext[Int,String,Int])={
    //向每條邊的目標頂點發送數據,發送的是 源頂點的src的屬性數據+1
    ec.sendToDst(ec.srcAttr + 1)
  }
   //統計每個頂點收到的數據的值, 返回最大的數據值,作爲頂點的屬性數據
  def mergeMsg(a:Int, b:Int):Int={
    math.max(a,b)
  }

  def sumEdgeCount(g:Graph[Int,String], i:Int = 1):Graph[Int,String]={
    //執行aggregateMessages,返回頂點數據集
     val verts= g.aggregateMessages[Int](sendMsg, mergeMsg)
     verts.collect.foreach(println(_))
    //創建一個新的圖g2,由新生成的頂點數據集和生成前的邊的數據集構成(邊的數據集是一直不變的)
    val g2 = Graph(verts, g.edges)
    //然後,將g2和g的頂點數據集join起來,計算兩圖的頂點屬性差值
    val check = g2.vertices.join(g.vertices).map(x=> x._2._1 - x._2._2).reduce(_+_)

//遞歸終止條件,如果差值全部爲0,終止遞歸,如果不爲0,用新生成的圖繼續遞歸
    if (check > 0)
      sumEdgeCount(g2)
    else
      g
  }

  def main(args: Array[String]): Unit = {

    //設置運行環境
    val conf = new SparkConf().setAppName("SimpleGraphX").setMaster("local[2]")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")

    //構建圖
    //創建頂點信息
    val myVertices = sc.parallelize(Array(
      (1L, "Suan"),
      (2L, "David"),
      (3L, "Judy"),
      (4L, "Mike"),
      (5L, "Lisa")
    ))

    //創建邊信息
    val myEdges = sc.parallelize(Array(
      Edge(1L, 2L, "friends"),
      Edge(2L, 3L, "friends"),
      Edge(3L, 4L, "colleagues"),
      Edge(3L, 5L, "friends"),
      Edge(4L, 5L, "colleagues")
    ))

    val myGraph = Graph(myVertices, myEdges)

    //設置頂點屬性, 將所有頂點的屬性初始化爲 0
    val initGraph = myGraph.mapVertices((_,_) => 0)

    //用遞歸算法計算出圖中各頂點到id=1頂點的最遠距離
    sumEdgeCount(initGraph).vertices.collect.foreach(println(_))

  }
}

方法二:

object aggregate_demo2 {

  def sendMsg(ec:EdgeContext[Int,String,Int])={
    ec.sendToDst(ec.srcAttr + 1)
  }
   
  def mergeMsg(a:Int, b:Int):Int={
    math.max(a,b)
  }

  //在sumEdgeCount方法中增加一個屬性i,i表示的是第幾次遞歸,最大的頂點屬性數據 = 遞歸次數,當最大的頂點屬性數據 < 遞歸次數時,立即返回頂點頂點屬性數據
  def sumEdgeCount(g:Graph[Int,String], i:Int = 1):Graph[Int,String]={
    val verts= g.aggregateMessages[Int](sendMsg, mergeMsg)

    val g2 = Graph(verts, g.edges)
    val check = g2.vertices.map(x => x._2).max()

    if(check >= i)
      sumEdgeCount(g2, i+1)
    else
      g
  }

  def main(args: Array[String]): Unit = {

    //設置運行環境
    val conf = new SparkConf().setAppName("SimpleGraphX").setMaster("local[2]")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")

    //構建圖
    //創建頂點信息
    val myVertices = sc.parallelize(Array(
      (1L, "Suan"),
      (2L, "David"),
      (3L, "Judy"),
      (4L, "Mike"),
      (5L, "Lisa")
    ))

    //創建邊信息
    val myEdges = sc.parallelize(Array(
      Edge(1L, 2L, "friends"),
      Edge(2L, 3L, "friends"),
      Edge(3L, 4L, "colleagues"),
      Edge(3L, 5L, "friends"),
      Edge(4L, 5L, "colleagues")
    ))

    val myGraph = Graph(myVertices, myEdges)

    //設置頂點屬性, 將所有頂點的屬性初始化爲 0
    val initGraph = myGraph.mapVertices((_,_) => 0)

    //用遞歸算法計算出圖中各頂點到id=1頂點的最遠距離
    sumEdgeCount(initGraph,i=1).vertices.collect.foreach(println(_))
   }

  }

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章