基于图结构实现地铁乘坐线路查询
- github-python算法和flaskapp部分:repo
- github-android部分:repo
- flaskapp接口文档:传送门
- 深度了解Dijkstra优化算法:传送门
- personblog:github_page or csdnblog
问题描述
编写一个程序实现地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。
1.采用Dijkstra算法实现,使用优先队列对性能进行了优化;
2.如果两站间存在多条最短路径,则输出其中的一条即可;
- 本次项目实现采用了flask作为后端提供接口服务,使用androidApp进行get请求获得数据,显示在Textview中
设计需求
- 确定储存地铁站文件的格式文件 (已确认使用json格式和文本格式)
- 确定读取地铁站数据的方式 (使用python的file打开命令)
- 确定获取两站点最小站点数的算法方式
- 进行外表封装
- 进行输出格式的确定
- 性能测试
- 最后结果检查
数据存储格式
stationline.txt文本为存储的地图数据文本,格式如下图所示:
- 使用0与1来分别表示是否需要换乘
1 | 地铁线路条数 |
- 数据示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
192 20
曹庄 0
卞兴 0
芥园西道 0
咸阳路 0
长虹公园 1
广开四马路 0
西南角 1
鼓楼 0
东南角 0
建国道 0
天津站 1
远洋国际中心 0
顺驰桥 0
靖江路 1
翠阜新村 0
屿东城 0
登州路 0
国山路 0
数据文本读取代码
1 | with open(os.path.join(os.path.abspath('..'), "station/stationLine.txt"), "r") as f: |
打印结果
1
2
3
4
5stationline {"1": ["刘园", "西横堤", "果酒厂", "本溪路", "勤俭道", "洪湖里", "西站", "西北角", ..]}
linesdata {"刘园": [1], "西横堤": [1], "果酒厂": [1], "本溪路": [1], "勤俭道": [1], "洪湖里": [1], "西站": [1, 6], "西北角": [1], "西南角": [1, 2], "二纬路": [1], "海光寺": [1], "鞍山道": [1], "营口道": [1, 3], "小白楼": [1], "下瓦房": [1, 5],....}
station_num {"刘园": 0, "西横堤": 1, "果酒厂": 2, "本溪路": 3, "勤俭道": 4, "洪湖里": 5, "西站": 6, "西北角": 7, "西南角": 8, "二纬路": 9, "海光寺": 10, "鞍山道": 11, "营口道": 12, "小白楼": 13, "下瓦房": 14,.....}获得点与点之间的最短路径:
1 | def find_shortest_path(graph, start, end, path=[]): |
dijkstra算法具体分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22def dijkstra_shortest_pathS(graph, v0, endpos):
vnum = 0
for i in pathss.keys():
vnum += 1
assert 0 <= v0 < vnum
# 长为vnum的表记录路径
paths = [None] * vnum
count = 0
cands = PrioQueue([(0, v0, v0)])
while count < vnum and not cands.is_empty():
plen, u, vmin = cands.dequeue()
if paths[vmin]:
continue
paths[vmin] = (u, plen)
# print(u, plen)
for v in graph[vmin]:
if not paths[v]:
cands.enqueue((plen + 1, vmin, v))
count += 1
return pathsstationController 部分
1 | # encoding=utf-8 |
- stationController中具体使用的函数分析
1 | # 确定出发点和最后的站点 |
flask app的分析:
- flask具体作用类似与springboot,是python后端的一个框架,对新手及其友好,而json包则是用来处理json输出格式的一个工具
- 具体详情查看flask官方中文文档
1 | # encoding=utf-8 |
- flask具体demo已经部署在服务器上,返回信息,请求方式等具体请查看接口文档:传送门
安卓部分
- 编译器使用AS进行开发
- 使用友好的流线式布局进行开发
- 布局代码如下:
1 | <?xml version="1.0" encoding="utf-8"?> |
对与spinner(下拉框的集联操作使用xml进行了储存)
当选中相应的station值时进行选择第二个spinner中的应该显示的值
格式如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="station">
<item>-站点线路-</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>5</item>
<item>6</item>
<item>9</item>
</string-array>
<string-array name="station1">
<item>-站点-</item>
<item>刘园</item>
<item>西横堤</item>
<item>果酒厂</item>
<item>本溪路</item>
<item>勤俭道</item>
<item>洪湖里</item>
<item>西站</item>
<item>西北角</item>
<item>西南角</item>
<item>二纬路</item>
<item>海光寺</item>
<item>鞍山道</item>
<item>营口道</item>
<item>小白楼</item>
<item>下瓦房</item>
<item>南楼</item>
<item>土城</item>
<item>陈塘庄</item>
<item>复兴门</item>
<item>华山里</item>
<item>财经大学</item>
<item>双林</item>
<item>李楼</item>
</string-array>
......
</resources>代码控制:
1 | .... |
- demo图
- 使用okhttps获得json数据,get方式
- 相应的as添加jar包方式:
- 打开路径:file->project Structure->Depndences->app->+号 搜索相应的包即可
- 博主用的是 okhttp:2.7.5的包
1 | public void SendGetRequest(final String url,final String startpos,final String endpos){ |