python_计算重庆地铁最短路径(Floyd)和断面客流量

python_计算重庆地铁最短路径(Floyd)和断面客流量,第1张

概述1、摘要本文主要讲解:使用地铁客流业务逻辑来计算重庆地铁断面客流量主要思路:使用Floyd佛洛依德算法找到重庆地铁的最短路径;计算每个段面的客流量(算某个时间段重庆所有断面的客流量)把断面客流量加到json里面去,利用累加的方式去计算2、数据介绍重庆各站点间的区间长度,18年 1、摘要

本文主要讲解:使用地铁客流业务逻辑来计算重庆地铁断面客流量
主要思路:

使用Floyd佛洛依德算法找到重庆地铁的最短路径;计算每个段面的客流量(算某个时间段重庆所有断面的客流量)把断面客流量加到Json里面去,利用累加的方式去计算2、数据介绍

重庆各站点间的区间长度,18年的数据,共8条线142个站点


某个时间段的OD客流量,采用矩阵的方式进行存储

3、相关技术

1、panda读取文件后的数据为Dataframe,关于Dataframe的遍历方法itertuples
2、Json数据的key,value格式,适合存储与计算断面客流量

4、完整代码

代码输出如下:


Json格式的如下:


步骤1:根据每个站点的距离计算各个站点间的最短路径

from itertools import permutationsimport pandas as pdfrom my_utils.read_write import writeOneCsv, writeOneJsonsubway_dict = []transfer_dict = []src = r'D:\项目\重庆地铁断面客流量计算\\'try:    yearStop = pd.read_excel(src + '区间长度.xlsx', en@R_301_5563@='gbk')except Exception as e:    yearStop = pd.read_excel(src + '区间长度.xlsx', en@R_301_5563@='utf-8')def getRoute():    for feature in yearStop.itertuples(index=False):        line = str(getattr(feature, '线路名称'))        sstation = str(getattr(feature, 'sstation'))        EStation = str(getattr(feature, 'EStation'))        Length_Dow = getattr(feature, 'Length_Dow')        start = line + '-' + sstation        end = line + '-' + EStation        subway_dict.append([start, end, Length_Dow])transfer = {}def getTransfer():    '''sstation	EStation	Length_Dow	线路名称'''    features = yearStop.groupby('sstation')    for name, feature in features:        if feature.shape[0] > 0:            for one in feature.itertuples():                linename = getattr(one, '线路名称')                line_station = str(linename) + '-' + str(name)                if name not in transfer.keys():                    transfer[name] = []                transfer[name].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])# getTransfer()'''弗洛伊德算法(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 Nonedef 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])'''sstation	EStation	Length_Dow	线路名称'''def splitTime(i, j, shortestPath, path):    temp = path[i][j]    routeSplitData = [zhandian[i]]    time = shortestPath[i][j]    while (temp != j):        routeSplitData.append(zhandian[temp])        temp = path[temp][j]    routeSplitData.append(zhandian[j])    start = zhandian[i]    sstation = routeSplitData[len(routeSplitData) - 2].split('-')[1]    EStation = zhandian[j].split('-')[1]    if sstation != EStation:        save = [start, sstation, EStation, time]        print(save)        writeOneCsv(save, src+r'all.csv')def writeOneCsv(relate_record, src):    with open(src, 'a', newline='\n') as csvfile:        writer = csv.writer(csvfile)        writer.writerow(relate_record)#   写Json文件,一个数据一个文件def writeOneJson(relate_record, src):    Json_str = Json.dumps(relate_record, ensure_ascii=False)    with open(src, 'w', en@R_301_5563@='utf-8') as Json_file:        Json_file.write(Json_str)    Json_file.close()if __name__ == "__main__":    mainjson = []    getRoute()    getTransfer()    g = Graph()    # vel = 10  # 地铁的速度 m/s    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:  # 对图中的每一个顶点,获取与它有连接关系的顶点        for w in v.getConnections():            time = v.getWeight(w)            matrix[zhandian.index(v.getID())][zhandian.index(w.getID())] = time    graph = matrix    nodeNum = len(graph)    shortestPath = [[0 for i in range(nodeNum)] for j in range(nodeNum)]    print("计算时间比较长,请耐心等待几分钟!")    Floyd(graph, shortestPath)    allStation = []    '''sstation	EStation	Length_Dow	线路名称'''    for one_s in yearStop.itertuples():        line = str(getattr(one_s, '线路名称'))        start = line + '-' + str(getattr(one_s, 'sstation'))        end = line + '-' + str(getattr(one_s, 'EStation'))        if start not in allStation:            allStation.append(start)        if end not in allStation:            allStation.append(end)    for start in allStation:        for end in allStation:            if start != end:                s = zhandian.index(start)                e = zhandian.index(end)                printPath(s, e, shortestPath, path)                # splitTime(s, e, shortestPath, path)    writeOneJson(mainjson, src + '最短路径.Json')

