def match(gw, track, debug = False):
    dag = create_dag(gw, track)
    if dag is None:
        print 'failed creating DAG',
        return None
    # p_dag = cdagm.longest_path_dag(dag, init_weight_with, combine_weight_with)
    p_dag = cdagm.shortest_path_dag(dag, init_weight_with, combine_weight_with)
    if p_dag is None:
        print 'failed finding path in DAG',
        return None
    es = cdagm.pdag2es(dag, p_dag)
    if es is None:
        print 'failed generating edge list in Graph'
        return None
    p = cp.new_path_from_es(gw, track.tid, es)
    if p is None:
        print 'failed creating Path instance'
        return None

    update_ways_weight(p, track)
    # update_ways_weight_proj(p, track)

    if debug:
        global gdag
        gdag = dag.copy()
        global gpag
        gpdag = list(p_dag)
        global ges
        ges = list(es)
    return p
Ejemplo n.º 2
0
def match(gw, track, debug=False):
    dag = create_dag(gw, track)
    if dag is None:
        print 'failed creating DAG',
        return None
    # p_dag = cdagm.longest_path_dag(dag, init_weight_with, combine_weight_with)
    p_dag = cdagm.shortest_path_dag(dag, init_weight_with, combine_weight_with)
    if p_dag is None:
        print 'failed finding path in DAG',
        return None
    es = cdagm.pdag2es(dag, p_dag)
    if es is None:
        print 'failed generating edge list in Graph'
        return None
    p = cp.new_path_from_es(gw, track.tid, es)
    if p is None:
        print 'failed creating Path instance'
        return None

    update_ways_weight(p, track)
    # update_ways_weight_proj(p, track)

    if debug:
        global gdag
        gdag = dag.copy()
        global gpag
        gpdag = list(p_dag)
        global ges
        ges = list(es)
    return p
