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'))
Beispiel #5
0
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
Beispiel #6
0
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可达的车站
Beispiel #10
0

"""
    ===============================  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