主要功能
提供一副地鐵線路圖,計算指定兩站之間最短(最少經過站數)乘車路線;輸出指定地鐵線路的所有站點。以北京地鐵為例,地鐵線路信息保存在地鐵線路信息.txt中,格式如下:
地鐵線路總數
線路名1 站名1 站名2 站名3 ...
線路名2 站名1 站名2 站名3 ...
線路名3 站名1 站名2 站名3 ......
實現語言
python
實現算法
BFS
類職責划分
ReadFile(file_name):讀入地鐵信息
build_subway(**lines):構建圖結構
shortest_path(start, goal):用BFS找最短路徑
核心代碼
數據讀入:
def ReadFile(file_name):
data=dict()
with open(file_name, "rt", encoding="utf-8") as file:
n=int(file.readline())
for i in range(n):
value=""
line=file.readline().split()
for i in line[1:]:
value=value+i+" "
data[line[0]]=value
return data
構建圖結構:
def BuildMap(**lines):
for key in lines.keys():
value = lines[key]
lines[key] = value.split()
stations = set()
for key in lines.keys():
stations.update(set(lines[key]))
system = {}
for station in stations:
next_station = {}
for key in lines:
if station in lines[key]:
line = lines[key]
idx = line.index(station)
if idx == 0:
next_station[line[1]] = key
elif idx == len(line)-1:
next_station[line[idx-1]]=key
else:
next_station[line[idx-1]] = key
next_station[line[idx+1]] = key
system[station] = next_station
return system
處理環路:
def DealCircle(BJ_Subway): #發現環路時將其頭尾相連
BJ_Subway[u'西直門'][u'積水潭'] = '二號線'
BJ_Subway[u'積水潭'][u'西直門'] = '二號線'
BJ_Subway[u'勁松'][u'潘家園'] = '十號線'
BJ_Subway[u'潘家園'][u'勁松'] = '十號線'
return BJ_Subway
fin_subway = DealCircle(tmp)
用BFS找最短路徑:
def FindPath(start, goal):
if start == goal:
return [start]
explored = set()
queue = [ [start, ('',0)]]
while queue:
path = queue.pop(0)
s = path[-2]
linenum,changetimes = path[-1]#增加判斷換乘的元組,linenum表示上一次的線路,changetimes表示
if s == goal:
return path
for state, action in fin_subway[s].items():
if state not in explored:
linechange = changetimes
explored.add(state)
if linenum != action:
linechange += 1
path2 = path[:-1] + [action, state, (action, linechange)]
queue.append(path2)
queue.sort(key=lambda path:path[-1][-1])
return []
測試用例
兩站
換乘站到換乘站
代碼已上傳至github:https://github.com/QQQy120/Subway.git
總結
通過這次的作業我深刻認識到自己能力的不足,對於知識掌握的不熟練,不理解。
第一次使用博客園寫作業,對於專業能力有了全新的認識。