基于图结构实现地铁乘坐线路查询
github-python算法和flaskapp部分:repo
github-android部分:repo
flaskapp接口文档:传送门
深度了解Dijkstra优化算法:传送门
问题描述
编写一个程序实现地铁最短乘坐(站)线路查询,输入为起始站名和目的站名,输出为从起始站到目的站的最短乘坐站换乘线路。
1.采用Dijkstra算法实现,使用优先队列对性能进行了优化;
2.如果两站间存在多条最短路径,则输出其中的一条即可;
本次项目实现采用了flask作为后端提供接口服务,使用androidApp进行get请求获得数据,显示在Textview中
设计需求
确定储存地铁站文件的格式文件 (已确认使用json格式和文本格式)
确定读取地铁站数据的方式 (使用python的file打开命令)
确定获取两站点最小站点数的算法方式
进行外表封装
进行输出格式的确定
性能测试
最后结果检查
数据存储格式
stationline.txt文本为存储的地图数据文本,格式如下图所示:
使用0与1来分别表示是否需要换乘
地铁线路条数
线路x 线路x站数
站名1 是否需要换乘
站名2 是否需要换乘
...
数据示例
2 20
曹庄 0
卞兴 0
芥园西道 0
咸阳路 0
长虹公园 1
广开四马路 0
西南角 1
鼓楼 0
东南角 0
建国道 0
天津站 1
远洋国际中心 0
顺驰桥 0
靖江路 1
翠阜新村 0
屿东城 0
登州路 0
国山路 0
数据文本读取代码
with open(os.path.join(os.path.abspath('..'), "station/stationLine.txt"), "r") as f:
TOTAL = f.readline()
for line in f.readlines():
if line != '\n':
line = line.rstrip('\n')
line = line.split(' ')
if line[0] in LINEDATA:
linei = line[0]
continue
line[1] = linei
line0 = line[0]
intline = int(line[1])
if intline not in data.keys():
data[intline] = []
data[intline].append(line0)
else:
data[intline].append(line0)
if line0 not in datanum.keys():
datanum[line0] = [intline]
else:
datanum[line0].append(intline)
打印结果
stationline {"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,.....}
获得点与点之间的最短路径:
def find_shortest_path(graph, start, end, path=[]):
# 查找最短路径
path = path + [start]
if start == end:
return path
if not start in graph.keys():
return None
shortest = None
for node in graph[start]:
if node not in path:
newpath = find_shortest_path(graph, node, end, path)
if newpath:
if not shortest or len(newpath) < len(