Thao tác Biến đổi và Kết nối trên Đồ Thị với Spark GraphX

Các thao tác biến đổi đồ thị

Đồ thị trong GraphX cung cấp hai phương thức chính để biến đổi thành phần:

  • mapVertices(): Ánh xạ lại thuộc tính đỉnh, tạo đồ thị mới
  • mapEdges(): Biến đổi trọng số cạnh, trả về đồ thị đã cập nhật
println("Biến đổi đỉnh: tăng tuổi thêm 5")
doThi.mapVertices((id, info) => (id, (info._1, info._2 + 5)))
  .vertices.collect()
  .foreach(v => println(s"${v._2._1} - ${v._2._2} tuổi"))

println("Biến đổi cạnh: nhân đôi trọng số")
doThi.mapEdges(canh => canh.attr * 2)
  .edges.collect()
  .foreach(e => println(s"${e.srcId} → ${e.dstId}: ${e.attr}"))

Kết quả thực thi:

Biến đổi đỉnh: tăng tuổi thêm 5
Peter - 32 tuổi
Kate - 24 tuổi
Henry - 27 tuổi
Alice - 38 tuổi
Charlie - 55 tuổi
Mike - 35 tuổi

Biến đổi cạnh: nhân đôi trọng số
2 → 1: 10
2 → 4: 4
3 → 2: 14
3 → 6: 6
4 → 1: 2
5 → 2: 6
5 → 3: 16
5 → 6: 16

Tác vụ lọc cấu trúc đồ thị

Phương thức subgraph() cho phép trích xuất đồ thị con dựa trên điều kiện đỉnh:

println("Đồ thị con với người trên 26 tuổi")
val doThiCon = doThi.subgraph(vpred = (id, info) => info._2 > 26)

println("Danh sách đỉnh:")
doThiCon.vertices.collect().foreach(v => 
  println(s"${v._2._1} (${v._2._2} tuổi)"))

println("Danh sách cạnh:")
doThiCon.edges.collect().foreach(e => 
  println(s"${e.srcId} → ${e.dstId} (trọng số: ${e.attr})"))

Đầu ra mẫu:

Đồ thị con với người trên 26 tuổi
Danh sách đỉnh:
Peter (32 tuổi)
Henry (27 tuổi)
Alice (38 tuổi)
Charlie (55 tuổi)
Mike (35 tuổi)

Danh sách cạnh:
2 → 1 (trọng số: 5)
2 → 4 (trọng số: 2)
3 → 2 (trọng số: 7)
4 → 1 (trọng số: 1)
5 → 2 (trọng số: 3)
5 → 3 (trọng số: 8)

Kết nối đồ thị với thuộc tính mở rộng

Sử dụng outerJoinVertices() để kết hợp thông tin từ đồ thị phụ:

case class ThongTinNguoi(ten: String, tuoi: Int, bacVao: Int, bacRa: Int)

val doThiGoc = doThi.mapVertices((id, info) => 
  ThongTinNguoi(info._1, info._2, 0, 0))

val doThiHoanChinh = doThiGoc.outerJoinVertices(doThiGoc.inDegrees) {
  (id, nguoi, bacVao) => 
    ThongTinNguoi(nguoi.ten, nguoi.tuoi, bacVao.getOrElse(0), nguoi.bacRa)
}.outerJoinVertices(doThiGoc.outDegrees) {
  (id, nguoi, bacRa) => 
    ThongTinNguoi(nguoi.ten, nguoi.tuoi, nguoi.bacVao, bacRa.getOrElse(0))
}

println("Thông tin độ kết nối:")
doThiHoanChinh.vertices.collect().foreach { case (_, tt) => 
  println(s"${tt.ten}: bậc vào=${tt.bacVao}, bậc ra=${tt.bacRa}")
}

println("Người có bậc vào bằng bậc ra:")
doThiHoanChinh.vertices.filter { case (_, tt) => 
  tt.bacVao == tt.bacRa 
}.collect().foreach { case (_, tt) => println(tt.ten) }

Kết quả xử lý:

Thông tin độ kết nối:
Peter: bậc vào=1, bậc ra=1
Kate: bậc vào=2, bậc ra=0
Henry: bậc vào=2, bậc ra=2
Alice: bậc vào=2, bậc ra=0
Charlie: bậc vào=1, bậc ra=2
Mike: bậc vào=0, bậc ra=3

Người có bậc vào bằng bậc ra:
Peter
Henry

Thẻ: spark-graphx rdd-transformations vertex-operations graph-algorithms

Đăng vào ngày 9 tháng 8 lúc 18:20