fly.csv文件下载链接: https://pan.baidu.com/s/1rDcrRxmXMpMIJyOp48zKAw
提取码: erd9
package Flyfenxi
import org.apache.spark.SparkContext
import org.apache.spark.graphx.{Edge, Graph}
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{SparkSession}
/**
* @Author Bright
* @Date 2021/1/14
* @Description
* 探索航班飞行网图数据
* 构建航班飞行网图
* 使用Spark GraphX完成下列任务
* (1)统计航班飞行网图中机场的数量
* (2)统计航班飞行网图中航线的数量
* (3)计算最长的飞行航线(Point to Point)
* (4)找出最繁忙的机场
* (5)找出最重要的飞行航线(PageRank)
* (6)找出最便宜的飞行航线(SSSP)
*/
object AirportsFenXi {
def main(args: Array[String]): Unit = {
// 创建SparkSession
val spark: SparkSession
= SparkSession.builder().appName(this.getClass.getName).master("local[1]").getOrCreate()
// 创建SparkContext
val sc: SparkContext = spark.sparkContext
// 数据加载
val rdd: RDD[String] = sc.textFile("D:\\scalastu\\kb09\\SparkLearn1\\data\\input3\\USA Flight Datset - Spark Tutorial - Edureka.csv")
// 获取首行
val header: String = rdd.first()
//header.foreach(println)
//过滤出来不包含第一行的数据 并且按","分割数据 // 去掉表头, 思路: 和首行一样的, 就去掉
val AirportRDD: RDD[Array[String]] = rdd.filter(_!=header).map(_.split(","))
//AirportRDD.first().foreach(print)
//AirportRDD.repartition(1).foreach(println)
//使用flatMap才可以把Array中的元素拿出来 才可以去重 将(机场编号,机场名)作为Graph的顶点集合
val airport: RDD[(Long, String)] = AirportRDD.flatMap(x =>
Array(
(x(5).toLong, x(6)),
(x(7).toLong, x(8))
)
).distinct()
//airport.foreach(println)
//机场数量
//println(airport.count())
//map取出 (起飞机场编号,到达机场编号,飞行距离) 三列数据作为Graph的边集合
val lines: RDD[Edge[Int]] = AirportRDD.map(x => (
x(5).toLong,
x(7).toLong,
x(16).toInt
)).distinct.map(x => Edge(x._1, x._2, x._3))
//构建Graph
val graph: Graph[String, Int] = Graph(airport,lines)
//graph.triplets.collect.foreach(println)
// (1)统计航班飞行网图中机场的数量
println(graph.numVertices)
// (2)统计航班飞行网图中航线的数量
println(graph.numEdges)
// (3)计算最长的飞行航线(Point to Point)
graph.triplets.sortBy(x=>x.attr,false).take(1).foreach(println)
// (4)找出最繁忙的机场
graph.inDegrees.sortBy(x=>x._2,false).take(5).foreach(println)
// (5)找出最重要的飞行航线(PageRank)
graph.pageRank(0.05).vertices.takeOrdered(3)(Ordering.by(_._2))
graph.pageRank(0.05).triplets.sortBy(x=>x.attr,false).take(5).foreach(println)
// (6)找出最便宜的飞行航线(SSSP)
graph.mapEdges(e=>180+e.attr*0.15)
//赋给原点一个初值,其他点赋值无穷大
.mapVertices((id,attr)=>if(id==12478) 0.0 else Double.PositiveInfinity)
.pregel(Double.PositiveInfinity)(
//接收消息时的处理函数
(id,dist,new_dist)=>math.min(dist,new_dist),
// 发送消息的处理函数
triplet=>{
//如果当前点的价格+边长的价格<目标点有的价格就发送消息[当前点的价格+边长的价格]
//否则不发送消息
if(triplet.srcAttr+triplet.attr<triplet.dstAttr)
Iterator((triplet.dstId,triplet.srcAttr+triplet.attr))
else Iterator.empty
},
// 合并消息的函数, 求最小值
(a,b)=>math.min(a,b)
// 取价格最便宜的前三个遍历
).vertices.takeOrdered(3)(Ordering.by(_._2)).foreach(println)
// graph.triplets.map(x=>(x.srcAttr,x.dstAttr,x.attr,x.attr*0.15+180)).sortBy(x=>(x._4),false).take(5)
// .foreach(println)
}
}