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_scheme(source, target, G_schedule, dict_parents, prepareT=15): """ 在起终点之间 找最早的一班列车 G_schedule: 列车时刻表建的有向图 dict_parents: 上一代的信息 prepareT: 准备时间 15 mins return: 乘坐的最佳列车的基本信息 """ last_arriveT = dict_parents[source]['arrive'] ## 前车的到站时间 past_travelT = dict_parents[source]['total_travelT'] ## 在以前已经用掉的旅行时间 all_trains = G_schedule[source][target] min_travelT = 10**6 # 设置一个足够大的旅行时间 out_info = {'from':source,'to':target,'last_arrive':last_arriveT,'past_travelT':past_travelT} for ID in all_trains: info = all_trains[ID] departT = info['depart'] delta_t = get_deltaT(last_arriveT, departT, unit='min') ### 前车到站时间 和 下趟车出发时间 的比较 if delta_t>=12*60 or delta_t<prepareT: # 接续换乘等待时间不太长,也不太短 continue this_during = info['travel_time'] # 本次列车的运行时间,min travelT = past_travelT + delta_t + this_during # 已用 + 换乘 + 本次 if travelT< min_travelT: min_travelT = travelT for k in info: out_info[k] = info[k] out_info['scheduleDelay'] = delta_t # mins out_info['total_travelT'] = travelT out_info['total_travelT_h'] = str(travelT//60).zfill(2)+':'+str((travelT%60)).zfill(2) # 字符串 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 calculate_travelT_from_scheme(list_scheme): """ 由各段的换乘方案计算总的旅行时间 """ if len(list_scheme) == 1: return list_scheme[0][5] totalT = 0 for i in range(len(list_scheme) - 1): travelT = list_scheme[i][5] schedule_delay = get_deltaT(list_scheme[i][4], list_scheme[i + 1][3], unit='min') totalT += travelT + schedule_delay totalT += list_scheme[-1][5] #print("Total travel time",str(totalT//60).zfill(2)+':'+str(totalT%60).zfill(2)) return totalT
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 get_scheme(source, target, G_schedule, list_scheme_of_source, prepareT=15): """ 在起终点之间所有的列车中,选择使得总旅行时间最短的列车 :param source: 出发车站 :param target: 目的车站 :param G_schedule: 列车时刻表建的有向图 :param list_scheme_of_source: 节点source的最短旅行方案 :param prepareT: 准备时间 15mins :return: 输出 (从源点出发的)方案列表,及总旅行时间 """ last_arriveT = list_scheme_of_source[-1]['arrive'] # 前车的到站时间 past_travelT = list_scheme_of_source[-1]['total_travelT'] # 在以前已经用掉的旅行时间 all_trains = G_schedule[source][target] min_travelT = 10**6 # 设置一个足够大的旅行时间 out_info = {'depart_station': source, 'arrive_station': target} for ID in all_trains: info = all_trains[ID] departT = info['depart'] delta_t = get_deltaT(last_arriveT, departT, unit='min') # 前车到站时间 和 下趟车出发时间 的比较 ################################## ###################################################################### if delta_t > 24 * 60 or delta_t < prepareT: # 接续换乘等待时间不太长,也不太短 continue this_during = info['travel_time'] # 本次列车的运行时间,min travelT = past_travelT + delta_t + this_during # 已用 + 换乘 + 本次 if travelT < min_travelT: min_travelT = travelT out_info.update(info) out_info['total_travelT'] = travelT #out_info['total_travelT_h'] = str(travelT//60).zfill(2)+':'+str((travelT%60)).zfill(2) # 字符串 if not 'train_code' in out_info: ## 并没有产生有效的接续换乘策略(正常情况下不会出现) return [], 10**6 list_schemes = list_scheme_of_source + [out_info] return list_schemes, out_info['total_travelT']
def construct_scheme(list_layerAccess, dest): """ 根据零散的 list_layerAccess,及目的地,生成出行方案 倒着找,是最少旅行时间,最多换乘的 """ if dest in list_layerAccess[0]: scheme = list_layerAccess[0][dest] #dict_distScheme[dest] = scheme #print('Directly car driving accessible') return [] scheme = [] for i in range(len(list_layerAccess)): j = len(list_layerAccess) - i - 1 if dest in list_layerAccess[j]: ### 在这层里, info = list_layerAccess[j][dest] last_station = info['from'] scheme.insert(0, info) while j > 1: j -= 1 info = list_layerAccess[j][last_station] last_station = info['from'] scheme.insert(0, info) break if not scheme: #print('No transfer scheme for station %s'%dest) return [] info = list_layerAccess[0][last_station] scheme.insert(0, info) out = [] for i in range(len(scheme)): train_code = scheme[i]['train_code'] source = scheme[i].get('from', '--') if i + 1 < len(scheme): destination = scheme[i + 1].get('from', '--') else: destination = dest dt = scheme[i].get('depart', '--') at = scheme[i].get('arrive', '--') if 'middle' in scheme[i]: ## 中间有乘车转站 midT = scheme[i].get('middle_arrive', '--') out.append([ train_code, source, scheme[i]['middle'], dt, midT, get_deltaT(dt, midT, unit='min') ]) out.append([ 'carDriving', scheme[i]['middle'], destination, midT, at, get_deltaT(midT, at, unit='min') ]) else: travelT = scheme[i].get('travel_time') out.append([train_code, source, destination, dt, at, travelT]) table = PrettyTable([ "train_code", "source", "target", "departure time", "arrival time", "travel time" ]) for row in out: table.add_row(row) totalT = str(scheme[-1]['total_travelT'] // 60).zfill(2) + ':' + str( scheme[-1]['total_travelT'] % 60).zfill(2) #print('Transfer scheme is as follow, travel time:',totalT) #print(table) return out
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