def get_scheme(source, target, G_schedule, dict_parents, prepareT=0.25): """ 在起终点之间有很多的车,找一班最近的列车 G_schedule: 列车时刻表建的有向图 dict_parents: 上一代的信息 return: 乘坐的最佳列车的基本信息 """ last_arrive = dict_parents[source]['arrive'] ## 前车的到站时间 last_travelT = dict_parents[source]['travelT'] ## 在以前已经用掉的旅行时间 all_trains = list(G_schedule[source][target].items()) temp_travelT = 10000 out_info = {} for depart, info in all_trains: delta_t = get_deltaT(last_arrive, depart, unit='h') if delta_t >= 12 or delta_t < prepareT: ### 相差十二小时以上是无法判断的 continue during = get_deltaT(info['depart'], info['arrive'], unit="h") travelT = last_travelT + delta_t + during ## 已用 + 换乘 + 本次 if travelT < temp_travelT: temp_travelT = travelT daysign = 1 if strT_to_floatT(info['arrive']) < strT_to_floatT( info['depart']) else 0 #### 非必须 out_info = info ## 计算一个在当前车上的停留时间 out_info[ 'travelT'] = travelT # 前车已用的旅行时间+准备时间,准备好到真正发车的时间,本次列车将花费的时间 out_info['scheduleDelay'] = delta_t out_info['daysign'] = daysign out_info['last_depart_station'] = source out_info['during'] = during return out_info
def get_driving_origins(G_HSRGrid, originGrid, str_startT): """ 确定从家里出发,驾车可达的源车站 return: """ startT = strT_to_floatT(str_startT, unit='m') ## min dict_ChildInfo = {} carAccessHSR = list(nx.neighbors(G_HSRGrid, originGrid)) ## 1.5小时内开车到达的车站 ### 组装一个初始的 dict_ChildInfo 字典 for s in carAccessHSR: int_arriveT = startT + round( G_HSRGrid[s][originGrid]['duration_s'] / 60) # min 为单位 arriveT = str((int_arriveT % 1440) // 60).zfill(2) + ':' + str( int((int_arriveT % 1440) % 60)).zfill(2) # 字符串 dict_ChildInfo[s] = { 'train_code': 'carDriving', 'depart_station': '--', 'arrive_station': s, 'depart': str_startT, 'arrive': arriveT, } dict_ChildInfo[s]['travel_time'] = get_deltaT(str_startT, arriveT, unit='min') dict_ChildInfo[s]['total_travelT'] = dict_ChildInfo[s]['travel_time'] return dict_ChildInfo
def update_Candidate_cardriving(source, dict_Candidate, dict_Sure, G_stationPair, dict_StillSure, heap): """ 功能上与 update_Candidate 类似, 但是注意这里输入的图变为了 G_stationPair --> 两车站间驾车需要的时间 (所以也就是说,update_Candidate 更新的是 从source出发,“乘坐火车”的路径, 而 本函数 更新的是 从source出发,“驾车”的路径)--> 模仿同城不同站换乘的情况 """ list_updates = [] if source not in G_stationPair: # 不存在短时间内驾车可达的车站,无需执行任何操作 return [] list_scheme_of_source = dict_Sure[source] last_arriveT = list_scheme_of_source[-1]['arrive'] # 到站时间 past_travelT = list_scheme_of_source[-1]['total_travelT'] # 已用的总旅行时间 neighbors = set(nx.neighbors(G_stationPair, source)) - set( dict_Sure.keys()) - set(dict_StillSure.keys()) # 还是把确定的去掉 ##### for name in neighbors: if name in dict_StillSure: dict_Candidate[name] = dict_StillSure[name] ##################### del dict_StillSure[name] ##################################### continue ######################################################### driveT = round( G_stationPair[source][name]['duration_min']) # 从source到name totalT = past_travelT + driveT if name not in dict_Candidate or dict_Candidate[name][-1][ 'total_travelT'] > totalT: # 新添了路径或路径更短了,添加/更新 # 生成这段的出行方案 info = { 'train_code': 'carDriving', 'depart_station': source, 'arrive_station': name, 'depart': last_arriveT } int_arriveT = strT_to_floatT(last_arriveT, unit='m') + driveT # min 为单位 info['arrive'] = str( (int_arriveT % 1440) // 60).zfill(2) + ':' + str( int((int_arriveT % 1440) % 60)).zfill(2) # 字符串 info['travel_time'] = driveT info['total_travelT'] = totalT #if name not in dict_Candidate or len(dict_Candidate[name])>len(list_scheme_of_source + [info]): ## 2019.10.14 改 dict_Candidate[name] = list_scheme_of_source + [info] heapq.heappush(heap, (dict_Candidate[name][-1]['total_travelT'], name)) # 加入堆 ############### list_updates.append(name) return list_updates
def func(NAME): originGrid = str( lib_grid.get_nearestGrid(eval(dict_CityLocs[NAME]), 1 / 12)) if originGrid not in G_PortGrid: print('Grid point is not in G_HSRGrid. %s:%s' % (NAME, originGrid)) return 0 for str_startT in list_str_startT: # 生成所有时间点 #str_startT = '00:10' dict_Sure = {} ## 存储已经找到最短路径的点 dict_Candidate = {} ## 存储找到路径的 ### 1.1 初始化,从家cardriving可达的车站 originInfo_station = lib_transferTWO.get_driving_origins( G_PortGrid, originGrid, str_startT) ### 1.2 构造成方案列表的形式 for name in originInfo_station: dict_Candidate[name] = [originInfo_station[name]] while dict_Candidate: ### 2.1 选出一个旅行时间最短的目的 车站/机场 添加进 dict_Sure中 selected = lib_transferTWO.add_shortest2Sure( dict_Sure, dict_Candidate) ### 2.2 用该确定最短路径的节点更新所有其他节点的路径 (机场-->机场, 车站--> 车站) updates = lib_transferTWO.update_Candidate(selected, dict_Candidate, dict_Sure, G_schedule) updates2 = lib_transferTWO.update_Candidate_cardriving( selected, dict_Candidate, dict_Sure, G_PortPort, {}) ### 3处理结果 ### 简化结果,只取最短时间,不要路径 dict_accessed = {} for name in dict_Sure: dict_accessed[name] = dict_Sure[name][-1]['total_travelT'] #ttt.duration('Scheme ready') df = lib_transferTWO.save_scheme(dict_Sure) ############### 生成详细信息 #path = '/run/media/pengfei/OTHERS/每日总结/20191015/%s/'%NAME path = '/run/media/pengfei/OTHERS/每日总结/20191016-2/%s/' % NAME if not os.path.exists(path): # 判断文件夹是否已经存在 os.mkdir(path) ii = int(strT_to_floatT(str_startT, unit='m') / RESOLUTION) ## 五分钟的分辨率 df.to_csv(os.path.join(path, str(ii) + '.csv.gz'), compression='gzip') lib_file.json_save(dict_accessed, os.path.join(path, str(ii) + '.json'))
def get_driving_origins(G_HSRGrid, originGrid, str_startT): startT = strT_to_floatT(str_startT, unit='m') ## min dict_ChildInfo = {} carAccessHSR = list(nx.neighbors(G_HSRGrid, originGrid)) ## 1.5小时内开车到达的车站 ### 组装一个初始的 dict_ChildInfo 字典 for s in carAccessHSR: int_arriveT = startT + round( G_HSRGrid[s][originGrid]['duration_s'] / 60) # min 为单位 arriveT = str((int_arriveT % 1440) // 60).zfill(2) + ':' + str( int((int_arriveT % 1440) % 60)).zfill(2) # 字符串 dict_ChildInfo[s] = {} dict_ChildInfo[s]['train_code'] = 'carDriving' dict_ChildInfo[s]['depart'] = str_startT dict_ChildInfo[s]['arrive'] = arriveT dict_ChildInfo[s]['travel_time'] = get_deltaT(str_startT, arriveT, unit='min') dict_ChildInfo[s]['total_travelT'] = int_arriveT - startT ## 浮点数 return dict_ChildInfo
def extend_accessHSRs(dict_ChildInfo, dict_accessed, G_stationPair): """ 接上步,在获取了第N+1层的车站的信息之后,计算一定时间内可开车到达的车站 以便同城异站换乘 """ dict_extendInfo = {} for name in dict_ChildInfo: if not name in G_stationPair: ## 这个车站周围不存在 20分钟 车程就可到达的车站 continue info = dict_ChildInfo[name] neighbors = list(nx.neighbors(G_stationPair, name)) ## 20分钟车程可到的车站 for n in neighbors: ######################## 2019.10.11 去掉了这个限制 #if n in dict_ChildInfo: ##在前N层 或 第N+1层被访问过,略掉 n in dict_accessed or # continue temp_info = {} driveT = round(G_stationPair[name][n]['duration_min']) totalT = info['total_travelT'] + driveT if (n not in dict_extendInfo) or ( dict_extendInfo[n]['total_travelT'] > totalT): # 碰到了新的或更小的 if n in dict_accessed and dict_accessed[n] <= totalT: continue for k in info: temp_info[k] = info[k] temp_info['middle'] = info['to'] temp_info['middle_arrive'] = info['arrive'] at = (strT_to_floatT(info['arrive'], unit='m') + driveT) % 1440 temp_info['arrive'] = str(at // 60).zfill(2) + ':' + str( (at % 60)).zfill(2) temp_info['to'] = n temp_info['total_travelT'] = totalT dict_extendInfo[n] = temp_info return dict_extendInfo
def func(str_startT): # DataFrame的一条,只能传进来列表 startT = strT_to_floatT(str_startT) list_layerAccess = [] dict_accessed = {} # 车站:最短旅行时间 dict_ChildInfo = {} # defaultdict(dict) # 车站:由N层到N+1层 所乘坐列车基本信息 originGrid = str((lon, lat)) carAccessHSR = list(nx.neighbors(G_HSRGrid, originGrid)) ## 1.5小时内开车到达的车站 for s in carAccessHSR: arriveT = startT + G_HSRGrid[s][originGrid][ 'duration_s'] / 60 / 60 # 出发时刻+开车时间+准备时间 dict_ChildInfo[s] = {} dict_ChildInfo[s]['arrive'] = str(int(arriveT)).zfill(2) + ':' + str( int((arriveT % 1) * 60)).zfill(2) # 字符串 dict_ChildInfo[s]['travelT'] = arriveT - startT ## 浮点数 dict_ChildInfo[s]['daysign'] = 0 dict_ChildInfo[s]['train_code'] = 'carDriving' while dict_ChildInfo: for name in dict_ChildInfo: ## 既然是被留下来的,就证明是旅行时间更短的 dict_accessed[name] = dict_ChildInfo[name]['travelT'] list_layerAccess.append(dict_ChildInfo) dict_ChildInfo = get_accessHSRs(G_schedule, list_layerAccess[-1], dict_accessed) ttt.duration('shortest travel time finished') #### 将可达车站扩展到可达区域 ### 5. 将可达车站扩展到可达的区域 dict_AccessArea = defaultdict(list) for name in dict_accessed: neighbors = list(nx.neighbors(G_HSRGrid, name)) for grid in neighbors: dict_AccessArea[grid].append(dict_accessed[name] + G_HSRGrid[grid][name]['duration_s'] / 3600) dict_AccessAreaMin = {} ### 选出最短的旅行时间 for p in dict_AccessArea: dict_AccessAreaMin[p] = min(dict_AccessArea[p]) ### 5.1 画图 ## imshow的底图+ 带colorbar的散点图 ## 画车站 #x = [] #y = [] #z = [] #for name in dict_HSRshortestT: # if dict_HSRshortestT[name]<=20: # x.append(dict_HSRLocs[name][0]) # y.append(dict_HSRLocs[name][1]) # # z.append(dict_HSRshortestT[name]) x, y = zip(*[eval(k) for k in dict_AccessAreaMin.keys()]) z = list(dict_AccessAreaMin.values()) xs = [] ys = [] zs = [] for i, v in enumerate(z): if v <= 7: xs.append(x[i]) ys.append(y[i]) zs.append(v) x, y, z = xs, ys, zs minx, maxx, miny, maxy = (73.4997347, 134.7754563, 17.7, 53.560815399999996) implot = lib_plot.ImPlot( '/run/media/pengfei/OTHERS/Gitlab/pythonsharedfunctions.git/China.png') lib_plot.scatter_with_colorbar(x, y, z, s=4, vmin=0, vmax=7) implot.plot_point(eval(originGrid)[0], eval(originGrid)[1], marker='x', color='black', alpha=1, markersize=10) implot.plot_point(121.451093, 31.25151, marker='+', color='green', alpha=1, markersize=10) plt.title(str_startT) ii = int(strT_to_floatT(str_startT, unit='m') / 5) ## 五分钟的分辨率 implot.imshow( fpath='/run/media/pengfei/OTHERS/每日总结/20190923/beijing-5.5h/' + str(ii)) # ttt.duration('plot finished.')
markersize=10) implot.plot_point(121.451093, 31.25151, marker='+', color='green', alpha=1, markersize=10) plt.title(str_startT) ii = int(strT_to_floatT(str_startT, unit='m') / 5) ## 五分钟的分辨率 implot.imshow( fpath='/run/media/pengfei/OTHERS/每日总结/20190923/beijing-5.5h/' + str(ii)) # ttt.duration('plot finished.') def main(): pool = multiprocessing.Pool(processes=8) res = pool.map(func, list_str_startT) return res #### 生成todo列表 list_str_startT = [] str_startT = '00:00' startT = 0 while startT < 24: list_str_startT.append(str_startT) startT = (strT_to_floatT(str_startT, unit='m') + 5) / 60 # 加五分钟 str_startT = floatT_to_strT(startT, unit='h') main()
""" ffff = open(OS + 'Code/比较旅行时间/China_cities_population.csv') df_pops = pd.read_csv(ffff) dict_CityLocs = dict(zip(df_pops.name, df_pops.location)) #ttt = lib_time.MeasureT() ##### 开始计时 #NAME='北京' #originGrid = str(lib_grid.get_nearestGrid(dict_HSRLocs[NAME],1/20)) RESOLUTION = 10 #### 生成todo列表 list_str_startT = [] str_startT = '00:00' startT = 0 while startT < 24: list_str_startT.append(str_startT) startT = (strT_to_floatT(str_startT, unit='m') + RESOLUTION) / 60 # 加五分钟 str_startT = floatT_to_strT(startT, unit='h') def func(NAME): originGrid = str( lib_grid.get_nearestGrid(eval(dict_CityLocs[NAME]), 1 / 12)) if originGrid not in G_PortGrid: print('Grid point is not in G_HSRGrid. %s:%s' % (NAME, originGrid)) return 0 for str_startT in list_str_startT: # 生成所有时间点 #str_startT = '00:10' dict_Sure = {} ## 存储已经找到最短路径的点 dict_Candidate = {} ## 存储找到路径的 ### 1.1 初始化,从家cardriving可达的车站
""" =============================== Program Start ============================ """ ttt = lib_time.MeasureT() ##### 开始计时 NAME='上海市' originGrid = str(lib_grid.get_nearestGrid(eval(dict_CityLocs[NAME]),1/12)) # 分辨率 1/12度, 5弧分 RESOLUTION=10 #### 生成todo列表 list_str_startT = [] str_startT = '00:00' startT = 0 while startT<24: list_str_startT.append(str_startT) startT = (strT_to_floatT(str_startT, unit='m') + RESOLUTION)/60 # 加五分钟 str_startT = floatT_to_strT(startT, unit='h') dict_Sure = {} ## 存储已经找到最短路径的点 dict_Candidate = {} ## 存储找到路径的 ### 1.1 初始化,从家cardriving可达的车站 originInfo_station = lib_transferTWO.get_driving_origins(G_PortGrid,originGrid,str_startT) ### 1.2 构造成方案列表的形式 for name in originInfo_station: dict_Candidate[name] = [originInfo_station[name]] while dict_Candidate: ### 2.1 选出一个旅行时间最短的目的 车站/机场 添加进 dict_Sure中 selected = lib_transferTWO.add_shortest2Sure(dict_Sure,dict_Candidate) ### 2.2 用该确定最短路径的节点更新所有其他节点的路径 (机场-->机场, 车站--> 车站)
G_stationPair = lib_graph.createG_fromFile(f_stationPair, source='source', target='target', attr=['distanceLBS_km','duration_min']) ##### 挑出来 20min 之内的可互达的车站 for e in list(G_stationPair.edges): if G_stationPair[e[0]][e[1]]['duration_min']>20: G_stationPair.remove_edge(e[0],e[1]) for n in list(G_stationPair.nodes): if len(list(nx.neighbors(G_stationPair,n)))==0: G_stationPair.remove_node(n) ttt = lib_time.MeasureT() ##### 开始计时 str_startT = '06:00' #startT = 6.00 startT = strT_to_floatT(str_startT,unit='m') ## min list_layerAccess = [] dict_accessed = {} # 车站:最短旅行时间 dict_ChildInfo = {} # defaultdict(dict) # 车站:由N层到N+1层 所乘坐列车基本信息 originGrid = str(lib_grid.get_nearestGrid(dict_HSRLocs['哈尔滨'],1/20)) carAccessHSR = list(nx.neighbors(G_HSRGrid,originGrid)) ## 1.5小时内开车到达的车站 ### 组装一个初始的 dict_ChildInfo 字典 for s in carAccessHSR: int_arriveT = startT + round(G_HSRGrid[s][originGrid]['duration_s']/60) # min 为单位 arriveT = str((int_arriveT%1440)//60).zfill(2)+':'+str(int((int_arriveT%1440)%60)).zfill(2) # 字符串 dict_ChildInfo[s] = {} dict_ChildInfo[s]['train_code'] = 'carDriving' dict_ChildInfo[s]['depart'] = str_startT dict_ChildInfo[s]['arrive'] = arriveT dict_ChildInfo[s]['total_travelT'] = int_arriveT-startT ## 浮点数
def update_Candidate_based_before(source, dict_Candidate, dict_Sure, G_schedule, G_scheme, dict_StillSure, G_stationPair, heap, prepareT=15, RESOLUTION=10): """ 先判断前一个时间戳的出行方案能否继续使用 根据已经确定的source节点的信息更新所有的路径 (扫描由这个新添节点出发,是否可以使得某些已有的路径变得更短) G_scheme: 上一个时间戳的出行方案建立的图(树),节点上的属性时出行方案 """ list_updates = [] neighbors = set(nx.neighbors(G_schedule, source)) - set( dict_Sure.keys()) #-set(dict_StillSure.keys()) list_scheme_of_source = dict_Sure[source] last_arriveT = list_scheme_of_source[-1]['arrive'] # 到站时间 for name in neighbors: if name in dict_StillSure: dict_Candidate[name] = dict_StillSure[name] ##################### del dict_StillSure[name] ######################################## continue ######################################## old_scheme = G_scheme.node[name]['scheme'] if ( name in G_scheme and 'scheme' in G_scheme.node[name]) else [ ] # 找到这个点原来的出行方案 #print(len(old_scheme),len(list_scheme_of_source),name,source) len_source = len(list_scheme_of_source) # 新的源点的换乘方案的长度 ## 尝试使用原来的方案:一定是比之前的方案中schedule daley小了, # # 查看换乘时间是否仍然充足; d_t 可能是负数,没有用编好的 get_deltaT 函数 if len(old_scheme)>len_source \ and old_scheme[len_source]['depart_station'] == source \ and old_scheme[len_source]['train_code'] != 'carDriving' \ and strT_to_floatT(old_scheme[len_source]['depart'],unit='m') - strT_to_floatT(last_arriveT, unit='m') >= prepareT \ and strT_to_floatT(old_scheme[len_source]['depart'],unit='m') - strT_to_floatT(last_arriveT, unit='m') < get_deltaT(old_scheme[len_source-1]['arrive'], old_scheme[len_source]['depart'], unit='min'): list_scheme = _update_scheme(list_scheme_of_source, old_scheme, RESOLUTION) travelT = list_scheme[-1]['total_travelT'] #dict_StillSure[name] = list_scheme ### 知道 name是stillSure之后,它的子树也是确定的了,注意要更新总旅行时间 ################################################################### update_successors(list_scheme, G_scheme, dict_Sure, dict_StillSure, RESOLUTION, G_stationPair, heap) # 更新所有子树上的旅行时间 ################################################################### else: # 生成新的方案 list_scheme, travelT = get_scheme(source, name, G_schedule, list_scheme_of_source) if not list_scheme: ## 并没有生成可用的方案 (两车站虽然连通,但是考虑真实列车时是不可达的) continue # 如果新添了路径,或者路径变更短了,更新方案 if name not in dict_Candidate \ or dict_Candidate[name][-1]['total_travelT']>travelT \ or (dict_Candidate[name][-1]['total_travelT']==travelT and len(dict_Candidate[name])>len(list_scheme)): dict_Candidate[name] = list_scheme heapq.heappush(heap, (dict_Candidate[name][-1]['total_travelT'], name)) # 加入堆 ############### list_updates.append(name) # for name in dict_StillSure: # if name not in dict_Candidate or dict_Candidate[name][-1]['total_travelT']>dict_StillSure[name][-1]['total_travelT']: # 新添了路径或路径更短了,添加/更新 # dict_Candidate[name] = dict_StillSure[name] # list_updates.append(name) return list_updates