예제 #1
0
def ECMP_PATH(self,
              src_datapath_id,
              src_port,
              dst_datapath_id,
              dst_port,
              weight="weight"):
    """
    ecmp選擇多條cost與shortest path一樣的路徑
    """
    #ecmp選擇多條cost與shortest path一樣的路徑
    #會造成選擇不多樣
    #ecmp跟我們說這樣的條件會保證loop free所以不需要確認
    ok_path = []
    best_length = 0
    for idx, path in enumerate(
            nx.shortest_simple_paths(GLOBAL_VALUE.G,
                                     (src_datapath_id, src_port),
                                     (dst_datapath_id, dst_port),
                                     weight=weight)):
        if idx == 0:
            best_length = path_weight(GLOBAL_VALUE.G, path, weight=weight)
            ok_path.append(path)
            continue
        if best_length == path_weight(GLOBAL_VALUE.G, path, weight=weight):
            ok_path.append(path)
        else:
            break
    return ok_path, best_length
예제 #2
0
def k_shortest_path_first_and_maximum_flow_version(self,
                                                   k,
                                                   src_datapath_id,
                                                   src_port,
                                                   dst_datapath_id,
                                                   dst_port,
                                                   check_G=None,
                                                   weight="weight"):
    #這個保證路徑沒有loop
    #當我們想要考量 最大剩餘頻寬 於鏈路cost如何合併?
    loop_free_path = []
    path_length = []
    loop_check = Loop_Free_Check(check_G)
    for path in nx.shortest_simple_paths(GLOBAL_VALUE.G,
                                         (src_datapath_id, src_port),
                                         (dst_datapath_id, dst_port),
                                         weight=weight):
        if len(loop_free_path) == k:
            break
        prev_node = None
        for node in path:
            if prev_node != None:
                #print(prev_node,node,weight)
                loop_check.add_edge(
                    prev_node,
                    node,
                    weight=GLOBAL_VALUE.G[prev_node][node][weight])
            prev_node = node
        _check_free = loop_check.check_free_loop()
        if _check_free:
            loop_free_path.append(path)
            path_length.append(path_weight(GLOBAL_VALUE.G, path,
                                           weight=weight))

    return loop_free_path, path_length
예제 #3
0
def k_shortest_paths(G, source, target, k, dists_calc=True, weight=None):
    # esto es un generador de caminos, los devuelve del mas corto al mas largo
    gen = nx.shortest_simple_paths(G, source, target, weight)
    # los caminos los voy a guardar en un array de objetos (inicializados como None)
    paths = np.empty(shape=(k), dtype=object)
    # si me piden calcular las distancias tmb
    if dists_calc:
        dists = np.zeros(shape=(k))
    try:
        # recorro el generador
        for i, path in enumerate(gen):
            # agrego el camino
            paths[i] = path
            if dists_calc:
                # agrego la distancia
                dists[i] = path_weight(G, path, weight=weight)
            if i == k - 1:
                # si llegue a k caminos, dejo de recorrer
                break
        if i < k - 1:
            # si calcule menos que k caminos, aviso
            print("Hay solo {} caminos entre {} y {}".format(
                i + 1, source, target))
    except nx.NetworkXNoPath:
        # si no estan conectados los nodos tengo que avisar
        print("Nodos {}-{} no conectados".format(source, target))
        dists = np.repeat(np.inf, k)
    # retorno lo calculado
    if dists_calc:
        return dists, paths
    else:
        return paths
예제 #4
0
def k_shortest_path_loop_free_version(self,
                                      k,
                                      src_datapath_id,
                                      src_port,
                                      dst_datapath_id,
                                      dst_port,
                                      check_G=None,
                                      weight="weight"):
    """
    這個利用先深搜尋確保路徑沒有loop
    """
    loop_free_path = []
    path_length = []
    #初始化拓樸當check_G==None就新增一個空的有向拓樸
    loop_check = Loop_Free_Check(check_G)

    shortest_simple_paths = nx.shortest_simple_paths(
        GLOBAL_VALUE.G, (src_datapath_id, src_port),
        (dst_datapath_id, dst_port),
        weight=weight)

    #從最好的路線開始挑選

    for path in shortest_simple_paths:
        #當挑出來的路到達k條就可以離開
        if len(loop_free_path) == k:
            break
        #依序藉由節點塞入拓樸
        prev_node = None
        for node in path:
            if prev_node != None:
                print(prev_node, node, GLOBAL_VALUE.G[prev_node][node].keys())
                if weight in GLOBAL_VALUE.G[prev_node][node]:
                    loop_check.add_edge(
                        prev_node,
                        node,
                        weight=GLOBAL_VALUE.G[prev_node][node][weight])
                else:
                    loop_check.add_edge(prev_node, node, weight=0)
            prev_node = node

        #確認是否沒有發生loop
        _check_free = loop_check.check_free_loop()
        if _check_free:
            #沒有發生loop所以我們可以蒐集起來
            loop_free_path.append(path)
            print(path)
            path_length.append(path_weight(GLOBAL_VALUE.G, path,
                                           weight=weight))
            #所有k條loop free路線,這些路線的權重

    return loop_free_path, path_length
