地鐵線路最短路徑(實現)


主要功能


提供一副地鐵線路圖,計算指定兩站之間最短(最少經過站數)乘車路線;輸出指定地鐵線路的所有站點。以北京地鐵為例,地鐵線路信息保存在地鐵線路信息.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

總結

通過這次的作業我深刻認識到自己能力的不足,對於知識掌握的不熟練,不理解。
第一次使用博客園寫作業,對於專業能力有了全新的認識。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM