Graphxプロジェクトの実際の戦闘機ネットワーク分析

1.タスクの説明

要件の概要

  • フライトネットワークグラフデータの探索
  • フライトネットワークマップを作成する
  • Spark GraphXを使用して次のタスクを完了します
  • フライトネットワークマップ内の空港の数を数える
  • フライトネットワークマップのルート数をカウントする
  • 最長の飛行ルートを計算する(ポイントツーポイント)
  • 最も忙しい空港を見つける
  • 最も重要な飛行ルートを見つける(PageRank)
  • 最安フライトルートを検索(SSSP)

二.具体分析

問題分析1:データ探索

  • データリンクのダウンロード:https://pan.baidu.com/s/1fubnDM_sggw_MWS9iI1AoQ抽出コード:xnxv
  • データ形式:ファイル形式はCSVで、フィールド間の区切り文字は「、」です。
  • 順序は次のとおりです。#日、周#、航空会社、航空機登録番号、フライト番号、出発空港番号、出発空港、到着空港番号、到着空港、出発予定時刻(時間と分)、出発時刻、出発遅延(分) 、推定到着時間、到着時間、到着遅延(分)、推定飛行時間、飛行距離

ここに画像の説明を挿入

問題分析2:飛行ネットワーク図の作成

  • 属性グラフの作成Graph [VD、ED]
  • CSVをRDDとしてロードし、各空港を頂点としてロードします。キーフィールド:出発空港番号、出発空港、到着空港番号、到着空港、飛行距離
  • 頂点セットAirports:RDD [(VertexId、String)]を初期化します。頂点属性は空港名です
  • エッジセットラインを初期化します:RDD [エッジ]、エッジ属性は飛行距離
//导入包
import org.apache.spark.graphx._
//加载数据
val flights = sc.textFile("file:///data/flight.csv").map(_.split(","))
//机场数据
val airports = flights.flatMap(x => Array((x(5).toLong, x(6)), (x(7).toLong,x(8)))).distinct
//航线数据
val lines = flights.map(x => (x(5).toLong, x(7).toLong, x(16).toInt)).distinct.map(x => Edge(x._1, x._2, x._3))
//构建图
val graph = Graph(airports, lines)

問題分析3:フライトネットワークマップ内の空港とルートの数を数える

  • 空港の数:頂点の数を見つける:Graph.numVertices
  • ルートの数:エッジの数を見つける:Graph.numEdges
//机场个数
graph.vertices.count
graph.numVertices
//航线数
graph.numEdges

//补充使用spark_sql
//spark_sql
val df= spark.read.format("csv").option("header","false").option("delimiter",",").load("file:///data/flight.csv").toDF("dom","dow","carrier","tail_num","fl_num","origin_id","origin","des_id","dest","crs_dep_time","dep_time","dep_delay_mins","crs_arr_time","arr_time","arr_delay_mins","crs_elapse_time","dist")
val df2 = df.select("origin_id","origin","des_id","dest")
df2.registerTempTable("flight")
//起飞机场多少个
spark.sql("with t1 as (select origin_id from flight group by origin_id) select sum(1) from t1 ").show//301
df.select("origin_id").distinct.count//301
//目的地机场多少个
spark.sql("with t1 as (select des_id from flight group by des_id) select sum(1) from t1 ").show//301
df.select("des_id").distinct.count//301
//起飞机场和目的地机场多少个
df.select("origin_id").union(df.select("des_id")).distinct.count //301
//航线个数
df.select("origin_id","des_id").distinct.count

問題分析4:最長飛行ルートを計算する

  • 最大のエッジ属性:トリプレットを飛行距離でソートし(降順)、最初のものを取得します
graph.triplets.sortBy(_.attr,false).take(1)
graph.triplets.sortBy(_.attr,false).map(t => "The distance is %d from %s to %s.".format(t.attr, t.srcAttr, t.dstAttr)).take(1)(0)
graph.inDegrees.sortBy(_._2,false).take(1)
graph.outDegrees.filter(x=>x._1==10397).collect
val (x,y)= graph.degrees.sortBy(_._2,false).take(1)(0)

//reduce求最大值
lines.reduce((x,y)=>if (x.attr > y.attr) x else y)
//fold求最大值
lines.fold(Edge(0))((x,y)=>if(x.attr> y.attr) x else y)
spark.sql("select * from flight order by cast(dist as int) desc").show(1)

問題分析5:最も混雑している空港を見つける

  • 最も多くのフライトが到着する空港:頂点のインディグリーを計算してソートする
//sort
graph.inDegrees.sortBy(_._2,false).take(1)(0)
//reduce
graph.inDegrees.reduce((x,y)=>if(x._2>y._2) x else y)

問題分析6:最も重要な空港を見つける

  • PageRank:収束エラー:0.05
graph.pageRank(0.05).vertices.join(airports).sortBy(_._2._1,false).map(_._2._2).take(1)

val g = graph.pageRank(0.0001)
g.vertices.take(10)
val iv = g.vertices.reduce((x,y)=>if(x._2>y._2) x else y)

問題分析7:最安のフライトルートを見つける

  • 料金モデル:価格= 180.0 +距離* 0.15
  • SSSP問題:最初に指定されたソースポイントから任意のポイントまでの最短距離

プレゲル

  • ソースポイントと他の頂点を初期化します(Double.PositiveInfinity)
  • 最初のメッセージ(Double.PositiveInfinity)
  • 最小値を計算するvprog関数
  • sendMsg関数は、次の反復に進むかどうかを計算します
  • mergeMsg関数は、受信したメッセージをマージし、最小値を取ります
val count = airports.count//总机场数
var fraction = 1.0//系数
var samples = airports.sample(false, fraction/count, count) //抽样
while ( samples.count < 0 ) {
    
    
fraction = fraction + 1
samples = airports.sample(false, fraction/count, count)
}
val source_id: VertexId = samples.first._1//得到源点 14952
//给初始值,转换定价模型
val init_graph = graph.mapVertices((id, _) => if (id == source_id) 0.0 else Double.PositiveInfinity).mapEdges(e => 180.toDouble + e.attr.toDouble*0.15)
//构建pregel模型	
val pregel_graph = init_graph.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)
)
//航线
val cheap_lines = pregel_graph.edges.map {
    
     case(Edge(src_id, dst_id, price))
=> (src_id, dst_id, price) }.takeOrdered(3)(Ordering.by(_._3))
//机场
val cheap_airports = pregel_graph.vertices.takeOrdered(3)(Ordering.by(_._2))

おすすめ

転載: blog.csdn.net/sun_0128/article/details/107926914