예제 #5
0
def k_maximum_flow_loop_free_version(self,
                                     k,
                                     src_datapath_id,
                                     src_port,
                                     dst_datapath_id,
                                     dst_port,
                                     check_G=None,
                                     weight="weight",
                                     capacity="capacity"):
    """
    這個保證路徑沒有loop
    當我們想要考量 最大剩餘頻寬 於鏈路cost如何合併? 
    """
    loop_free_path = []
    path_length = []
    tmp_G = GLOBAL_VALUE.G.copy()

    if check_G == None:
        check_G = nx.DiGraph()

    while len(loop_free_path) < k:
        try:
            maxflow = nx.maximum_flow(tmp_G, (src_datapath_id, src_port),
                                      (dst_datapath_id, dst_port),
                                      capacity=capacity)

            _tmp_path = []
            for node in maxflow:
                _tmp_path.append(node)
            loop_free_path.append(_tmp_path)

            G.remove_edge(0, 1)
        except:
            pass
            break

    return loop_free_path

    if check_G == None:
        check_G = nx.DiGraph()
    for path in nx.shortest_simple_paths(GLOBAL_VALUE.G,
                                         (src_datapath_id, src_port),
                                         (dst_datapath_id, dst_port),
                                         weight=weight):
        tmp_check_G = check_G.copy()
        if len(loop_free_path) == k:
            break
        prev_node = None
        for node in path:
            if prev_node != None:
                tmp_check_G.add_edge(
                    prev_node,
                    node,
                    weight=GLOBAL_VALUE.G[prev_node][node][weight])
            prev_node = node
        try:
            nx.find_cycle(tmp_check_G, orientation="original")
        except:
            check_G = tmp_check_G
            loop_free_path.append(path)
            path_length.append(path_weight(check_G, path, weight=weight))
    return loop_free_path, path_length
예제 #6
0
def k_shortest_path_save(
    prune_type,
    map,
    map_name,
    k,
    prune_vals_given=None,
    prune_vals_number=None,
    prune_vals_max=None,
    prune_vals_offset=None,
    filter_att="GRUPO",
    filter_val="control sano",
    op=op.eq,
    remove_nodes=[34, 83],
    trace=False,
    trace_k_paths=False,
    prune_start=0,
    prune_finish=None,
    case_start=0,
    case_finish=None,
):
    # cargo solo los conectomas que me interesan
    connectomes_original, cases = connectomes_filtered(
        filter_att, filter_val, op, remove_nodes=remove_nodes, ret_cases=True)
    n_connectomes = len(connectomes_original)
    c_size = connectomes_original.shape[1]
    if case_finish == None:
        case_finish = n_connectomes
    print("Loading {} connectomes".format(n_connectomes))

    if prune_vals_given == None:
        assert prune_vals_max != None, "prune_vals_max should be max prune value"
        assert (prune_vals_number !=
                None), "prune_vals_number should be number of prune values"
        assert (prune_vals_offset != None
                ), "prune_vals_offset should be offset from lowest prune value"
        connectomes_control_sano = connectomes_filtered(
            "GRUPO",
            "control sano",
            op,
            remove_nodes=remove_nodes,
            ret_cases=False)
        # voy a calcular el numero minimo de conexiónes que son 0 para algun conectoma
        nn = connectomes_control_sano.shape[1]
        # solo me importa la parte superior de la matriz, sin diagonal
        min_connectomes_zeros = (np.min(
            (connectomes_control_sano == 0).sum(axis=2).sum(axis=1)) - nn -
                                 (nn * (nn - 1) / 2))
        # el porcentaje lo saco dividiendo por la cantidad total de elementos en la parte superior de la matriz
        min_zero_percentage = min_connectomes_zeros / (nn * (nn - 1) / 2)
        prune_vals = np.linspace(min_zero_percentage - prune_vals_offset,
                                 prune_vals_max, prune_vals_number)
        if prune_finish == None:
            prune_finish = prune_vals_number
    else:
        prune_vals = prune_vals_given
    start_flag = False
    save_path = "C:\\Users\Tomas\Desktop\Tesis\Programacion\\results\pruning\k_paths_txt\{}_{}".format(
        map_name, "_".join(filter_val.split()))
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    for i, prune_val in enumerate(prune_vals):
        # les aplico pruning a los conectomas
        connectomes = prune_connectomes(connectomes_original, prune_type,
                                        prune_val)
        for j, connectome in enumerate(connectomes):
            if (i >= prune_start) and ((j >= case_start) | start_flag):
                start_flag = True
                if (i <= prune_finish) and (j <= case_finish):
                    if trace:
                        print(
                            "Prune val: {:.3f}/{:.3f} - {} - Connectome: {}/{} - "
                            .format(
                                prune_val,
                                np.max(prune_vals),
                                cases[j],
                                j + 1,
                                n_connectomes,
                            ),
                            end="",
                        )
                    # mido el tiempo
                    start = time.time()
                    # creo un grafo del conectoma
                    G = nx.from_numpy_matrix(connectome)
                    # le agrego un atributo
                    add_edge_map(G, map, map_name)
                    # longitud, aristas usadas y longitud en aristas
                    paths = global_k_shortest_paths(G,
                                                    k,
                                                    trace=trace_k_paths,
                                                    weight=map_name,
                                                    dists=False)
                    for k_v in range(k):
                        fname = "{}_k={}_{}_prune_val={}_{}.txt".format(
                            cases[j], k_v + 1, prune_type, prune_val, map_name)
                        fname = os.path.join(save_path, fname)
                        f = open(fname, "w")
                        f.truncate(0)
                        f.write(
                            "Inicio,Fin,Camino(separado por comas),Distancia del camino\n"
                        )
                        for i_idx in range(paths.shape[0]):
                            for j_idx in range(i_idx + 1, paths.shape[1]):
                                if paths[i_idx, j_idx][k_v] != None:
                                    f.write("{},{},{},{}\n".format(
                                        i_idx,
                                        j_idx,
                                        ",".join([
                                            str(e)
                                            for e in paths[i_idx, j_idx][k_v]
                                        ]),
                                        path_weight(G, paths[i_idx,
                                                             j_idx][k_v],
                                                    map_name),
                                    ))
                                else:
                                    f.write("{},{},None,None\n".format(
                                        i_idx, j_idx))
                        f.close()

                    end = time.time()
                    # printeo el tiempo
                    if trace:
                        print("{:.5f} s".format(end - start))
    pass