主运行程序入口

import pandas as pdfrom my_utils.read_write import writeOneJson, readJson, writeOneCsv'''此文件用于计算重庆地铁线路断面客流量计算步骤:1、找到最短路径;2、计算每个段面的客流量(算0这个时间段所有深圳所有断面的客流量)'''src = r'D:\项目\重庆地铁断面客流量计算\\'try:    od_people = pd.read_excel(src + 'OD客流量.xlsx', en@R_301_5563@='gbk')except Exception as e:    od_people = pd.read_excel(src + 'OD客流量.xlsx', en@R_301_5563@='utf-8')try:    yearStop = pd.read_excel(src + '区间长度.xlsx', en@R_301_5563@='gbk')except Exception as e:    yearStop = pd.read_excel(src + '区间长度.xlsx', en@R_301_5563@='utf-8')all_split = []for one_s in yearStop.itertuples():    line = str(getattr(one_s, '线路名称'))    start = line + '-' + str(getattr(one_s, 'sstation'))    end = line + '-' + str(getattr(one_s, 'EStation'))    all_split.append(start + '_' + end)    all_split.append(end + '_' + start)def add_count(split, od_count, routeSplitJson):    if split not in routeSplitJson.keys():        routeSplitJson[split] = 0    # 某个断面某个时间加入od的数量    routeSplitJson[split] = routeSplitJson[split] + od_countdef readJson(filepath):    try:        with open(filepath, 'r', en@R_301_5563@='GBK') as file_open:            data = Json.load(file_open)        file_open.close()        return data    except:        try:            with open(filepath, 'r', en@R_301_5563@='utf-8') as file_open:                data = Json.load(file_open)                file_open.close()                return data        except:            with open(filepath, 'r', en@R_301_5563@="unicode_escape") as file_open:                data = Json.load(file_open)            file_open.close()            return datadef routeSplit(df, routeSplitJson):    minWays = readJson(src + '最短路径.Json')    min_ways = {}    for one in minWays:        keys = one.keys()        for i in keys:            if i not in min_ways.keys():                min_ways[i] = {}                # 某个断面某个时间加入od的数量            min_ways[i] = one[i]    allStation = []    for one_s in yearStop.itertuples():        line = str(getattr(one_s, '线路名称'))        start = line + '-' + str(getattr(one_s, 'sstation'))        end = line + '-' + str(getattr(one_s, 'EStation'))        if start not in allStation:            allStation.append(start)        if end not in allStation:            allStation.append(end)    # o_station,d_station,tw,od    for row in df.itertuples(index=False):        line = str(getattr(row, '线路'))        start = line + '-' + str(getattr(row, '车站编号'))        for n in range(len(allStation)):            if start != allStation[n]:                od_count = row[n + 2]                od_name = start + '_' + allStation[n]                # 获取到最短路径的数据                minStations = min_ways[od_name]                for m in range(0, len(minStations)):                    if m + 1 < len(minStations):                        split = minStations[m] + '_' + minStations[m + 1]                        if split in all_split:                            # 把断面客流量加到Json里面去                            add_count(split, od_count, routeSplitJson)def final():    routeSplitJson = {}    routeSplit(od_people, routeSplitJson)    writeOneJson(routeSplitJson, src + '重庆断面客流量.Json')def deal_Json():    data = readJson(src + '重庆断面客流量.Json')    # 上行客流量,断面,下行客流量    alr = []    one = []    for key in data.keys():        if key not in alr:            split_data = key.split('_')            add = split_data[0].split('-')[1] + '-' + split_data[1].split('-')[1]            down_key = split_data[1] + '_' + split_data[0]            alr.append(down_key)            alr.append(key)            if down_key in data.keys():                writeOneCsv([data[key], add, data[down_key]], src + '重庆地铁断面客流量.csv')            else:                writeOneCsv([data[key], add, 0], src + '重庆地铁断面客流量.csv')if __name__ == '__main__':    deal_Json()    final()

read_write文件在我的下载里有,请自行搜索
如需数据示例请私聊我,有偿

5、参考链接

60行python代码_计算深圳地铁断面客流量

python_pandas_计算深圳地铁线路断面客流量

总结

以上是内存溢出为你收集整理的python_计算重庆地铁最短路径(Floyd)和断面客流量全部内容,希望文章能够帮你解决python_计算重庆地铁最短路径(Floyd)和断面客流量所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1185100.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存