from itertools import permutations
from utils.read_write import readJson, writeOneJSON
import pandas as pd
subway_dict = []
transfer_dict = []
def getRoute(year):
src = r'D:\data\地铁数据\SZ_Metro\min_way\route_time\\'
try :
yearStop = pd.read_csv(src + 'route_time_length_{}.csv'.format(year),usecols=[0,6,7,10],encoding='gbk')
except Exception as e:
yearStop = pd.read_csv(src + 'route_time_length_{}.csv'.format(year), usecols=[0, 6, 7, 10], encoding='utf-8')
for feature in yearStop.itertuples(index=False):
line = str(int(getattr(feature,'Layer').split('号')[0]))
SStation = getattr(feature,'SStation')
EStation = getattr(feature,'EStation')
Length_Dow = getattr(feature,'Length_Dow')
start = line+'-'+SStation
end = line+'-'+EStation
subway_dict.append([start,end,Length_Dow])
transfer = {}
src = 'D:\学习文件\项目文件\方舆地铁分析系统\data\SZ_Metro_LineSUM_Stoppoint\\'
def getTransfer(year):
# 站点编号 站点名称 线路 是否换乘站
station = pd.read_csv('D:\data\地铁数据\SZ_Metro\metro_station_2020.txt', sep='\t',
usecols=[1, 2, 4, 5],
encoding='gbk')
yearStop = readJson(src + 'SZ_Metro_LineSUM_Stoppoint_{}_GCJ02.json'.format(year))
features = yearStop['features']
for feature in features:
properties = feature['properties']
CName = properties['CName']
change = station[station['站点名称'] == CName]
if change.shape[0]>0:
changeS = change.iat[0, 3]
if changeS == '是':
NAME = properties['NAME']
linename = str(int(NAME.split('-')[0]))
line_station = linename+'-'+CName
if CName not in transfer.keys():
transfer[CName] = []
transfer[CName].append(line_station)
# 列举排列结果[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
data4 = list(permutations([i for i in range(0,4)],2))
for key in transfer.keys():
data = transfer[key]
if len(data) ==2 :
transfer_dict.append([data[1],data[0],120])
transfer_dict.append([data[0], data[1],120])
elif len(data) ==3:
transfer_dict.append([data[1], data[0],180])
transfer_dict.append([data[0], data[1],180])
transfer_dict.append([data[0], data[2],180])
transfer_dict.append([data[2], data[0],180])
transfer_dict.append([data[1], data[2],180])
transfer_dict.append([data[2], data[1],180])
elif len(data) ==4:
for one in data4:
transfer_dict.append([data[one[0]], data[one[1]],240])
# print(transfer_dict)
'''
弗洛伊德算法(Floyd算法)
'''
class Vertex:
def __init__(self, key):
self.id = key
self.connectedTo = {}
def addNeighbor(self, nbr, weight=0):
self.connectedTo[nbr] = weight
def __str__(self):
return str(self.id) + ' connectedTo: ' + str([x.id for x in self.connectedTo])
def getConnections(self):
return self.connectedTo.keys()
def getId(self):
return self.id
def getWeight(self, nbr):
return self.connectedTo[nbr]
class Graph:
def __init__(self):
self.vertList = {}
self.numVertices = 0
def addVertex(self, key):
self.numVertices = self.numVertices + 1
newVertex = Vertex(key)
self.vertList[key] = newVertex
return newVertex
def getVertex(self, n):
if n in self.vertList:
return self.vertList[n]
else:
return None
def __contains__(self, n):
return n in self.vertList
def addEdge(self, f, t, cost=0):
if f not in self.vertList:
nv = self.addVertex(f)
if t not in self.vertList:
nv = self.addVertex(t)
self.vertList[f].addNeighbor(self.vertList[t], cost)
def getVertices(self):
return self.vertList.keys()
def __iter__(self):
return iter(self.vertList.values())
def Floyd(Graph, ShortestPath):
global path
NodeNum = len(Graph)
lastShortestDistance = [[0 for i in range(NodeNum)] for j in range(NodeNum)]
currentShortestDistance = [[0 for i in range(NodeNum)] for j in range(NodeNum)]
path = [[0 for i in range(NodeNum)] for j in range(NodeNum)]
for i in range(NodeNum):
for j in range(NodeNum):
path[i][j] = j
for i in range(NodeNum):
for j in range(NodeNum):
lastShortestDistance[i][j] = Graph[i][j]
currentShortestDistance[i][j] = lastShortestDistance[i][j]
for k in range(NodeNum):
for i in range(NodeNum):
for j in range(NodeNum):
if lastShortestDistance[i][j] > lastShortestDistance[i][k] + lastShortestDistance[k][j]:
currentShortestDistance[i][j] = lastShortestDistance[i][k] + lastShortestDistance[k][j]
path[i][j] = path[i][k]
lastShortestDistance = currentShortestDistance
for i in range(NodeNum):
for j in range(NodeNum):
# if i==j:
# ShortestPath[i][j]=0
# else:
ShortestPath[i][j] = currentShortestDistance[i][j]
print("path is: ", path)
print("shortestPath is: ", ShortestPath)
# print(currentShortestDistance)
return None
def printPath(i, j, shortestPath, path):
print(zhandian[i] + "----" + zhandian[j] + "\n最短时间:" + str(shortestPath[i][j]) + "s\n路径:\n" + zhandian[i])
temp = path[i][j]
odName = zhandian[i] + "_" + zhandian[j]
jsonData = {}
routeSplitData = [zhandian[i]]
while (temp != j):
routeSplitData.append(zhandian[temp])
print("-->" + zhandian[temp])
temp = path[temp][j]
routeSplitData.append(zhandian[j])
jsonData[odName] = routeSplitData
mainJson.append(jsonData)
print("-->" + zhandian[j])
if __name__ == "__main__":
save = 'D:\data\地铁数据\SZ_Metro\min_way\min_route_floyd\\'
mainJson = []
for i in range(2020,2021):
year = str(i)
getRoute(year)
getTransfer(year)
g = Graph()
vel = 10 # 地铁的速度 m/s
for x in subway_dict:
g.addEdge(x[0], x[1], int(float(x[2]) / vel)) # 由距离得到时间
g.addEdge(x[1], x[0], int(float(x[2]) / vel)) # 双向都有
for x in transfer_dict:
g.addEdge(x[0], x[1], int(float(x[2]))) # 换站给的直接就是时间
# print(len(g.getVertices())) #打印图中顶点数
# print(g.getVertices()) #打印图中所有的顶()点
zhandian = []
for i in g.getVertices():
zhandian.append(i)
zhandian = tuple(list(zhandian))
x = float('inf')
matrix = [[x for i in range(338)] for i in range(338)]
for i in range(338):
matrix[i][i] = 0
for v in g: # 对图中的每一个顶点,获取与它有连接关系的顶点
# print(v)
for w in v.getConnections():
# print("( %s , %s )" % (v.getId(), w.getId()))
# print("Time:%s" % v.getWeight(w)) #获取相邻两个顶点之间的时间s
# print(zhandian.index(w.getId()))
time = v.getWeight(w)
matrix[zhandian.index(v.getId())][zhandian.index(w.getId())] = time
# matrix[i][j]=time
# j+=1
# i+=1
# pass
# 除了每一个顶点到自身的距离不对外,其它路径啥的都没问题
# graph=[[0,1,1,10],[1,0,10,10],[1,10,0,1],[10,10,1,0]]
# graph=[[0,5,7,0,3],[5,0,0,4,8],[7,0,0,2,1],[0,4,2,0,6],[3,8,1,6,0]] #图的邻接表示
# graph=[[0,12,0,0,0,16,14],[12,0,10,0,0,7,0],[0,10,0,3,5,6,0],[0,0,3,0,4,0,0],[0,0,5,4,0,2,8],[16,7,6,0,2,0,9],[14,0,0,0,8,9,0]]
graph = matrix
nodeNum = len(graph)
shortestPath = [[0 for i in range(nodeNum)] for j in range(nodeNum)]
print("计算时间比较长,请耐心等待几分钟!")
Floyd(graph, shortestPath)
# while True:
# try:
# start = input("请输入起点: ")
# s = zhandian.index(start)
# except:
# start = input("请重新输入起点:")
# s = zhandian.index(start)
# try:
# end = input("请输入终点: ")
# e = zhandian.index(end)
# except:
# end = input("请重新输入终点: ")
# e = zhandian.index(end)
# if s < e:
# printPath(s, e, shortestPath, path)
# else:
# printPath(e, s, shortestPath, path)
allStation = []
yearStop = readJson(src + 'SZ_Metro_LineSUM_Stoppoint_{}_GCJ02.json'.format(year))
features = yearStop['features']
for feature in features:
properties = feature['properties']
CName = properties['CName']
NAME = properties['NAME']
linename = str(int(NAME.split('-')[0]))
line_station = linename + '-' + CName
allStation.append(line_station)
for start in allStation:
for end in allStation:
if start != end:
s = zhandian.index(start)
e = zhandian.index(end)
printPath(s, e, shortestPath, path)
writeOneJSON(mainJson, save + year + '.json')
如需数据示例或帮忙请私聊我!