def tree_part(graph, pop_col, pop_target, epsilon, node_repeats): w = graph.copy() for ed in w.edges(): w.add_edge(ed[0], ed[1], weight=random.random()) T = tree.maximum_spanning_edges(w, algorithm='kruskal', data=False) ST = nx.Graph() ST.add_edges_from(list(T)) #nx.draw(ST) h = ST.copy() for e in ST.edges(): ##print(e) #e=random.choice(list(ST.edges()))#new h.remove_edge(e[0], e[1]) for t in nx.connected_components(h): tsum = 0 for n in t: tsum += graph.nodes[n][pop_col] #print(tsum/pop_target) if abs(tsum - pop_target) < pop_target * epsilon: ##print("MADE IT") clusters = {} clusters[1] = list(t) clusters[-1] = [] for nh in graph.nodes(): if nh not in clusters[1]: clusters[-1].append(nh) return clusters h.add_edge(e[0], e[1])
def get_spanning_tree_k(graph): w = graph.copy() for ed in w.edges(): w.add_edge(ed[0], ed[1], weight=random.random()) T = tree.maximum_spanning_edges(w, algorithm='kruskal', data=False) return T
def random_spanning_tree(graph, pop_col): for edge in graph.edges: graph.edges[edge]["weight"] = random.random() edges = tree.maximum_spanning_edges(graph, algorithm="kruskal", data=False) spanning_tree = nx.Graph(edges) for node in graph: spanning_tree.nodes[node][pop_col] = graph.nodes[node][pop_col] return spanning_tree
def get_spanning_tree_k(graph): ''' Generates a non -uniform spanning tree using Karger/Kruskal ''' w=graph.copy() for ed in w.edges(): w.add_edge(ed[0],ed[1],weight=random.random()) T = tree.maximum_spanning_edges(w, algorithm='kruskal', data=False) return T
def partition_spanning_tree_single(partition): graph = partition.graph tgraph = nx.Graph() sgn = {} for label in partition.parts: #print(label) sgn[label] = [] #make this a dictionary for n in graph.nodes(): sgn[partition.assignment[n]].append(n) for label in partition.parts: sgraph = nx.subgraph(graph, sgn[label]) tempT = get_spanning_tree_u_w(sgraph) #get_spanning_tree_k(sgraph) tgraph.add_edges_from(tempT) #print("done with inividual") #pretty fast anyway el = set() for edge in partition["cut_edges"]: el.add((partition.assignment[edge[0]], partition.assignment[edge[1]])) #print("set f edges") w = nx.Graph() w.add_edges_from(list(el)) #print("built district graph") for ed in w.edges(): w.add_edge(ed[0], ed[1], weight=random.random()) T = tree.maximum_spanning_edges(w, algorithm='kruskal', data=False) ST = nx.Graph() ST.add_edges_from(list(T)) #print("built district tree") e_to_add = [] for edge in ST.edges(): tempo = 0 templ = tuple(partition["cut_edges_by_part"][edge[0]]) #print(edge[0],edge[1]) #rint("new district edge") while tempo == 0: qedge = random.choice(templ) #print("tried an edge",[partition.assignment[qedge[0]],partition.assignment[qedge[1]]]) if edge[1] == partition.assignment[ qedge[0]] or edge[1] == partition.assignment[qedge[1]]: tempo = 1 e_to_add.append(qedge) tgraph.add_edges_from(e_to_add) return tgraph
def get_max_spanning_tree(G): """ This gets the maximum weighted spanning tree for the input network :param G: The graph whose tree you want to get the mwst for :return: the max weighted spanning tree networkx network object """ G_copy = G.copy() mst_edges = maximum_spanning_edges(G_copy) mst = nx.Graph() for edge in mst_edges: mst.add_edge(edge[0], edge[1], weight=1) return mst
def get_spanning_tree(graph, node_communities): ''' Returns a pseudo-random spanning tree of the input graph ''' w=graph.copy() h=graph.copy() community_edges = set() for community in node_communities: community_subgraph = graph.subgraph(community) community_edges.update(community_subgraph.edges()) for ed in w.edges(): if ed not in community_edges: w.add_edge(ed[0],ed[1],weight=random.random()) else: print("In Community") w.add_edge(ed[0],ed[1],weight=random.random()+100) T = [(edge[0],edge[1]) for edge in tree.maximum_spanning_edges(w, algorithm='kruskal', data=True)] for edge in graph.edges(): if edge not in T and (edge[1],edge[0]) not in T: h.remove_edge(edge[0],edge[1]) can_cut_dict = {edge:(False if edge in community_edges else True) for edge in h.edges()} nx.set_edge_attributes(h, can_cut_dict, 'cut') return h
def tree_part2(graph, pop_col, pop_target, epsilon,node_repeats): w=graph.copy() for ed in w.edges(): w.add_edge(ed[0],ed[1],weight=random.random()) T = tree.maximum_spanning_edges(w, algorithm='kruskal', data=False) ST= nx.Graph() ST.add_edges_from(list(T)) #nx.draw(ST) h=ST.copy() #nx.draw(ST,layout='tree') #root = random.choice(list(h.nodes())) root = random.choice([x for x in ST.nodes() if ST.degree(x)>1])#this used to be greater than 2 but failed on small grids:( #print(root) predbfs=nx.bfs_predecessors(h, root)#was dfs pred={} for ed in predbfs: pred[ed[0]]=ed[1] pops={x:[{x},graph.nodes[x][pop_col]] for x in graph.nodes()} leaves=[] t=0 layer=0 restarts=0 while 1==1: if restarts==node_repeats: w=graph.copy() for ed in w.edges(): w.add_edge(ed[0],ed[1],weight=random.random()) T = tree.maximum_spanning_edges(w, algorithm='kruskal', data=False) ST= nx.Graph() ST.add_edges_from(list(T)) #nx.draw(ST) h=ST.copy() #nx.draw(ST,layout='tree') #root = random.choice(list(h.nodes())) root = random.choice([x for x in ST.nodes() if ST.degree(x)>1])#this used to be greater than 2 but failed on small grids:( #print(root) predbfs=nx.bfs_predecessors(h, root)#was dfs pred={} for ed in predbfs: pred[ed[0]]=ed[1] pops={x:[{x},graph.nodes[x][pop_col]] for x in graph.nodes()} leaves=[] t=0 layer=0 restarts=0 #print("Bad tree -- rebuilding") if len(list(h.nodes()))==1: h=ST.copy() root = random.choice([x for x in ST.nodes() if ST.degree(x)>1])#this used to be greater than 2 but failed on small grids:( #print(root) #pred=nx.bfs_predecessors(h, root)#was dfs predbfs=nx.bfs_predecessors(h, root)#was dfs pred={} for ed in predbfs: pred[ed[0]]=ed[1] pops={x:[{x},graph.nodes[x][pop_col]] for x in graph.nodes()} #print("bad root --- restarting",restarts) restarts+=1 layer=0 leaves=[] if leaves == []: leaves = [x for x in h.nodes() if h.degree(x)==1] layer=layer+1 if len(leaves) == len(list(h.nodes()))-1: tsum = pops[root][1] for r in range(2,len(leaves)): for s in itertools.combinations(leaves,r): for node in s: tsum+=pops[node][1] if abs(tsum-pop_target)<epsilon*pop_target: print(pops[leaf][1]/pop_target) clusters={} clusters[1]=list(pops[leaf][0]) clusters[-1]=[] for nh in graph.nodes(): if nh not in clusters[1]: clusters[-1].append(nh) return clusters if root in leaves: #this was in an else before but is still apparently necessary? leaves.remove(root) #if layer %10==0: #print("Layer",layer) for leaf in leaves: if layer>1 and abs(pops[leaf][1]-pop_target) < pop_target * epsilon: #print(pops[leaf][1]/pop_target) #ST.remove_edge(leaf,pred[leaf])#One option but slow #parts=list(nx.connected_components(h)) #ST here too #print(layer, len(parts)) #part=parts[random.random()<.5] clusters={} clusters[1]=list(pops[leaf][0]) clusters[-1]=[] for nh in graph.nodes(): if nh not in clusters[1]: clusters[-1].append(nh) return clusters parent = pred[leaf] pops[parent][1]+=pops[leaf][1] pops[parent][0]=pops[parent][0].union(pops[leaf][0]) #h = nx.contracted_edge(h,(parent,leaf),self_loops = False)#too slow on big graphs h.remove_node(leaf) leaves.remove(leaf) t=t+1
def mst(image_path, N_runs, new_size = 'automatic',union_type = None, reversed_colors = True, noise_on=True, rseed = None, t2 =.1, ds_interpolation = 'nearest'): #cluster inputs cluster_flag = True G_filtered = 0 if rseed is None: rseed = list(range(N_runs)) if len(rseed)!= N_runs: print('not enough seeds') else: s = time.process_time() # STEP 1: pre extraction # parameters: #t2 = .5 number_of_colors = 0 number_of_cc = 1 graph_type = '1' t1 = 0.0 print(ds_interpolation) G_pre_extracted, color_dict, partition_dict, folder_path = pre_extraction.pre_extraction_from_image(image_path, new_size, t2, number_of_colors, number_of_cc, graph_type, t1, reversed_colors, ds_interpolation = ds_interpolation) Gpe_nodes = len(G_pre_extracted.nodes()) Gpe_edges = len(G_pre_extracted.edges()) print('Gpe: n_nodes,n_edges:',len(G_pre_extracted.nodes()),len(G_pre_extracted.edges())) #G_pre_extracted = filtering.bifurcation_paths(G_pre_extracted,[]) ## STEP 2: tree approximation #sys.exit() # bfs_Graph = steiner_tree(G_pre_extracted, list(G_pre_extracted.nodes())) mst = tree.maximum_spanning_edges(G_pre_extracted, algorithm='kruskal', data='weight') bfs_Graph = nx.Graph() bfs_Graph.add_edges_from(list(mst)) # bfs_Graph = pre_extraction.tree_approximation(G_pre_extracted, color_dict, partition_dict, folder_path) with open(folder_path + '/bfs_extracted_graph.pkl', 'wb') as file: pkl.dump(bfs_Graph, file) with open(folder_path + '/other_par.pkl', 'wb') as file: pkl.dump([color_dict, partition_dict, folder_path], file) print('info stored') if cluster_flag: folder_path_cluster = './runs/'+image_path.split('/')[-2]+'/'+(image_path.split('/')[-1]).split('.')[0] ''' print('fpc',folder_path_cluster) with open(folder_path_cluster + '/other_par.pkl', 'rb') as file: [color_dict, partition_dict, folder_path] = pkl.load(file) with open(folder_path_cluster + '/extracted_graph.pkl', 'rb') as file: G_pre_extracted = pkl.load(file) with open(folder_path_cluster + '/bfs_extracted_graph.pkl', 'rb') as file: bfs_Graph = pkl.load(file) ''' # STEP #3: filtering (via MST) # computing the leaves deg = nx.degree_centrality(bfs_Graph) N = len(bfs_Graph.nodes) for node in deg.keys(): deg[node] = round(deg[node] * (N - 1)) terminal_candidates= [node for node in bfs_Graph.nodes() if deg[node] == 1] print('leaves',len(terminal_candidates)) Gf = {} terminals = {} for i in range(N_runs): print('steiner tree n=',i) # getting a random terminals #terminal_list = [random.choice(terminal_candidates) for i in range(int(.025 * len(terminal_candidates)))] terminal_list = [] print('random seed',rseed[i]) rng = np.random.RandomState(seed=rseed[i]) node = rng.choice(terminal_candidates) terminal_list.append(node) print('number of terminals',int(.025 * len(terminal_candidates))) while len(terminal_list)<int(.025 * len(terminal_candidates)): #print('i',i) node = rng.choice(terminal_candidates) #terminal_list.append(node) #print('node',node) node_pos = G_pre_extracted.nodes[node]['pos'] dist_bool = [] for elem in terminal_list: if elem != node: #print('elem!= node') elem_pos = G_pre_extracted.nodes[elem]['pos'] val = distance.euclidean(elem_pos,node_pos)>.2 dist_bool.append(val) #print('db',dist_bool) #print('db',dist_bool) if sum(dist_bool)==len(dist_bool): terminal_list.append(node) print('terminal_list',terminal_list) print('computing steiner tree:') G_filtered = steiner_tree(G_pre_extracted, terminal_list) G_filtered = quality_measure.relabeling(G_filtered, G_pre_extracted) Gf[i] = G_filtered terminals[i] = terminal_list #print(terminal_list) for i in range(N_runs): graph = Gf[i] terminal_list = terminals[i] #print('terminals',terminal_list) print('------random n=:'+str(i)+'----------: n_nodes:',len(graph.nodes()),', n_edges:',len(graph.edges())) pre_extraction.plt_graph_plots([graph], partition_dict, color_dict, folder_path_cluster, '/G_filtered' + str(i) + '.png', alpha=.6, width_list=[3], color_list=['black'], highlighted_nodes=[terminal_list]) #with open(folder_path + '/G_filtered' + str(i) + '.pkl', 'wb') as file: # pkl.dump(graph, file) G_filtered = img2net.superimposing_graphs(Gf.values(), G_pre_extracted, union_type) weights = [8*G_filtered.edges[edge]['weight'] for edge in G_filtered.edges()] pre_extraction.plt_graph_plots([G_filtered], partition_dict, color_dict, folder_path, '/G_filtered.png', alpha=.5, width_list=[weights], color_list=['black'] ) with open(folder_path_cluster + '/G_filtered.pkl', 'wb') as file: pkl.dump(G_filtered, file) print('storing results at:',folder_path_cluster) ''' try: os.system('rm -r '+ '../../data/output/test/'+folder_path.split('/')[-1]+'/mst/') except: pass ''' #img2net.move_files(folder_path_cluster,'../../data/output/test/'+folder_path.split('/')[-1]+'/mst/') #os.system('rm -r '+folder_path) e = time.process_time() execution_time = e-s ''' with open( '../../data/output/test/'+folder_path.split('/')[-1]+'/mst/ex_time.pkl', 'wb') as file: pkl.dump(execution_time, file) ''' return G_filtered, Gpe_nodes, Gpe_edges