import os M = 15 # 校園景點數量 INF = 0x3f3f3f3f class Campus: att = ["","正門","科技樓","第一教學樓","基礎教學樓","圖書館","北小門","宿舍區","西操場","學二食堂","澡堂","體育館","學一食堂"] #景點 inf = [['']] * M edges = [[INF] * M] * M #邊 Nodes_Num = 0 edges_Num = 0 #總結點數,總邊數 def putMap(): print(" ") print(" 石家莊鐵道大學校園導遊圖 ") print(" ") print(" ") print(" =================================================================================================== ") print(" ----1:正門 ") print(" / \\ / | \\ ") print(" / \\ / | \\ ") print(" / ----- | | ----- 2:科技樓------ ") print(" / \\ | | | | | ") print(" 9:學二食堂 --- ----3:第一教學樓 --------- | | ") print(" =================================================================================================== ") print(" | | | | / | 5:圖書館 \ ") print(" | | | | / | \\ \8:西操場 ") print(" | / \\ | / | -- 11:體育館 ") print(" 12:學一食堂 / -4:基礎教學樓 | | ") print(" \\ / | / | ") print(" \\ / | / /------------ ") print(" =================================================================================================== ") print(" 7:宿舍區----------------- | / | ") print(" | \ | / | ") print(" | \ 10: 澡堂------- | ") print(" | \ | | ") print(" -----------------------6:北小門---------------------------------- ") print(" ") print(" =================================================================================================== ") def putMenu(): print("") print(" * * ******** * * ******** ") print(" * * * * * * * ") print(" ******* ******* * * * * ") print(" * * * * * * * ") print(" * * ******** ******* ******* ******** ") print(" ") print(" ") print(" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =") print(" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =") print(" = = = =") print(" = = 歡迎使用石家莊鐵道大學校園導航系統 = =") print(" = = = =") print(" = = 請選擇服務: = =") print(" = = = =") print(" = = 1.學校資訊 可查詢景點 當前地點和目的地 4.退出系統 = =") print(" = = = =") print(" = = 2.尋找兩景點之間的最短路徑 = =") print(" = = = =") print(" = = 3.尋找景點之間的最短路徑 = =") print(" = = = =") print(" = = = =") print(" = = = =") print(" = = = =") print(" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =") print(" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =") print() op = input(" 請根據你的需求選擇操作:") return op def getCampus(g): file = r'./map.txt' inff = r'./information.txt' for i in range(1,g.Nodes_Num+1): for j in range(1,g.Nodes_Num+1): if i == j: g.edges[i][j] = 0 with open(file) as f: i = 0 for line in f: if i == 0: tmp1,tmp2 = line.split(',') g.Nodes_Num = int(tmp1) g.edges_Num = int(tmp2) i = 1 else: x, y, w = line.split(',') g.edges[int(x)][int(y)] = g.edges[int(y)][int(x)] = int(w) with open('information.txt','r', encoding='utf-8') as f: for line in f: tmp1,tmp2 = line.split(' ') poi = int(tmp1) g.inf[poi] = tmp2 def getinf(g): poi = int(input("請輸入您想了解到景點,0結束:")) while poi != 0: print("以下是該景點資訊:") print(g.inf[poi]) poi = int(input("請輸入您想了解到景點,0結束:")) def check(ch): if ch < 0 or ch > 12: print("\n您的輸入有誤,請輸入0~12之間的數字!") return False else: return True def Search(g): number = 0 while True: putMap() print("請問您想檢視哪個景點(請輸入景點編號,輸入0結束):") input(number) # system("cls") #清空螢幕 if(check(number)): if(number == 0): break else: print("景點編號:{}".format(g.att[number].num)) print("景點名稱:{}".format(g.att[number])) class passing(): pathStack = [[0]*M] ##路徑棧 top = 0 count = 0 #棧頂位置,路徑數 visited = [[False]*M] #判斷是否已經經過 #Floyd演算法求兩景點間的一條最短的路徑 class DIS: distence = [[0] * M] * M #距離向量 path = [[0] * M] * M def shortPath(g,dis): for i in range(1,g.Nodes_Num+1): #初始化距離向量矩陣與路徑向量矩陣 for j in range(1,g.Nodes_Num+1): dis.distence[i][j] = g.edges[i][j] if i != j and dis.distence[i][j] != INF: dis.path[i][j] = i #表示如果i和j相鄰,i到j需要經過i else: dis.path[i][j] = -1 #否則用 -1代表當前兩點不可達 for k in range(1,g.Nodes_Num+1): #遞推求解每兩景點的最短路徑 for i in range(1,g.Nodes_Num+1): for j in range(1,g.Nodes_Num+1): if dis.distence[i][j] > (dis.distence[i][k] + dis.distence[k][j]): #如果發現引入k點可以使得路徑更短 dis.distence[i][j] = dis.distence[i][k] + dis.distence[k][j] #更新最短路徑長度 dis.path[i][j] = k # 更新最短路徑上的經結點 # 遞迴實現列印兩點間的最短路徑(不包括起始點) def Floyd_Print(g,dis,start,end): #遞迴基:如果兩點相鄰或者兩點不可達,結束遞迴 if dis.path[start][end] == -1 or dis.path[start][end] == end or dis.path[start][end] == start: return else: Floyd_Print(g,dis, start, dis.path[start][end]) #將中間點作為終點繼續列印路徑 print('{}->'.format(g.att[dis.path[start][end]]),end='') #列印中間景點名字 Floyd_Print(g, dis,dis.path[start][end], end) #將中間點作為起點繼續列印路徑 #輸出並列印兩點間的最短路徑 def print_shortPath(g,dis): start = int(input(" 請輸入起點編號:")) end = int(input(" 請輸入終點編號:")) print(" {}到{}的最短距離是{}M".format(g.att[start],g.att[end],dis.distence[start][end])) print(" 最佳遊覽路線:",end='') print('{}->'.format(g.att[start]),end='') #輸出路徑上的起點 Floyd_Print(g,dis,start, end) #輸出路徑上的中間點 print(g.att[end]) #輸出路徑上的終點 def bestPath(g,dis): vNum = [0,0,0,0,0,0,0,0,0,0,0,0,0] count = 1 #記錄使用者輸入的編號資訊 len = 500 #統計全程路徑總長 vNum[count] = int(input(" 請輸入你要遊覽的景點的編號(輸入0結束輸入):")) while vNum[count] != 0 and count <= 12: if vNum[count] == 0: break count += 1 vNum[count] = int(input(" 請輸入你要遊覽的景點的編號(輸入0結束輸入):")) print(" 已為您挑選最佳訪問路徑:") i = 1 while vNum[i] > 0 and vNum[i + 1] > 0 : #遍歷所有輸入的景點 print("{}->".format( g.att[vNum[i]]),end='') #輸出路徑上的起點 Floyd_Print(g,dis, vNum[i],vNum[i + 1]) #利用Floyd演算法得到這兩點之間的最短路徑 len += dis.distence[vNum[i]][vNum[i + 1]] #算出最短路長度 i += 1 print(g.att[vNum[count - 1]]) #輸出路徑上的終點 print(" 全程總長為:{}m".format(len)) if __name__ == '__main__': g = Campus() dis = DIS() p = passing() getCampus(g) #從檔案讀取資訊建立校園地圖 shortPath(g,dis) #透過Floyd求出distence表與path表 while True : op = putMenu() while op != '0': #列印主選單 if op == '1': putMap() getinf(g) os.system("pause") os.system('cls') op = putMenu() elif op == "2": putMap() print_shortPath(g,dis) #兩景點間最短路徑查詢 os.system("pause") os.system('cls') op = putMenu() elif op == "3": putMap() bestPath(g,dis) #多景點間訪問最優路線查詢 os.system("pause") os.system('cls') op = putMenu() elif op == '4': print("感謝使用!") exit() else: print(" 對不起!沒有該選項對應的操作.") os.system("pause") os.system('cls') op = putMenu()