Ejemplo n.º 3
0
def track2path(gw, track, path_selector, k=5, r=0.1, sigma=0.02, **kwargs):
    dag = nx.DiGraph()
    ## rds = track.aggre_records()
    rds = track.rds
    projss = []

    # for every gps-record in track, find its valid projection candidates
    for rd in list(rds):
        lonlat_rds = rd['gps_lonlat']
        projs = gw.find_projs_within(lonlat_rds, r)
        # if no projection candidates found, remove the gps-record from track
        if len(projs) == 0:
            rds.remove(rd)
        elif len(projs) > k:
            ordered_projs = list(projs)
            ordered_projs.sort(key = operator.itemgetter('d_proj'))
            projs = tuple(ordered_projs[0:k])
            projss.append(projs)
        else:
            projss.append(projs)
  
    if len(projss) == 0:
        return None

    # minimum length of path from source to vertex(i,ii) in DAG
    min_sw_dict = {}
    # previous vertex in path with minimum length(above) in DAG
    pre_dict = {}

    # for every projection candidate of every gps-record, add vertex to DAG
    for i in range(0,len(projss)):
        projs = projss[i]
        for ii in range(0,len(projs)):
            proj = projs[ii]

            # vertex in DAG represented by tuple (i,ii)
            # 1) i is the index of gps-record in track
            # 2) ii is the index of projection candidate in i gps-record
            dag.add_node((i, ii), s = proj['s'], t = proj['t'], \
                    gps_lonlat = rds[i]['gps_lonlat'], \
                    proj_lonlat = proj['proj_lonlat'], \
                    l_s = proj['l_s'], \
                    l_t = proj['l_t'], \
                    d_proj = proj['d_proj'], \
                    weight = -math.log(norm(0,sigma).pdf(proj['d_proj'])))
                    ## weight = 0)
            # the source vertexes
            if i == 0:
                min_sw_dict[(i,ii)] = 0
                pre_dict[(i,ii)] = -1
            else:
                min_sw_dict[(i,ii)] = INF
                pre_dict[(i,ii)] = None
   
    # for every pair of contiguous gps-records
    for i in range(0,len(projss)-1):
        j = i + 1
        i_projs = projss[i]
        j_projs = projss[j]

        # for every projection candidate ii of i gps-record
        for ii in range(0,len(i_projs)):
            ii_proj = i_projs[ii]
            s_ii = ii_proj['s']
            t_ii = ii_proj['t']
            speed_ii = gw.G[s_ii][t_ii]['speed']
            sw_ii = min_sw_dict[(i,ii)]
            
            # for every projection candidate jj of j=i+1 gps-record
            for jj in range(0,len(j_projs)):
                jj_proj = j_projs[jj]
                s_jj = jj_proj['s']
                t_jj = jj_proj['t']
                speed_jj = gw.G[s_jj][t_jj]['speed']
                
                # calculate:
                # 1) path on map between ii and jj
                # 2) weight of path between ii and jj
                if t_ii == s_jj:
                    p_tii_sjj = ()
                    w_tii_sjj = ii_proj['l_t'] + jj_proj['l_s']
                
                elif t_ii == t_jj and s_ii == s_jj:
                    p_tii_sjj = ()
                    w_tii_sjj = jj_proj['l_s'] - ii_proj['l_s']
                    
                    if w_tii_sjj < 0:
                        ## p_tii_sjj = gw.shortest_path_from_to(t_ii, s_jj)
                        ## p_tii_sjj = best_path_from_to_slow(gw, t_ii, s_jj)
                        p_tii_sjj = path_selector(gw, t_ii, s_jj, current = sw_ii, orig_lonlat=ii_proj['proj_lonlat'], dest_lonlat=jj_proj['proj_lonlat'], **kwargs)

                        if not len(p_tii_sjj) > 0:
                            w_tii_sjj = INF
                        else:
                            w_tii_sjj = gw.length_of_edges(p_tii_sjj) + ii_proj['l_t'] + jj_proj['l_s']
                
                else:
                    ## p_tii_sjj = gw.shortest_path_from_to(t_ii, s_jj)
                    ## p_tii_sjj = best_path_from_to_slow(gw, t_ii, s_jj)
                    p_tii_sjj = path_selector(gw, t_ii, s_jj, current = sw_ii, orig_lonlat=ii_proj['proj_lonlat'], dest_lonlat=jj_proj['proj_lonlat'], **kwargs)

                    if not len(p_tii_sjj) > 0:
                        w_tii_sjj = INF
                    else:
                        w_tii_sjj = gw.length_of_edges(p_tii_sjj) + ii_proj['l_t'] + jj_proj['l_s']
                
                # add edge between ii and jj to DAG
                # w_tii_sjj = math.exp(-w_tii_sjj)
                dag.add_edge((i, ii), (j, jj), path = p_tii_sjj, weight = w_tii_sjj)
        
        for jj in range(0,len(j_projs)):
            min_sw_j_jj = INF
            min_ii = None
            for tmp_ii in range(0,len(i_projs)):
                min_sw_i_ii = min_sw_dict[(i, tmp_ii)] 
                tmp_sw_j_jj = min_sw_i_ii + dag[(i,tmp_ii)][(j,jj)]['weight']
                if tmp_sw_j_jj < min_sw_j_jj:
                    min_sw_j_jj = tmp_sw_j_jj
                    min_ii = tmp_ii
            min_sw_dict[(j,jj)] = min_sw_j_jj
            pre_dict[(j,jj)] = (i, min_ii)

    # find the sink vertex with minimum sum of weights
    min_sw_j_jj = INF
    j = len(projss) - 1
    min_jj = -1
    for jj in range(0,len(projss[-1])):
        sw_j_jj = min_sw_dict[(j,jj)]
        if sw_j_jj < min_sw_j_jj:
            min_sw_j_jj = sw_j_jj
            min_jj = jj

    if min_jj < 0:
        return None

    # backward from best sink vertex, generate the path in DAG
    pdag = []
    v = (j,min_jj)
    while True:
        pdag.append(v)
        pv = pre_dict[v]
        if pv is None:
            return None
        if pv == -1:
            break
        else:
            v = pv

    pdag = pdag[::-1]



    def combine_weight_with(sw_cv, w_cv_nv, w_nv):
        return sw_cv + w_cv_nv + w_nv

    def init_weight_with(w_source_v):
        return w_source_v

    pdag = cdagm.shortest_path_dag(dag, init_weight_with, combine_weight_with)   




    # generating es from pdag
    vds = dag.nodes(data = True)
    vds_dict = {}
    for vd in vds:
        vds_dict[vd[0]] = vd[1]

    es = []
    v = pdag[0]
    e = (vds_dict[v]['s'], vds_dict[v]['t'])
    es.append(e)
    for i in range(1,len(pdag)):
        v = pdag[i]
        pv = pdag[i-1]
        e = (vds_dict[v]['s'], vds_dict[v]['t'])
        pe = es[-1]
        if e == pe:
            continue
        else:
            es = es + list(dag[pv][v]['path'])
            es.append(e)

    if len(es) == 0:
        return None
    
    # generating path instance from es
    path = cp.new_path_from_es(gw, track.tid, es)
    return path