動手構建地鐵關係網,實現最短路徑查詢

1、前言

打開手機‘北京地鐵’APP,輸入起始點:霍營,終點:北京南站,發現系統給咱們推薦了兩條路線。
最短期路線與最少換乘路線,而且分別給出了耗時與乘坐里程費。看到這裏,不由開啓了靚仔疑問,假如給你地鐵站相關數據,如何構建這樣的關係網絡呢?(儘可能少寫代碼,畢竟我這我的懶的不行,花最少的功夫,整最炫的效果,咦)
html

1.整理地鐵站點數據,處理成echarts圖表所須要的結構
2.整理地鐵站點數據,本身寫代碼實現,能實現(好累啊…)
3.整理地鐵站點數據,導入 Neo4j 中,點擊查看

sql

分析:方案一,不只要處理數據還要搞echarts樣式,算了吧。方案二,直接PASS,仍是方案三省力,正好個人電腦上以前安裝過 Neo4j 圖數據庫,哈哈哈,開搞開搞!
軟件下載地址:http://doc.we-yun.com:1008/neo4j-chs
軟件安裝教程:https://www.cnblogs.com/jstarseven/p/9546555.html

數據庫

![Neo4j 地鐵關係網][1]瀏覽器

2、數據準備

既然須要展現地鐵關係,那麼首先須要的就是北京全部地鐵站的信息,以及站點之間的關係,距離,耗時。搜索了一圈,最後在北京地鐵官方網站,發現了所有地鐵線路,站點名稱,站點與站點之間距離等信息。可是缺乏了具體站點與站點之間的乘車耗時,行吧,先將就着用吧!具體數據樣例以下:網絡

![Neo4j 地鐵關係網][2]

數據來源地址:https://www.bjsubway.com/station/zjgls/#echarts

站點關係

一共18條線路,一頓複製粘貼和 Notepad++ 文本替換以後,咱們獲得了一個 Excel文件,包含了全部站點之間的關係數據,以下:網站

![Neo4j 地鐵關係網][3]

獲取站點

複製全部站點進入Excel文件的某一個sheet,選擇數據去重,獲得全部站點名稱。url

![Neo4j 地鐵關係網][4]

處理CSV

將站點關係與站點數據處理成CSV文件格式,方便導入 Neo4j 數據庫中,創建圖節點與關係。操做也就是 notepad++ 替換‘ ’爲‘,’,另存爲 .CSV 文件,具體獲得下列文件。(由於方便 Neo4j 數據庫不一樣的路線顯示不一樣的顏色,我特意將站點關係數據拆解成了多個地鐵線的CSV文件,若是不考慮顯示,能夠一個CSV文件,導入站點關係便可)spa

![Neo4j 地鐵關係網][9]

備註:將全部CSV文件,放入 Neo4j 安裝目錄下的 import 文件夾中(沒有就新建),以下:.net

![Neo4j 地鐵關係網][5]

3、創建地鐵關係網

Neo4j 支持導入本地以及網絡資源中的 CSV 文件數據,而且能夠從CSV文件數據中,直接創建圖形節點以及節點關係。具體 cypher 語句,以下:

創建地鐵站點

LOAD CSV WITH HEADERS  FROM "file:///station.csv" AS line
MERGE (p:Station{id:line.id,name:line.name});

創建站點鏈接

LOAD CSV WITH HEADERS FROM "file:///line1.csv" AS line1
match (from1:Station{name:line1.sn}),(to1:Station{name:line1.en})
merge (from1)-[r1:一號線{jl:line1.jl,xl:line1.xl}]->(to1);

LOAD CSV WITH HEADERS FROM "file:///line2.csv" AS line2
match (from2:Station{name:line2.sn}),(to2:Station{name:line2.en})
merge (from2)-[r2:二號線{jl:line2.jl,xl:line2.xl}]->(to2);

LOAD CSV WITH HEADERS FROM "file:///line4.csv" AS line4
match (from4:Station{name:line4.sn}),(to4:Station{name:line4.en})
merge (from4)-[r4:四號線{jl:line4.jl,xl:line4.xl}]->(to4);

LOAD CSV WITH HEADERS FROM "file:///line5.csv" AS line5
match (from5:Station{name:line5.sn}),(to5:Station{name:line5.en})
merge (from5)-[r5:五號線{jl:line5.jl,xl:line5.xl}]->(to5);

LOAD CSV WITH HEADERS FROM "file:///line6.csv" AS line6
match (from6:Station{name:line6.sn}),(to6:Station{name:line6.en})
merge (from6)-[r6:六號線{jl:line6.jl,xl:line6.xl}]->(to6);

LOAD CSV WITH HEADERS FROM "file:///line7.csv" AS line7
match (from7:Station{name:line7.sn}),(to7:Station{name:line7.en})
merge (from7)-[r7:七號線{jl:line7.jl,xl:line7.xl}]->(to7);

