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
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
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
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
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
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
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, ))
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)