예제 #7
0
def process_function_k_paths(
    connectomes,
    j_vals,
    prune_val,
    prune_vals,
    cases,
    map,
    map_name,
    k,
    prune_type,
    save_path,
    trace,
    trace_k_paths,
):
    for j in j_vals:
        connectome = connectomes[j]
        n_connectomes = len(connectomes)
        if trace:
            print(
                "Working with - Prune val: {:.3f}/{:.3f} - {} - Connectome: {}/{}"
                .format(prune_val, np.max(prune_vals), cases[j], j + 1,
                        n_connectomes))
        # mido el tiempo
        start = time.time()
        # creo un grafo del conectoma
        G = nx.from_numpy_matrix(connectome)
        # le agrego un atributo
        add_edge_map(G, map, map_name)
        # longitud, aristas usadas y longitud en aristas
        paths = global_k_shortest_paths(G,
                                        k,
                                        trace=trace_k_paths,
                                        weight=map_name,
                                        dists=False)
        for k_v in range(k):
            fname = "{}_k={}_{}_prune_val={}_{}.txt".format(
                cases[j], k_v + 1, prune_type, prune_val, map_name)
            fname = os.path.join(save_path, fname)
            f = open(fname, "w")
            f.truncate(0)
            f.write(
                "Inicio,Fin,Camino(separado por comas),Distancia del camino\n")
            for i_idx in range(paths.shape[0]):
                for j_idx in range(i_idx + 1, paths.shape[1]):
                    if paths[i_idx, j_idx][k_v] != None:
                        f.write("{},{},{},{}\n".format(
                            i_idx,
                            j_idx,
                            ",".join(
                                [str(e) for e in paths[i_idx, j_idx][k_v]]),
                            path_weight(G, paths[i_idx, j_idx][k_v], map_name),
                        ))
                    else:
                        f.write("{},{},None,None\n".format(i_idx, j_idx))
            f.close()

        end = time.time()
        # printeo el tiempo
        if trace:
            print(
                "Prune val: {:.3f}/{:.3f} - {} - Connectome: {}/{} - {:.5f} s".
                format(
                    prune_val,
                    np.max(prune_vals),
                    cases[j],
                    j + 1,
                    n_connectomes,
                    end - start,
                ))
예제 #8
0
    length, path = nx.multi_source_dijkstra(G, {p}, weight=impedance)
print(round((time.time() - start_time), 1), "seconds--")

import igraph as ig

g = ig.Graph.from_networkx(G)
# path = g.get_shortest_paths(1,1000,mode="out",weights=impedance,output="epath")
# sum(g.es[path[0]][impedance])
start_time = time.time()
for p in range(12000, 12100):
    path = g.get_all_shortest_paths(p, to=None, weights=impedance, mode='out')
print(round((time.time() - start_time), 1), "seconds--")

route = nx.shortest_path(G=G, source=1, target=1000, weight=impedance)
print("impedance: " +
      str(round(path_weight(G=G, path=route, weight=impedance), 1)))
#####################

orig = (Locations.iloc[0].geometry.coords.xy[0][0],
        Locations.iloc[0].geometry.coords.xy[1][0])
desti = (Locations.iloc[33].geometry.coords.xy[0][0],
         Locations.iloc[33].geometry.coords.xy[1][0])

if method == "simple":
    route, pos = routesimple(graph, G, orig, desti, impe=impedance)
    print("impedance: " +
          str(round(path_weight(G=G, path=route, weight=impedance), 1)))
    printroute(route, pos, col="blue")

if method == "accurate":
    orig = addNode(orig, nodes, links, graph, v_add=50)