LOAD CSV WITH HEADERS FROM "file:///line8.csv" AS line8
match (from8:Station{name:line8.sn}),(to8:Station{name:line8.en})
merge (from8)-[r8:八號線{jl:line8.jl,xl:line8.xl}]->(to8);

LOAD CSV WITH HEADERS FROM "file:///line9.csv" AS line9
match (from9:Station{name:line9.sn}),(to9:Station{name:line9.en})
merge (from9)-[r9:九號線{jl:line9.jl,xl:line9.xl}]->(to9);

LOAD CSV WITH HEADERS FROM "file:///line10.csv" AS line10
match (from10:Station{name:line10.sn}),(to10:Station{name:line10.en})
merge (from10)-[r10:十號線{jl:line10.jl,xl:line10.xl}]->(to10);

LOAD CSV WITH HEADERS FROM "file:///line13.csv" AS line13
match (from13:Station{name:line13.sn}),(to13:Station{name:line13.en})
merge (from13)-[r13:十三號線{jl:line13.jl,xl:line13.xl}]->(to13);

LOAD CSV WITH HEADERS FROM "file:///line14.csv" AS line14
match (from14:Station{name:line14.sn}),(to14:Station{name:line14.en})
merge (from14)-[r14:十四號線{jl:line14.jl,xl:line14.xl}]->(to14);

LOAD CSV WITH HEADERS FROM "file:///line15.csv" AS line15
match (from15:Station{name:line15.sn}),(to15:Station{name:line15.en})
merge (from15)-[r15:十五號線{jl:line15.jl,xl:line15.xl}]->(to15);

LOAD CSV WITH HEADERS FROM "file:///linebt.csv" AS linebt
match (frombt:Station{name:linebt.sn}),(tobt:Station{name:linebt.en})
merge (frombt)-[rbt:八通線{jl:linebt.jl,xl:linebt.xl}]->(tobt);

LOAD CSV WITH HEADERS FROM "file:///linecp.csv" AS linecp
match (fromcp:Station{name:linecp.sn}),(tocp:Station{name:linecp.en})
merge (fromcp)-[rcp:昌平線{jl:linecp.jl,xl:linecp.xl}]->(tocp);

LOAD CSV WITH HEADERS FROM "file:///lineyz.csv" AS lineyz
match (fromyz:Station{name:lineyz.sn}),(toyz:Station{name:lineyz.en})
merge (fromyz)-[ryz:亦莊線{jl:lineyz.jl,xl:lineyz.xl}]->(toyz);

LOAD CSV WITH HEADERS FROM "file:///linedx.csv" AS linedx
match (fromdx:Station{name:linedx.sn}),(todx:Station{name:linedx.en})
merge (fromdx)-[rdx:大興線{jl:linedx.jl,xl:linedx.xl}]->(todx);

LOAD CSV WITH HEADERS FROM "file:///linefs.csv" AS linefs
match (fromfs:Station{name:linefs.sn}),(tofs:Station{name:linefs.en})
merge (fromfs)-[rfs:房山線{jl:linefs.jl,xl:linefs.xl}]->(tofs);

LOAD CSV WITH HEADERS FROM "file:///linejc.csv" AS linejc
match (fromjc:Station{name:linejc.sn}),(tojc:Station{name:linejc.en})
merge (fromjc)-[rjc:機場線{jl:linejc.jl,xl:linejc.xl}]->(tojc);

執行效果

備註:Neo4j瀏覽器須要開啓多語句執行配置,不然會報語句執行錯誤,配置界面以下:

1.Neo4j瀏覽器配置

![Neo4j 地鐵關係網][6]

2.cypher語句執行過程

![Neo4j 地鐵關係網][7]

3.地鐵關係網效果

![Neo4j 地鐵關係網][8]

4、路徑檢索

以‘霍營’與‘北京南站’地鐵站爲例,檢索具體一下路徑:

最少站點路徑

MATCH (p1:Station {name:"霍營"}),(p2:Station{name:"北京南站"}),p=shortestpath((p1)-[*]-(p2)) RETURN p

最短路程路徑

MATCH p=(b:Station{name:"霍營"})-[*..20]->(d:Station{name:"北京南站"}) WITH p,reduce(s = 0, r IN rels(p) | s + r.jl) AS dist return p ORDER BY dist DESC limit 1

最少耗時路徑

很遺憾,由於沒有找到北京地鐵每站之間具體的耗時數據,因此此處檢索不出來,行吧,我太難了。

5、總結

1)數據整理涉及節點數據,節點關係數據,可在導入CSV時一併建立;
2)Cypher 是 借鑑了sql語句的 Neo4j 數據庫操做語句;
3)(a)-[*…20]->(b):表示路徑長度的最大值是20,起始節點是a,終止節點是b;
4)一次執行多條語句,Neo4j瀏覽器須要開啓多語句執行配置;


點擊查看更多內容
相關文章
相關標籤/搜索