Spark GraphX图计算实例

航空数据简单计算

数据格式

dom – 月中第几天 (day of month)
dow – 周中第几天 (day of week)
carrier – 航空公司
tail_num – 飞机注册号
fl_num – 航班号
origin_id – 起飞机场编号
origin – 起飞机场
dest_id – 到达机场编号
dest – 到达机场
crs_dep_time – 预计起飞时间
dep_time – 起飞时间
dep_delay_mins – 起飞延迟 (分钟)
crs_arr_time – 预计到达时间
arr_time – 到达时间
arr_delay_mins – 到达延迟 (分钟)
crs_elapse_time – 预计飞行时间
dist – 飞行距离

这是其中一小部分数据,充当演示数据格式的作用,不是全部数据

在这里插入图片描述

项目要求
  1. 统计航班飞行网图中机场的数量
  2. 统计航班飞行网图中航线的数量
  3. 计算最长的飞行航线(Point to Point)
  4. 找出最繁忙的机场
  5. 找出最重要的飞行航线(PageRank)
  6. 找出最便宜的飞行航线
基本代码
//模板代码
private val spark: SparkSession = SparkSession.builder()
.appName(this.getClass.getSimpleName)
.master("local[*]")
.getOrCreate()
private val sc: SparkContext = spark.sparkContext

//加载数据
private val flights: RDD[Array[String]] = 
			  sc.textFile("src/main/scala/cn8/Test2/plane.csv")
              .mapPartitionsWithIndex((index, iter) =>
              if (index == 0) iter.drop(1) else iter)
              .map(_.split(","))
              .cache()
//点集合
private val airports: RDD[(Long, String)] = 
	flights.flatMap(x => Array((x(5).toLong, x(6)), (x(7).toLong, x(8)))).distinct()


//边集合
private val lines: RDD[Edge[Int]] = 
	flights.map(x => (x(5).toLong, x(7).toLong, x(16).toInt))
	.distinct().map(x => Edge(x._1, x._2, x._3))

//构建图
private val graph: Graph[String, Int] = Graph(airports, lines)
1.统计机场数量

实际上就是找出顶点的个数

println("机场数量 : " + graph.numVertices)
2.统计航线的数量

实际上就是找出边的数量

println("航线数量 : " + graph.numEdges)
3. 计算最长的飞行航线

可以通过 起飞机场 和 降落机场 及 其中的参数进行判断

graph.triplets.sortBy(_.attr, false).take(1)
  .map(x => "航线距离最长 : " + x.srcAttr + "---->" + x.dstAttr + "----距离 : " + x.attr)
  .foreach(println)
4.最繁忙的机场

即找到 入度 和 出度 数量最多的 点
//入度

graph.inDegrees
	.sortBy(_._2, false)
  	.take(1)
 	.foreach(x => println("入度最多机场 : " + x))

//出度

graph.outDegrees
	.sortBy(_._2, false)
	.take(1)
	.foreach(x => println("出度最多机场 : " + x))
5.最重要的机场

需要通过PageRank进行权重排序

graph.pageRank(0.05).vertices.join(airports)
         .sortBy(_._2._1, false)
         .take(3)
         .map(x => (x._2._2, x._2._1))
         .foreach(println)
6.最便宜的飞行路线
计算公式 : price = 180.0 + distance * 0.15
//取得一个点作为原点,可随机设置,也可以手动设置
//此处使用手动设置,机场编号12478
val source_id: VertexId = 12478
//初始化一个图,包括点和边
private val init_graph: Graph[Double, Double] = 
	graph.mapVertices((id, _) => 
	if (id == source_id) 0.0 else Double.PositiveInfinity)
	.mapEdges(e => e.attr.toDouble * 0.15)

//这里需要使用到pregel方法,需要事先定义 接受消息 发送消息 合并消息 三个值
//接受消息
val f1: (VertexId, Double, Double) => Double = 
	(id, dist, new_dist) => math.min(dist, new_dist)

//(筛选)发送消息
val f2: EdgeTriplet[Double, Double] => Iterator[(VertexId, Double)] = triplet =>
{
        if (triplet.srcAttr + triplet.attr < triplet.dstAttr) 
        	Iterator((triplet.dstId,triplet.srcAttr + triplet.attr))
        else 
        	Iterator.empty
}

//合并
val f3: (Double, Double) => Double = (x, y) => math.min(x, y)

//调用pregel函数进行计算
val pregel_graph: Graph[Double, Double] = 
	init_graph.pregel(Double.PositiveInfinity)(f1, f2, f3)


//输出
pregel_graph.vertices.filter(x => x._2 != 0).takeOrdered(1)
{
	Ordering.by(x => x._2)
}.foreach(x => println(s"从$source_id 出发到 ${x._1}最便宜的价格为: ${x._2}"))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值