def __init__(self, genomes, name, log_file, tl): if len(genomes) != 3: raise Exception("Incorrect number of genomes for median problem") self.gene_sets = [ set(genome.get_gene_multiset().keys()) for genome in genomes ] self.s_all_genes = complete_genes_multiset( reduce(operator.or_, self.gene_sets, set()), 1) self.cbg_vertex_set = vertex_set_from_gene_multiset(self.s_all_genes) self.cbg_ind2vertex = [''] + [u for u in self.cbg_vertex_set] self.cbg_vertex2ind = { self.cbg_ind2vertex[i]: i for i in range(1, len(self.cbg_ind2vertex)) } obverse_edges = observed_edges_from_gene_multiset(self.s_all_genes) self.ind_cbg_obverse_edges = { tuple(sorted((self.cbg_vertex2ind[u], self.cbg_vertex2ind[v]))) for u, v in obverse_edges } genome_graphs = [ genome.convert_to_genome_graph() for genome in genomes ] self.ind_cbg_p_i_vertex_sets = [{ self.cbg_vertex2ind[u] for u in vertex_set_from_gene_multiset( complete_genes_multiset(gene_set, 1)) } for gene_set in self.gene_sets] self.ind_cbg_p_i_edges = [{ tuple(sorted((self.cbg_vertex2ind[u], self.cbg_vertex2ind[v]))) for u, v in matching } for matching, _ in genome_graphs] self.ind_cbg_p_i_telomers = [{ self.cbg_vertex2ind[u] for u in telomers } for _, telomers in genome_graphs] self.ind_ancestral_set = set( reduce(operator.or_, [ self.ind_cbg_p_i_vertex_sets[i] & self.ind_cbg_p_i_vertex_sets[j] for i, j in itertools.combinations(range(len(genomes)), 2) ], set())) self.ancestral_gene_set = reduce(operator.or_, [ self.gene_sets[i] & self.gene_sets[j] for i, j in itertools.combinations(range(len(self.gene_sets)), 2) ], set()) self.number_of_genomes = len(genomes) self.biggest_const = len(self.cbg_ind2vertex) self.name_model = name self.log_file = log_file self.time_limit = tl flag = False for i in range(3): if len(self.ind_cbg_p_i_telomers[i]) != 0: flag = True self.allowable_telomers = {x: flag for x in self.ind_ancestral_set} graph = nx.MultiGraph() graph.add_nodes_from(self.cbg_vertex2ind.values()) for edges in self.ind_cbg_p_i_edges[0:2]: for u, v in edges: graph.add_edge(u, v) self.allowable_ancestral_edges = set() self.connection_constrs = dict() for component in nx.connected_component_subgraphs(graph): for v in component.nodes(): connect_indices = set() for u in component.nodes(): if u != v: self.allowable_ancestral_edges.add( tuple(sorted((u, v)))) connect_indices.add(tuple(sorted((u, v)))) self.connection_constrs[v] = connect_indices self.number_of_cycles = 0 self.number_of_even_paths = 0 for component in nx.connected_component_subgraphs(graph): isCycle = True for v in component.nodes(): if graph.degree(v) != 2: isCycle = False if isCycle: self.number_of_cycles += 1 elif (len(component.nodes()) - 1) % 2 == 0: self.number_of_even_paths += 1
import networkx as nx import matplotlib.pyplot as plt graph = nx.MultiGraph(["ab", "ab"]) S = {"a"} T = {"b"} nx.draw_planar(G=graph, with_labels=True, node_color='g', node_size=800, font_size=14, width=0.8) plt.show() print(nx.cut_size(graph, {"a"}, {"b"}))
def test_periodicity(self): en1 = EnvironmentNode(central_site='Si', i_central_site=3, ce_symbol='T:4') en2 = EnvironmentNode(central_site='Ag', i_central_site=5, ce_symbol='T:4') en3 = EnvironmentNode(central_site='Ag', i_central_site=8, ce_symbol='O:6') en4 = EnvironmentNode(central_site='Fe', i_central_site=23, ce_symbol='C:8') graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3]) graph.add_edge(en1, en2, start=en1.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en3, start=en1.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(10, (0, 0, 1), (0, 0, 1)), (11, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) assert cc.is_0d assert not cc.is_1d assert not cc.is_2d assert not cc.is_3d assert not cc.is_periodic assert cc.periodicity == '0D' graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3]) graph.add_edge(en1, en2, start=en1.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en3, start=en1.isite, end=en3.isite, delta=(0, 0, 0), ligands=[(10, (0, 0, 1), (0, 0, 1)), (11, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en2, en3, start=en2.isite, end=en3.isite, delta=(0, 0, 1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) assert not cc.is_0d assert cc.is_1d assert not cc.is_2d assert not cc.is_3d assert cc.is_periodic assert cc.periodicity == '1D' graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3]) graph.add_edge(en1, en2, start=en1.isite, end=en2.isite, delta=(0, 0, 1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en3, start=en1.isite, end=en3.isite, delta=(0, 0, 0), ligands=[(10, (0, 0, 1), (0, 0, 1)), (11, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en2, en3, start=en2.isite, end=en3.isite, delta=(0, 0, -1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) assert cc.periodicity == '0D' # Test errors when computing periodicity graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3]) graph.add_edge(en1, en1, start=en1.isite, end=en1.isite, delta=(0, 0, 1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en1, start=en1.isite, end=en1.isite, delta=(0, 0, 1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) with pytest.raises( ValueError, match=r'There should not be self loops with the same ' r'\x28or opposite\x29 delta image\x2E'): cc.compute_periodicity_all_simple_paths_algorithm() graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3]) graph.add_edge(en1, en1, start=en1.isite, end=en1.isite, delta=(3, 2, -1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en1, start=en1.isite, end=en1.isite, delta=(-3, -2, 1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) with pytest.raises( ValueError, match=r'There should not be self loops with the same ' r'\x28or opposite\x29 delta image\x2E'): cc.compute_periodicity_all_simple_paths_algorithm() graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3]) graph.add_edge(en1, en1, start=en1.isite, end=en1.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) with pytest.raises( ValueError, match=r'There should not be self loops with delta image = ' r'\x280, 0, 0\x29\x2E'): cc.compute_periodicity_all_simple_paths_algorithm() # Test a 2d periodicity graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3, en4]) graph.add_edge(en1, en2, start=en1.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en3, start=en1.isite, end=en3.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en4, en2, start=en4.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en3, en4, start=en4.isite, end=en3.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en3, en4, start=en4.isite, end=en3.isite, delta=(0, -1, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en3, en2, start=en2.isite, end=en3.isite, delta=(-1, -1, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) assert not cc.is_0d assert not cc.is_1d assert cc.is_2d assert not cc.is_3d assert cc.is_periodic assert cc.periodicity == '2D' assert np.allclose( cc.periodicity_vectors, [np.array([0, 1, 0]), np.array([1, 1, 0])]) assert type(cc.periodicity_vectors) is list assert cc.periodicity_vectors[0].dtype is np.dtype(int) # Test a 3d periodicity graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3, en4]) graph.add_edge(en1, en2, start=en1.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en3, start=en1.isite, end=en3.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en4, en2, start=en4.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en3, en4, start=en4.isite, end=en3.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en3, en4, start=en4.isite, end=en3.isite, delta=(0, -1, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en3, en2, start=en2.isite, end=en3.isite, delta=(-1, -1, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en3, en3, start=en3.isite, end=en3.isite, delta=(-1, -1, -1), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) assert not cc.is_0d assert not cc.is_1d assert not cc.is_2d assert cc.is_3d assert cc.is_periodic assert cc.periodicity == '3D' assert np.allclose( cc.periodicity_vectors, [np.array([0, 1, 0]), np.array([1, 1, 0]), np.array([1, 1, 1])]) assert type(cc.periodicity_vectors) is list assert cc.periodicity_vectors[0].dtype is np.dtype(int)
def __init__(self, Edges, Weight, RM_List): self.Edges = Edges self.Weight = Weight self.RM_List = RM_List self.RM_Number = len(RM_List) #!!! # extracting lims of matrices. M_Lims = [x[y] for x in Edges for y in [0, 1]] # selecting lims of random matrices. RM_Lims = [ x for x in M_Lims for rm in RM_List if x[0] == rm[0] or x[0] == rm[0] + '*' ] # identifying matrices from the above list of lims. Matrices = [x[0:2] for x in M_Lims] # for each random matrix set explicitly, we collect and sort random matrices identified from the lims. RM1 = [ sorted([x for x in Matrices if x[0] == rm[0]], key=lambda t: t[1]) for rm in RM_List ] RM2 = [ sorted([x for x in Matrices if x[0] == rm[0] + '*'], key=lambda t: t[1]) for rm in RM_List ] # putting the same matrices together. self.RM1_grouped = [[x for x, y in groupby(rm1)] for rm1 in RM1] #!!!(?) RM2_grouped = sorted([[x for x, y in groupby(rm2)] for rm2 in RM2]) # listing random matrices in the calculus. self.RMs = [y[0] for x in self.RM1_grouped for y in x] + [y[0] for x in RM2_grouped for y in x] #!!! # relabeling the random matrices for the sake of Weingarten calculus. RM1_Labels = [[[rm1g[i][0:2], [rm1g[i][0], i]] for i in range(len(rm1g))] for rm1g in self.RM1_grouped] RM2_Labels = [[[rm2g[i][0:2], [rm2g[i][0], i]] for i in range(len(rm2g))] for rm2g in RM2_grouped] # making a dictionary for relabeling. Translation = [ [x[0][0]+str(x[0][1]) ,x[1][0:2]] for i in range(self.RM_Number) for x in RM1_Labels[i] ]+\ [ [x[0][0]+str(x[0][1]) ,x[1][0:2]] for i in range(self.RM_Number) for x in RM2_Labels[i] ] Translation_inv = [ [x[1][0]+str(x[1][1]) ,x[0][0]+str(x[0][1])] for i in range(self.RM_Number) for x in RM1_Labels[i] ]+\ [ [x[1][0]+str(x[1][1]) ,x[0][0]+str(x[0][1])] for i in range(self.RM_Number) for x in RM2_Labels[i] ] self.Label_Dic = dict(Translation) #!!! self.Label_Dic_inv = dict(Translation_inv) #!!! # listing all possible limes; # for each random matrix set explicitly, # generating all the lims of random matrices in the calculus. RM_Lims_generated1 =\ [[x+['L',y] for x in self.RM1_grouped[i] for y in range(len(RM_List[i][1]))]\ +[x+['R',y] for x in self.RM1_grouped[i] for y in range(len(RM_List[i][2]))] for i in range(self.RM_Number)] RM_Lims_generated2 =\ [[x+['L',y] for x in RM2_grouped[i] for y in range(len(RM_List[i][2]))]\ +[x+['R',y] for x in RM2_grouped[i] for y in range(len(RM_List[i][1]))] for i in range(self.RM_Number)] RM_Lims_generated = [[x for x in RM_Lims_generated1[i] ] +\ [x for x in RM_Lims_generated2[i] ] for i in range(self.RM_Number)] RM_Lims_generated_flat = [ x for i in range(self.RM_Number) for x in RM_Lims_generated[i] ] self.RMLg_String = [[ x[0] + str(x[1]) + x[2] + str(x[3]) for x in RM_Lims_generated[i] ] for i in range(self.RM_Number)] #!!! # listing lims of random matrices without *. self.RMLg1_relabeled = [[ self.Label_Dic[x[0] + str(x[1])] + x[2:4] for x in RM_Lims_generated1[i] ] for i in range(self.RM_Number)] #!!! # finding empty lims. RM_Lims_empty = [x for x in RM_Lims_generated_flat if x not in RM_Lims] # adding extra edges for each empty lim. Edges_extra = [[x, ['@' + x[0]] + x[1:4]] for x in RM_Lims_empty] # preparing edges for Weingarten calculus. Edges_Graph = Edges + Edges_extra # treating cases which gives 0. for i in range(self.RM_Number): if [len(x) for x in self.RM1_grouped[i] ] != [len(x) for x in RM2_grouped[i]]: Edges_Graph.clear() Weight = 0 else: pass # preparing a graph for Weingarten calculus; self.G = nx.MultiGraph() for x in Edges_Graph: a = x[0][0] + str(x[0][1]) + x[0][2] + str(x[0][3]) b = x[1][0] + str(x[1][1]) + x[1][2] + str(x[1][3]) self.G.add_edge(a, b, info=[a, b]) # storing the original lists, aftet changing them into strings. self.G.nodes[a]['original'] = x[0] self.G.nodes[b]['original'] = x[1]
def random_walk_transform_multigraph(G, t, alpha=1.0): aG = nx.MultiGraph() deg_dict = nx.degree(G) nb_list = [] # neighbor list: list of lists nb_len = [] for u in G.nodes_iter(): nb_list.append(G.neighbors(u)) nb_len.append(len(G.neighbors(u))) # WAY-1 for u in G.nodes_iter(): count = 1 for v in G.neighbors_iter(u): # perform (t-1) hop random walk from v z = v for i in range(t - 1): z = nb_list[z][random.randint(0, nb_len[z] - 1)] # if count == 1: if deg_dict[u] == 1: # EXCEPTION ! val = random.random() if val < 0.5: aG.add_edge(u, z) else: val = random.random() # use alpha if val < alpha: aG.add_edge(u, z) else: val = random.random() if val < (0.5 * deg_dict[u] - alpha) / (deg_dict[u] - 1): # use alpha aG.add_edge(u, z) # count += 1 # # WAY-2 # potential_edges = [] # list of edges # for u in G.nodes_iter(): # count = 1 # for v in G.neighbors_iter(u): # # perform (t-1) hop random walk from v # z = v # for i in range(t-1): # z = nb_list[z][random.randint(0,nb_len[z]-1)] # # # if count == 1: # if deg_dict[u] == 1: # EXCEPTION ! # val = random.random() # if val < 0.5: # aG.add_edge(u, z) # else: # aG.add_edge(u, z) # else: # potential_edges.append((u,z)) # # # count += 1 # # rand_vals = np.random.random_sample((len(potential_edges),)) # i = 0 # for (u,z) in potential_edges: ## val = random.random() # val = rand_vals[i] # i +=1 # if val < (0.5*deg_dict[u] - 1.0)/(deg_dict[u] - 1.0): # aG.add_edge(u, z) # return aG
def create_amazon_graph(self, line_limit=-1, review_limit=-1, is_graph_with_unknown_nodes=False, category_file=None, amazon_file=None, estimated_n_reviews=34686770): """ Create amazon graph - user-product connections with additional information related to user and connections such as: user name, and purchase details as connection properties. :param amazon_file: path to amazon's file (every attribute in separate line) :param category_file: path to amazon's category file :param line_limit: # of line to load from big amazon file :param review_limit: # of reviews to load :param is_graph_with_unknown_nodes: do you want to user unknown nodes in network? Some of the users/products are unknown, hence it is good idea to remove/skip them during network creation. :return: Graph Tool or NetworkX graph object - default Graph Tool, if you do not have graph tool installed NetworkX, will be used """ adp = pa.AmazonDatasetParser(category_file=category_file, amazon_file=amazon_file) log.debug('AmazonDatasetParser done!') n_reviews = 0 start = datetime.datetime.now() user_id_idx = OrderedDict() product_id_idx = OrderedDict() if _graph_tool: g = Graph() product_id_prop = g.new_vertex_property('string') user_id_prop = g.new_vertex_property('string') profile_name_prop = g.new_vertex_property('string') text_prop = g.new_edge_property('string') score_prop = g.new_edge_property('float') summary_prop = g.new_edge_property('string') price_prop = g.new_edge_property('float') helpfulness_prop = g.new_edge_property('string') title_prop = g.new_edge_property('string') time_prop = g.new_edge_property('string') else: g = nx.MultiGraph() for product_id, user_id, profile_name, text, score, summary, price, \ helpfulness, title, time, n_reviews in adp.amazon_snap_initial_parser( threshold_reviews=review_limit, threshold_lines=line_limit, is_graph_with_unknown_nodes=is_graph_with_unknown_nodes): # print [product_id, user_id, profile_name, text, score, summary, # price, helpfulness, title, time] # with bipartite attribute it's easier to divide node set into # two parts if not (n_reviews % 1000): log.info('Number of the reviews: {}'.format(n_reviews)) if not (n_reviews % 10000): delta = ((datetime.datetime.now() - start).seconds / 60) estimated_time = (delta * estimated_n_reviews) / delta log.info('Estimated time to end: {}min, {}h, {}d'.format( estimated_time, estimated_time / 60, {estimated_time / 60 / 24})) if _graph_tool: # TODO: profile this line # check if vertex in dictionary # add if not vertex_user = self.get_vertex_obj(user_id, user_id_idx, g) # log.debug('User vertex {}'.format(vertex_user)) if vertex_user is None: vertex_user = g.add_vertex() user_id_idx[user_id] = vertex_user profile_name_prop[vertex_user] = profile_name user_id_prop[vertex_user] = user_id vertex_product = self.get_vertex_obj(product_id, product_id_idx, g) # log.debug('Product vertex {}'.format(vertex_product)) if vertex_product is None: vertex_product = g.add_vertex() product_id_idx[product_id] = vertex_product product_id_prop[vertex_product] = product_id # log.debug('Add edge for: {}-{}'.format(vertex_user, vertex_product)) edge = g.add_edge(vertex_user, vertex_product) text_prop[edge] = text try: sc = float(score) except ValueError: sc = -1.0 # log.info('Score is not number: {}'.format(score)) score_prop[edge] = sc summary_prop[edge] = summary try: prc = float(price) except ValueError: prc = -1.0 # log.info('Score is not number: {}'.format(price)) price_prop[edge] = prc helpfulness_prop[edge] = helpfulness title_prop[edge] = title time_prop[edge] = time else: g.add_node(user_id, profile_name=profile_name, bipartite=0) g.add_edge(product_id, user_id, text=text, score=score, summary=summary, price=price, helpfulness=helpfulness, title=title, time=time, bipartite=1) log.info('#{} of the reviews were processed'.format(n_reviews)) delta = datetime.datetime.now() - start log.info('The reviews were processed in {}s'.format(delta.seconds)) return g
help="Save a .dot file (networkx). Specify the file without extension", required=True) args = parser.parse_args() # Open the file with open(args.planar, 'r') as fp: g_faces = json.load(fp) # Cast back to tuples. json.dump write the "list of list of tuples" as "list of list of list" # # Original: [[(3,2),(3,5)],[(2,4),(1,3),(1,3)], ... ,[(1,2),(3,4),(6,7)]] # Saved as: [[[3,2],[3,5]],[[2,4],[1,3],[1,3]], ... ,[[1,2],[3,4],[6,7]]] g_faces = [[tuple(l) for l in L] for L in g_faces] # Create the graph from the list of faces (flat them) flattened_egdes = [edge for face in g_faces for edge in face] for edge in flattened_egdes: reverse_edge = (edge[1], edge[0]) if reverse_edge in flattened_egdes: flattened_egdes.remove(reverse_edge) # Create an empty graph # Load the graph the_graph = nx.MultiGraph() for edge_to_add in flattened_egdes: the_graph.add_edge(edge_to_add[0], edge_to_add[1]) # Export export_graph(the_graph, args.output)
def from_pydot(P): """Return a NetworkX graph from a Pydot graph. Parameters ---------- P : Pydot graph A graph created with Pydot Returns ------- G : NetworkX multigraph A MultiGraph or MultiDiGraph. Examples -------- >>> K5=nx.complete_graph(5) >>> A=nx.to_pydot(K5) >>> G=nx.from_pydot(A) # return MultiGraph >>> G=nx.Graph(nx.from_pydot(A)) # make a Graph instead of MultiGraph """ if P.get_strict(None): # pydot bug: get_strict() shouldn't take argument multiedges = False else: multiedges = True if P.get_type() == 'graph': # undirected if multiedges: create_using = nx.MultiGraph() else: create_using = nx.Graph() else: if multiedges: create_using = nx.MultiDiGraph() else: create_using = nx.DiGraph() # assign defaults N = nx.empty_graph(0, create_using) N.name = P.get_name() # add nodes, attributes to N.node_attr for p in P.get_node_list(): n = p.get_name().strip('"') if n in ('node', 'graph', 'edge'): continue N.add_node(n, **p.get_attributes()) # add edges for e in P.get_edge_list(): u = e.get_source().strip('"') v = e.get_destination().strip('"') attr = e.get_attributes() N.add_edge(u, v, **attr) # add default attributes for graph, nodes, edges N.graph['graph'] = P.get_attributes() try: N.graph['node'] = P.get_node_defaults()[0] except: # IndexError,TypeError: N.graph['node'] = {} try: N.graph['edge'] = P.get_edge_defaults()[0] except: # IndexError,TypeError: N.graph['edge'] = {} return N
def solve_chinese_postman_problem(graph, start=None, end=None, matching_algorithm='efficient', is_multigraph=False): ''' Solves the chinese postman problem using the classical solution. 'Efficient' algorithm uses Edmund and Johnson's solution (1976) to find optimal edges. 'Original' tries all possible edge combinations and selects the smallest one (slow) ''' #Deals with start/end nodes and computes least total distance and backtracked nodes odd_node_list, odd_node_pairing_distance = analyze_odd_nodes(graph) if start == None or end == None: possible_startend_pairs = get_all_possible_pairings( odd_node_list, start, end) startend_dict = { } #{(start,end) : (least_total_distance, backtracked_edges)} for startend_pair in possible_startend_pairs: current_odd_node_list = [ n for n in odd_node_list if n not in startend_pair ] least_total_distance, backtracked_edges = find_optimal_graph_extension( graph, current_odd_node_list, odd_node_pairing_distance, matching_algorithm=matching_algorithm) startend_dict[startend_pair] = (least_total_distance, backtracked_edges) optimal_pair = min(startend_dict.keys(), key=lambda x: startend_dict[x][0]) least_total_distance, backtracked_edges = startend_dict[optimal_pair] start, end = optimal_pair else: if start not in odd_node_list or end not in odd_node_list: print 'WARNING: start and/or end are not odd, ending point might be unexpected' #If both start and end are specified, check if they are odd nodes current_odd_node_list = copy.deepcopy(odd_node_list) print current_odd_node_list, len(current_odd_node_list) if start != end: try: current_odd_node_list.remove(start) except ValueError: pass try: current_odd_node_list.remove(end) except ValueError: pass least_total_distance, backtracked_edges = find_optimal_graph_extension( graph, current_odd_node_list, odd_node_pairing_distance, matching_algorithm=matching_algorithm) else: least_total_distance, backtracked_edges = find_optimal_graph_extension( graph, odd_node_list, odd_node_pairing_distance, matching_algorithm=matching_algorithm) #Create enhanced eulerian graph in which backtracked edges are repeated graph_extended = nx.MultiGraph(graph) for node1, node2 in backtracked_edges: graph_extended.add_edge( node1, node2, attr_dict={'length': graph[node1][node2]['length']}) print backtracked_edges if start == end: path = find_eulerian_path_same_startend(graph_extended, start) else: path = find_eulerian_path_different_startend(graph_extended, start, end) check_distance = 0 prev_node = start for node in path[1:]: check_distance += graph.edge[prev_node][node]['length'] prev_node = node if least_total_distance < check_distance: diff = check_distance - least_total_distance #To avoid floating point errors, only consider it a problem if the difference is more than 1% the least distance if float(diff) / least_total_distance > 0.01: print 'WARNING: PATH OF FINAL DISTANCE IS NOT OPTIMAL, TRAVELLED %.3f MORE' % diff check_path = check_solution(graph, path) if check_path == False: print 'WARNING: NOT ALL EDGES HAVE BEEN VISITED' if is_multigraph == True: # Modify duplicated nodes node_type = type(path[0]) new_path = [] for node in path: if type(node) == str: if "\'" in node: node = node.replace("\'", "") node = node_type(node) if len(new_path) > 0 and node == new_path[-1]: continue new_path.append(node) path = new_path return least_total_distance, path
def test_bidirectional_dijkstra_multigraph(self): G = nx.MultiGraph() G.add_edge('a', 'b', weight=10) G.add_edge('a', 'b', weight=100) dp = nx.bidirectional_dijkstra(G, 'a', 'b') assert_equal(dp, (10, ['a', 'b']))
plt.figure() nx.draw_networkx(G11) plt.show() G12 = nx.Graph() G12.add_edge('A', 'B', relation='friend') G12.add_edge('B', 'C', relation='coworker') G12.add_edge('C', 'D', relation='family') G12.add_edge('E', 'F', relation='neighbor') print('网络符号:',G12.edges(data=True)) plt.figure() nx.draw_networkx(G12) plt.show() # 多重图 G13 = nx.MultiGraph() G13.add_edge('A', 'B', relation='friend') G13.add_edge('A', 'B', relation='neighbor') G13.add_edge('G', 'F', relation='family') G13.add_edge('G', 'F', relation='coworker') print('多重图:',G13.edges(data=True)) plt.figure() nx.draw_networkx(G13) plt.show() # 6 网络的属性访问 # 6.1 边属性的访问 G14 = nx.Graph() G14.add_edge('A','B',weight=6,relation='family')
def make_graph(self, graph_xml): # start with empty DiGraph or MultiDiGraph edgedefault = graph_xml.get("defaultedgetype", None) if edgedefault == "directed": G = nx.MultiDiGraph() else: G = nx.MultiGraph() # graph attributes graph_name = graph_xml.get("name", "") if graph_name != "": G.graph["name"] = graph_name graph_start = graph_xml.get("start") if graph_start is not None: G.graph["start"] = graph_start graph_end = graph_xml.get("end") if graph_end is not None: G.graph["end"] = graph_end graph_mode = graph_xml.get("mode", "") if graph_mode == "dynamic": G.graph["mode"] = "dynamic" else: G.graph["mode"] = "static" # timeformat self.timeformat = graph_xml.get("timeformat") if self.timeformat == "date": self.timeformat = "string" # node and edge attributes attributes_elements = graph_xml.findall( f"{{{self.NS_GEXF}}}attributes") # dictionaries to hold attributes and attribute defaults node_attr = {} node_default = {} edge_attr = {} edge_default = {} for a in attributes_elements: attr_class = a.get("class") if attr_class == "node": na, nd = self.find_gexf_attributes(a) node_attr.update(na) node_default.update(nd) G.graph["node_default"] = node_default elif attr_class == "edge": ea, ed = self.find_gexf_attributes(a) edge_attr.update(ea) edge_default.update(ed) G.graph["edge_default"] = edge_default else: raise # unknown attribute class # Hack to handle Gephi0.7beta bug # add weight attribute ea = { "weight": { "type": "double", "mode": "static", "title": "weight" } } ed = {} edge_attr.update(ea) edge_default.update(ed) G.graph["edge_default"] = edge_default # add nodes nodes_element = graph_xml.find(f"{{{self.NS_GEXF}}}nodes") if nodes_element is not None: for node_xml in nodes_element.findall(f"{{{self.NS_GEXF}}}node"): self.add_node(G, node_xml, node_attr) # add edges edges_element = graph_xml.find(f"{{{self.NS_GEXF}}}edges") if edges_element is not None: for edge_xml in edges_element.findall(f"{{{self.NS_GEXF}}}edge"): self.add_edge(G, edge_xml, edge_attr) # switch to Graph or DiGraph if no parallel edges were found. if self.simple_graph: if G.is_directed(): G = nx.DiGraph(G) else: G = nx.Graph(G) return G
def networks(idlist, token): # print ("Let me calculate a network of co-usership between the pages you provided...") # pageids = [] # userids = [] # udict = {} # actdict = {} # cdict = {} # pdict = {} # rdict = {} # ids = idlist # for i in ids: # if os.path.isfile("posts_from_"+i+".csv"): # # with open ("posts_from_"+i+".csv", encoding="utf-8") as file: # readCSV = csv.reader((x.replace('\0', '') for x in file), delimiter=';') # next(readCSV) # rows = 0 # typesof = [] # users = [] # for row in readCSV: # pageid=row[0] # userid=row[2] # typeof=row[4] # pageids.append(pageid) # userids.append(userid) # users.append(userid) # typesof.append(typeof) # rows = rows+1 # udict.update({i: len(set(users))}) # actdict.update({i: rows}) # cdict.update({i: typesof.count("comment")}) # pdict.update({i: typesof.count("status") + typesof.count("photo") + typesof.count("video") + typesof.count("link") + typesof.count("event")}) # rdict.update({i: typesof.count("LIKE") + typesof.count("SAD") + typesof.count("HAHA") + typesof.count("LOVE") + typesof.count("ANGRY")+ typesof.count("WOW")}) # # else: # print("The Facebook ID"+i+"has no matching file in the working directory. Has data been collected correctly?") # # # print("Handled "+str(len(actdict))+" page IDs.") # # # trim idlist and dicts for empty entries: # actdict = {k: v for k, v in actdict.items() if v != 0} # ids = list(actdict.keys()) # udict = {k: v for k, v in udict.items() if k in ids} # cdict = {k: v for k, v in cdict.items() if k in ids} # pdict = {k: v for k, v in pdict.items() if k in ids} # rdict = {k: v for k, v in rdict.items() if k in ids} ## the problem is: admin and page_id are identical: when admin from page A posts on page B, ## the graph is not strictly bipartite anymore, as now we do not ONLY have user-page connection, ## but page-page connection. ## those users that are page_admins (i.e. have the same user_id as page_id) will get little "admin" remark ## and applied it: # userids = change_id(ids, userids) ## write out to a bipartite edgelist # with open("edgelist_user.csv", "w", newline='', encoding="utf-8") as file: # writer = csv.writer(file, delimiter=";") # writer.writerow(["Source","Target"]) # for i in range(len(userids)): # # writer.writerow([userids[i], pageids[i]]) # ## # dicti = [] # for i in range(len(userids)): # zeile = (userids[i], pageids[i]) # dicti.append(zeile) # ## and get us our networks: # # G=nx.MultiGraph() # G.add_edges_from(dicti) # for u,v,data in G.edges(data=True): # w = data['weight'] = 1.0 # G.edges(data=True) # # H = nx.Graph() # for u,v,data in G.edges(data=True): # w = data['weight'] # if H.has_edge(u,v): # H[u][v]['weight'] += w # else: # H.add_edge(u, v, weight=w) ## H.edges(data=True) ## H.is_directed() ## nx.is_bipartite(H) # F = bipartite.weighted_projected_graph(H, ids, ratio=False) # nx.set_node_attributes(F, actdict, 'total_activities') # nx.set_node_attributes(F, udict, 'unique_users') # nx.set_node_attributes(F, cdict, 'comments') # nx.set_node_attributes(F, pdict, 'posts') # nx.set_node_attributes(F, rdict, 'reactions') # elist = list(F.edges()) # for i in elist: # F[i[0]][i[1]]['sfrac'] = F[i[0]][i[1]]['weight'] / udict.get(i[0]) # F[i[0]][i[1]]['tfrac'] = F[i[0]][i[1]]['weight'] / udict.get(i[1]) # if F[i[0]][i[1]]['sfrac'] < F[i[0]][i[1]]['tfrac']: # F[i[0]][i[1]]['maxfrac'] = F[i[0]][i[1]]['sfrac'] # else: # F[i[0]][i[1]]['maxfrac'] = F[i[0]][i[1]]['tfrac'] # pagenames = [] # for i in ids: # a = getpageinfo(token,i) # pagenames.append (a["name"]) # mapping = dict(zip(ids, pagenames)) # F=nx.relabel_nodes(F,mapping) # nx.write_graphml(F, "user_projection_pages.graphml") # nx.write_weighted_edgelist(F, 'user_projection_edgelist.csv', delimiter=";", encoding="utf-8") # print("Done with the user-overlap - You'll find a weighted edgelist in csv-format and a graphml-file in your working directory.") print ("Let me calculate a network of content overlap between the pages you provided...") # next we set a regular expression to extract links. MIT license from Diego Perini (https://gist.github.com/dperini/729294) #URL_REGEX = r'^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$' URL_REGEX = re.compile( u"^" # protocol identifier u"(?:(?:https?|ftp)://)" # user:pass authentication u"(?:\S+(?::\S*)?@)?" u"(?:" # IP address exclusion # private & local networks u"(?!(?:10|127)(?:\.\d{1,3}){3})" u"(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})" u"(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})" # IP address dotted notation octets # excludes loopback network 0.0.0.0 # excludes reserved space >= 224.0.0.0 # excludes network & broadcast addresses # (first & last IP address of each class) u"(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])" u"(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}" u"(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))" u"|" # host name u"(?:(?:[a-z\u00a1-\uffff0-9]-?)*[a-z\u00a1-\uffff0-9]+)" # domain name u"(?:\.(?:[a-z\u00a1-\uffff0-9]-?)*[a-z\u00a1-\uffff0-9]+)*" # TLD identifier u"(?:\.(?:[a-z\u00a1-\uffff]{2,}))" u")" # port number u"(?::\d{2,5})?" # resource path u"(?:/\S*)?" u"$" , re.UNICODE) content_edgelist = [] idict = {} actdict = {} cdict = {} pdict = {} rdict = {} ids = idlist for i in ids: linkids = [] messageids = [] pageids = [] with open ("posts_from_"+i+".csv", encoding="utf-8") as file: readCSV = csv.reader((x.replace('\0', '') for x in file), delimiter=';') next(readCSV) rows = 0 typesof = [] for row in readCSV: pageid=row[0] typeof=row[4] linkid=row[5] messageid=row[7] pageids.append(pageid) linkids.append(linkid) messageids.append(messageid) typesof.append(typeof) rows = rows+1 actdict.update({i: rows}) cdict.update({i: typesof.count("comment")}) pdict.update({i: typesof.count("status") + typesof.count("photo") + typesof.count("video") + typesof.count("link") + typesof.count("event")}) rdict.update({i: typesof.count("LIKE") + typesof.count("SAD") + typesof.count("HAHA") + typesof.count("LOVE") + typesof.count("ANGRY")+ typesof.count("WOW")}) urls = [] for x in messageids: if isinstance(x, str) == True: for url in re.findall(URL_REGEX, x): urls.append(url) for x in linkids: if isinstance(x, str) == True: for url in re.findall(URL_REGEX, x): urls.append(url) urlset = set(urls) uniqueurls = list(urlset) idict.update({i: len(urlset)}) for i in range(len(uniqueurls)): zeile = (uniqueurls[i], pageids[0]) content_edgelist.append(zeile) # trim idlist and dicts for empty entries: actdict = {k: v for k, v in actdict.items() if v != 0} ids = list(actdict.keys()) # udict = {k: v for k, v in udict.items() if k in ids} cdict = {k: v for k, v in cdict.items() if k in ids} pdict = {k: v for k, v in pdict.items() if k in ids} rdict = {k: v for k, v in rdict.items() if k in ids} with open("edgelist_content.csv", "w", newline='', encoding="utf-8") as file: writer = csv.writer(file, delimiter=";") writer.writerow(["Source","Target"]) for i in range(len(content_edgelist)): writer.writerow(content_edgelist[i]) # G=nx.MultiGraph() G.add_edges_from(content_edgelist) for u,v,data in G.edges(data=True): w = data['weight'] = 1.0 G.edges(data=True) H = nx.Graph() for u,v,data in G.edges(data=True): w = data['weight'] if H.has_edge(u,v): H[u][v]['weight'] += w else: H.add_edge(u, v, weight=w) # H.edges(data=True) # H.is_directed() # nx.is_bipartite(H) F = bipartite.weighted_projected_graph(H, ids, ratio=False) nx.set_node_attributes(F, 'total_activities', actdict) nx.set_node_attributes(F, 'comments', cdict) nx.set_node_attributes(F, 'posts', pdict) nx.set_node_attributes(F, 'reactions', rdict) elist = list(F.edges()) for i in elist: F[i[0]][i[1]]['sfrac'] = F[i[0]][i[1]]['weight'] / idict.get(i[0]) F[i[0]][i[1]]['tfrac'] = F[i[0]][i[1]]['weight'] / idict.get(i[1]) if F[i[0]][i[1]]['sfrac'] < F[i[0]][i[1]]['tfrac']: F[i[0]][i[1]]['maxfrac'] = F[i[0]][i[1]]['sfrac'] else: F[i[0]][i[1]]['maxfrac'] = F[i[0]][i[1]]['tfrac'] pagenames = [] for i in ids: a = getpageinfo(token,i) pagenames.append (a["name"]) mapping = dict(zip(ids, pagenames)) F=nx.relabel_nodes(F,mapping) nx.write_graphml(F, "content_projection_pages.graphml") nx.write_weighted_edgelist(F, 'content_projection_edgelist.csv', delimiter=";", encoding="utf-8") L = bipartite.weighted_projected_graph(H, uniqueurls, ratio=False) nx.write_graphml(L, "content_projection_content.graphml") nx.write_weighted_edgelist(F, 'content_projection_content_edgelist.csv', delimiter=";", encoding="utf-8") print("Done with the content overlap - You'll find a weighted edgelist in csv-format and a graphml-file in your working directory.") print("Do you want to collect the network of page-likes as well?") print("Note: This takes a while is not possible in retrospect. It will always collect the status quo.") print("So if you have already done it, for your set of pages, we recommend to skip.") print("Please provide a choice: [c]ollect page-like data or [s]kip:"), prompt = '>' skp = set(['skip','s']) cllct = set(['collect','c']) cors = input(prompt).lower() if cors in skp: pass if cors in cllct: print ("Okay, let us collect the network of page-likes") getlikenetwork (ids, token)
def low_stretch_tree(graph, x=None, y=None): # set up tree lst = nx.Graph() lst.add_nodes_from(graph.nodes()) # assign parameter values n = graph.number_of_nodes() if x == None: x = exp(sqrt(log(n, 2) * log(log(n, 2), 2))) if y == None: rho = 1 if log(x) == 0 else ceil(3 * log(n) / log(x)) mu = 9 * rho * log(n) y = x * mu # divide edges into weight classes WI = {} # get edges and weights all_edges = graph.edges(data=True) all_weights = nx.get_edge_attributes(graph, "weight") # find max i value needed to cover all weights max_weight = max(all_weights.itervalues()) max_i = get_index_for_weight(max_weight, y, WI) # initialize E with empty lists E = {i: [] for i in xrange(0, max_i + 1)} # assign edges to E for (u, v, data) in all_edges: w = data["weight"] i = get_index_for_weight(w, y, WI) E[i].append((u, v)) #### perform iterative rounds #### j = 1 # convert to multigraph G = nx.MultiGraph(graph) Efull = [e for i in E.values() for e in i] while len(Efull) > 0: #pdb.set_trace() # get partition of vertices copy = nx.MultiGraph() #(G) copy.add_nodes_from(G.nodes()) copy.add_edges_from(G.edges(data=True)) partition = cluster(copy, E=E, x=x, y=y, j=j, WI=WI) # construct multigraph where each cluster is a vertex # and each intercluster edge is represented new_G = nx.MultiGraph() # add vertices for c in partition: c_i = partition.index(c) # vertices from our original graph which have been # "collapsed" into this cluster ov = [] for v in c: if 'orig_verts' in G.node[v]: ov.extend(G.node[v]['orig_verts']) else: ov.append(v) new_G.add_node(c_i, orig_verts=ov) # find a spanning tree for each cluster for c in partition: c_i = partition.index(c) # get induced subgraph for cluster sub = G.subgraph(c) # get shortest-paths spanning tree spanner = utils.shortest_paths_spanner(sub) # add the edges from the spanning tree into low-stretch tree for (u, v, data) in spanner.edges(data=True): if 'orig_edge' in data: (orig_u, orig_v) = data['orig_edge'] else: (orig_u, orig_v) = (u, v) lst.add_edge(orig_u, orig_v, attr_dict=data) # get all edges from this cluster c_edges = G.edges(c, data=True) # find and add intercluster edges for i in xrange(c_i + 1, len(partition)): c2 = partition[i] inter_edges = [(u, v, data) for (u, v, data) in c_edges if u in c2 or v in c2] for (u, v, data) in inter_edges: if 'orig_edge' in data: oe = data['orig_edge'] else: oe = (u, v) new_G.add_edge(c_i, i, weight=data['weight'], orig_edge=oe) # find and remove intracluster edges from E cset = set(c) intra_edges = set() #[] for (u, v, data) in c_edges: if u in cset and v in cset: if 'orig_edge' in data: intra_edges.add( data['orig_edge'] ) #intra_edges.append(data['orig_edge']) else: intra_edges.add((u, v)) # intra_edges.append((u,v)) for i in E: E[i] = [ (u, v) for (u, v) in E[i] if (u, v) not in intra_edges and (v, u) not in intra_edges ] # update E Efull = [e for i in E.values() for e in i] G = new_G j += 1 return lst
def bipartite_random_regular_graph(d, n, create_using=None, seed=None): """UNTESTED: Generate a random bipartite graph. Parameters ---------- d : integer Degree of graph. n : integer Number of nodes in graph. create_using : NetworkX graph instance, optional Return graph of this type. seed : integer, optional Seed for random number generator. Notes ------ Nodes are numbered 0...n-1. Restrictions on n and d: - n must be even - n>=2*d Algorithm inspired by random_regular_graph() """ # This algorithm could be improved - see random_regular_graph() # helper subroutine to check for suitable edges def suitable(leftstubs, rightstubs): for s in leftstubs: for t in rightstubs: if not t in seen_edges[s]: return True # else no suitable possible edges return False if not n * d % 2 == 0: print "n*d must be even" return False if not n % 2 == 0: print "n must be even" return False if not n >= 2 * d: print "n must be >= 2*d" return False if create_using is None: create_using = networkx.MultiGraph() elif create_using.is_directed(): raise networkx.NetworkXError(\ "Directed Graph not supported") if not seed is None: random.seed(seed) G = networkx.empty_graph(0, create_using) nodes = range(0, n) G.add_nodes_from(nodes) seen_edges = {} [seen_edges.setdefault(v, {}) for v in nodes] vv = [[v] * d for v in nodes] # List of degree-repeated vertex numbers stubs = reduce(lambda x, y: x + y, vv) # flatten the list of lists to a list leftstubs = stubs[:(n * d / 2)] rightstubs = stubs[n * d / 2:] while leftstubs: source = random.choice(leftstubs) target = random.choice(rightstubs) if source != target and not target in seen_edges[source]: leftstubs.remove(source) rightstubs.remove(target) seen_edges[source][target] = 1 seen_edges[target][source] = 1 G.add_edge(source, target) else: # further check to see if suitable if suitable(leftstubs, rightstubs) == False: return False return G
def node_link_graph(data, directed=False, multigraph=True, attrs=None): """Return graph from node-link data format. Parameters ---------- data : dict node-link formatted graph data directed : bool If True, and direction not specified in data, return a directed graph. multigraph : bool If True, and multigraph not specified in data, return a multigraph. attrs : dict A dictionary that contains five keys 'source', 'target', 'name', 'key' and 'link'. The corresponding values provide the attribute names for storing NetworkX-internal graph data. Default value: dict(source='source', target='target', name='id', key='key', link='links') Returns ------- G : NetworkX graph A NetworkX graph object Examples -------- >>> from networkx.readwrite import json_graph >>> G = nx.Graph([('A', 'B')]) >>> data = json_graph.node_link_data(G) >>> H = json_graph.node_link_graph(data) Notes ----- Attribute 'key' is only used for multigraphs. See Also -------- node_link_data, adjacency_data, tree_data """ # Allow 'attrs' to keep default values. if attrs is None: attrs = _attrs else: attrs.update({k: v for k, v in _attrs.items() if k not in attrs}) multigraph = data.get('multigraph', multigraph) directed = data.get('directed', directed) if multigraph: graph = nx.MultiGraph() else: graph = nx.Graph() if directed: graph = graph.to_directed() name = attrs['name'] source = attrs['source'] target = attrs['target'] links = attrs['link'] # Allow 'key' to be omitted from attrs if the graph is not a multigraph. key = None if not multigraph else attrs['key'] graph.graph = data.get('graph', {}) c = count() for d in data['nodes']: node = to_tuple(d.get(name, next(c))) nodedata = dict((make_str(k), v) for k, v in d.items() if k != name) graph.add_node(node, **nodedata) for d in data[links]: src = tuple(d[source]) if isinstance(d[source], list) else d[source] tgt = tuple(d[target]) if isinstance(d[target], list) else d[target] if not multigraph: edgedata = dict((make_str(k), v) for k, v in d.items() if k != source and k != target) graph.add_edge(src, tgt, **edgedata) else: ky = d.get(key, None) edgedata = dict((make_str(k), v) for k, v in d.items() if k != source and k != target and k != key) graph.add_edge(src, tgt, ky, **edgedata) return graph
def bipartite_havel_hakimi_graph(aseq, bseq, create_using=None): """Return a bipartite graph from two given degree sequences using a Havel-Hakimi style construction. Parameters ---------- aseq : list or iterator Degree sequence for node set A. bseq : list or iterator Degree sequence for node set B. create_using : NetworkX graph instance, optional Return graph of this type. Nodes from the set A are connected to nodes in the set B by connecting the highest degree nodes in set A to the highest degree nodes in set B until all stubs are connected. Notes ----- The sum of the two sequences must be equal: sum(aseq)=sum(bseq) If no graph type is specified use MultiGraph with parallel edges. If you want a graph with no parallel edges use create_using=Graph() but then the resulting degree sequences might not be exact. """ if create_using is None: create_using = networkx.MultiGraph() elif create_using.is_directed(): raise networkx.NetworkXError(\ "Directed Graph not supported") G = networkx.empty_graph(0, create_using) # length of the each sequence naseq = len(aseq) nbseq = len(bseq) suma = sum(aseq) sumb = sum(bseq) if not suma == sumb: raise networkx.NetworkXError(\ 'invalid degree sequences, sum(aseq)!=sum(bseq),%s,%s'\ %(suma,sumb)) G.add_nodes_from(range(0, naseq)) # one vertex type (a) G.add_nodes_from(range(naseq, naseq + nbseq)) # the other type (b) if max(aseq) == 0: return G # done if no edges # build list of degree-repeated vertex numbers astubs = [[aseq[v], v] for v in range(0, naseq)] bstubs = [[bseq[v - naseq], v] for v in range(naseq, naseq + nbseq)] astubs.sort() while astubs: (degree, u) = astubs.pop() # take of largest degree node in the a set if degree == 0: break # done, all are zero # connect the source to largest degree nodes in the b set bstubs.sort() for target in bstubs[-degree:]: v = target[1] G.add_edge(u, v) target[0] -= 1 # note this updates bstubs too. if target[0] == 0: bstubs.remove(target) G.name = "bipartite_havel_hakimi_graph" return G
def runRound(edges, start, end, cost, tax, biases, N, debug = False): # For each edge there is flow * c(flow). These are the edgeFuncs. The global # optimizer minimizes the sum of these functions initial =True preferences = {} edgeResults = {} # Add ids to every edge so that biases can be indexed for i, (n1, n2, edgeData) in enumerate(edges): edgeData['id'] = i G = networkx.MultiGraph() G.add_edges_from(edges) for i in range(N): for n1 in G.edge: for n2 in G.edge[n1]: for en in G.edge[n1][n2]: preferences[(i, n1, n2, en)] = biases[G.edge[n1][n2][en]['id']](i) #zero the graph edges to start for n1 in G.edge: for n2 in G.edge[n1]: for en in G.edge[n1][n2]: G.edge[n1][n2][en]['f'] = 0.0 # we need to preserve the balance of edges at the end of the round. becuas I should change my mind just because the flow changed... # If I change my mind, remove myself from the previous # for r in range(R): aCur = {} # create aPrev = None ct = 0 history = [] backtrack = False totalc = 0.0 edgeResults = {} maxIters = 10 while ((initial or aCur != aPrev) and ct < maxIters): ct += 1 if aCur in history: backtrack=True history.append(dict(aCur)) aPrev = dict(aCur) order = range(N) numpy.random.shuffle(order) for i in order: if i in aPrev: for n1, n2, betterEdgeIdx in aCur[i]: G.edge[n1][n2][betterEdgeIdx]['f'] -= 1.0 / N for n1 in G.edge: for n2 in G.edge[n1]: for en in G.edge[n1][n2]: G.edge[n1][n2][en]['c'] = cost[G.edge[n1][n2][en]['t']](G.edge[n1][n2][en]['f']) + \ tax[G.edge[n1][n2][en]['t']](G.edge[n1][n2][en]['f']) + \ preferences[(i, n1, n2, en)] paths = networkx.all_simple_path(G, source = start, target = end) pathCosts = [] for path in paths: c = 0 edges = zip(path[:-1], path[1:]) for n0, n1 in zip pEdge=list(zip(path[:-1], path[1:])) pEdge.sort() fullEdges = [] for n1, n2 in pEdge: #loop over the path increasing flow # It's possible there are two paths from one node to another, we must choose the better one betterEdgeIdx, betterEdgeData = sorted(G.edge[n1][n2].items(), key = lambda x : x[1]['c'])[0] fullEdges.append((n1, n2, betterEdgeIdx)) aCur[i] = fullEdges for n1, n2, betterEdgeIdx in aCur[i]: G.edge[n1][n2][betterEdgeIdx]['f'] += 1.0 / N totalc = 0.0 edgeResults = {} for n1, n2 in set(G.edges()): for edgeIdx, edgeData in G.edge[n1][n2].items(): key = (n1, n2, edgeIdx) edgeResults[key] = edgeData['f'], edgeData['t'] totalc += edgeData['f'] * cost[edgeData['t']](edgeData['f']) if debug: for (n1, n2, t), (f, t) in edgeResults.items(): print u"Edge ({0}, {1}), type {2}, flow {3}".format(n1, n2, t, f) print '----' print u"Total cost: {0}".format(numpy.mean(totalc)) print '****' initial = False if debug: print 'Total iterations:', ct if debug: if backtrack: print "Game is not potential game" else: print "No backtracking detected" return totalc, edgeResults, backtrack, (ct < maxIters)
def setup_environment_subgraph(self, environments_symbols, only_atoms=None): """ Set up the graph for predefined environments and optionally atoms. Args: environments_symbols: Symbols of the environments for the environment subgraph. only_atoms: Atoms to be considered. """ logging.info(f"Setup of environment subgraph for environments {', '.join(environments_symbols)}") if not isinstance(environments_symbols, collections.abc.Iterable): environments_symbols = [environments_symbols] environments_symbols = sorted(environments_symbols) envs_string = "-".join(environments_symbols) if only_atoms is not None: envs_string += "#" + "-".join(sorted(only_atoms)) # Get it directly if it was already computed if envs_string in self.environment_subgraphs: self._environment_subgraph = self.environment_subgraphs[envs_string] return # Initialize graph for a subset of environments self._environment_subgraph = nx.MultiGraph() # Add the sites with the required environment(s) for isite, ce_this_site_all in enumerate(self.light_structure_environments.coordination_environments): if ce_this_site_all is None: continue if len(ce_this_site_all) == 0: continue ce_this_site = ce_this_site_all[0]["ce_symbol"] if ce_this_site in environments_symbols: if only_atoms is None: env_node = get_environment_node( self.light_structure_environments.structure[isite], isite, ce_this_site, ) self._environment_subgraph.add_node(env_node) else: if self.light_structure_environments.structure.is_ordered: if self.light_structure_environments.structure[isite].specie.symbol in only_atoms: env_node = get_environment_node( self.light_structure_environments.structure[isite], isite, ce_this_site, ) self._environment_subgraph.add_node(env_node) else: # TODO: add the possibility of a "constraint" on the minimum percentage # of the atoms on the site this_site_elements = [ sp.symbol for sp in self.light_structure_environments.structure[isite].species_and_occu ] for elem_symbol in this_site_elements: if elem_symbol in only_atoms: env_node = get_environment_node( self.light_structure_environments.structure[isite], isite, ce_this_site, ) self._environment_subgraph.add_node(env_node) break # Find the connections between the environments nodes = list(self._environment_subgraph.nodes()) for inode1, node1 in enumerate(nodes): isite1 = node1.isite links_node1 = self._graph.edges(isite1, data=True) for inode2, node2 in enumerate(nodes[inode1:]): isite2 = node2.isite links_node2 = self._graph.edges(isite2, data=True) # We look for ligands that are common to both site1 and site2 connections_site1_site2 = {} for (site1_1, ilig_site1, d1) in links_node1: for (site2_1, ilig_site2, d2) in links_node2: if ilig_site1 == ilig_site2: delta_image = get_delta_image(isite1, isite2, d1, d2) if isite1 == isite2 and np.all(delta_image == 0): continue tuple_delta_image = tuple(delta_image) if tuple_delta_image in connections_site1_site2: connections_site1_site2[tuple_delta_image].append((ilig_site1, d1, d2)) else: connections_site1_site2[tuple_delta_image] = [(ilig_site1, d1, d2)] # Remove the double self-loops ... if isite1 == isite2: remove_deltas = [] alldeltas = list(connections_site1_site2.keys()) alldeltas2 = list(connections_site1_site2.keys()) if (0, 0, 0) in alldeltas: alldeltas.remove((0, 0, 0)) alldeltas2.remove((0, 0, 0)) for current_delta in alldeltas: opp_current_delta = tuple(-dd for dd in current_delta) if opp_current_delta in alldeltas2: remove_deltas.append(current_delta) alldeltas2.remove(current_delta) alldeltas2.remove(opp_current_delta) for remove_delta in remove_deltas: connections_site1_site2.pop(remove_delta) # Add all the edges for conn, ligands in list(connections_site1_site2.items()): self._environment_subgraph.add_edge( node1, node2, start=node1.isite, end=node2.isite, delta=conn, ligands=ligands, ) self.environment_subgraphs[envs_string] = self._environment_subgraph
raw_file_list = os.listdir(datadir) #raw_file_list = ["hou48kh.ord"] timestamps = sorted([ congress_no_from_filename(f) for f in raw_file_list if f.endswith(".ord") ]) print "timestamps:", timestamps for fname in sorted(raw_file_list, key=congress_no_from_filename): print "filename :", fname congress = congress_no_from_filename(fname) print "congress :", congress g1 = nx.Graph(name="g1") mg1 = nx.MultiGraph(name="mg1") senators = [] prev_state = "" with open(os.path.join(datadir, fname)) as f: for line in f: if not line: continue print "---------------------------------------" print "line: ", line # split into fields, wher each field is a numeric group fields = re.findall(r'\d+', line) print "fields: ", fields alphafields = re.findall(r"[A-Z., '-]+", line) print "alphafields: ", alphafields # Special case to deal with name BURDICK2 in congress 104
def create_nxgraph(net, respect_switches=True, include_lines=True, include_impedances=True, include_dclines=True, include_trafos=True, include_trafo3ws=True, nogobuses=None, notravbuses=None, multi=True, calc_branch_impedances=False, branch_impedance_unit="ohm", library="networkx", include_out_of_service=False): """ Converts a pandapower network into a NetworkX graph, which is a is a simplified representation of a network's topology, reduced to nodes and edges. Busses are being represented by nodes (Note: only buses with in_service = 1 appear in the graph), edges represent physical connections between buses (typically lines or trafos). INPUT: **net** (pandapowerNet) - variable that contains a pandapower network OPTIONAL: **respect_switches** (boolean, True) - True: open switches (line, trafo, bus) are being \ considered (no edge between nodes) False: open switches are being ignored **include_lines** (boolean or index, True) - determines, whether or which lines get converted to edges **include_impedances** (boolean or , True) - determines, whether or which per unit impedances (net.impedance) are converted to edges **include_dclines** (boolean or index, True) - determines, whether or which dclines get converted to edges **include_trafos** (boolean or index, True) - determines, whether or which trafos get converted to edges **include_trafo3ws** (boolean or index, True) - determines, whether or which trafo3ws get converted to edges **nogobuses** (integer/list, None) - nogobuses are not being considered in the graph **notravbuses** (integer/list, None) - lines connected to these buses are not being considered in the graph **multi** (boolean, True) - True: The function generates a NetworkX MultiGraph, which allows multiple parallel edges between nodes False: NetworkX Graph (no multiple parallel edges) **calc_branch_impedances** (boolean, False) - determines wether impedances are calculated and added as a weight to all branches or not. Impedances can be added in ohm or per unit (see branch_impedance unit parameter). DC Lines are considered as infinity. **branch_impedance_unit** (str, "ohm") - defines the unit of the branch impedance for calc_branch_impedances=True. If it is set to "ohm", the parameters 'r_ohm', 'x_ohm' and 'z_ohm' are added to each branch. If it is set to "pu", the parameters are 'r_pu', 'x_pu' and 'z_pu'. **include_out_of_service** (bool, False) - defines if out of service buses are included in the nx graph OUTPUT: **mg** - Returns the required NetworkX graph EXAMPLE: import pandapower.topology as top mg = top.create_nx_graph(net, respect_switches = False) # converts the pandapower network "net" to a MultiGraph. Open switches will be ignored. """ if multi: if graph_tool_available and library == "graph_tool": mg = GraphToolInterface(net.bus.index) else: mg = nx.MultiGraph() else: mg = nx.Graph() if branch_impedance_unit not in ["ohm", "pu"]: raise ValueError("branch impedance unit can be either 'ohm' or 'pu'") if respect_switches: open_sw = ~net.switch.closed.values.astype(bool) if calc_branch_impedances: ppc = get_nx_ppc(net) line = get_edge_table(net, "line", include_lines) if line is not None: indices, parameter, in_service = init_par(line, calc_branch_impedances) indices[:, F_BUS] = line.from_bus.values indices[:, T_BUS] = line.to_bus.values if respect_switches: mask = (net.switch.et.values == "l") & open_sw if mask.any(): open_lines = net.switch.element.values[mask] open_lines_mask = np.in1d(indices[:, INDEX], open_lines) in_service &= ~open_lines_mask parameter[:, WEIGHT] = line.length_km.values if calc_branch_impedances: baseR = get_baseR(net, ppc, line.from_bus.values) \ if branch_impedance_unit == "pu" else 1 line_length = line.length_km.values / line.parallel.values r = line.r_ohm_per_km.values * line_length x = line.x_ohm_per_km.values * line_length parameter[:, BR_R] = r / baseR parameter[:, BR_X] = x / baseR add_edges(mg, indices, parameter, in_service, net, "line", calc_branch_impedances, branch_impedance_unit) impedance = get_edge_table(net, "impedance", include_impedances) if impedance is not None: indices, parameter, in_service = init_par(impedance, calc_branch_impedances) indices[:, F_BUS] = impedance.from_bus.values indices[:, T_BUS] = impedance.to_bus.values if calc_branch_impedances: baseR = get_baseR(net, ppc, impedance.from_bus.values) \ if branch_impedance_unit == "ohm" else 1 r, x, _, _ = _calc_impedance_parameters_from_dataframe(net) parameter[:, BR_R] = r * baseR parameter[:, BR_X] = x * baseR add_edges(mg, indices, parameter, in_service, net, "impedance", calc_branch_impedances, branch_impedance_unit) dclines = get_edge_table(net, "dcline", include_dclines) if dclines is not None: indices, parameter, in_service = init_par(dclines, calc_branch_impedances) indices[:, F_BUS] = dclines.from_bus.values indices[:, T_BUS] = dclines.to_bus.values if calc_branch_impedances: parameter[:, BR_R] = np.inf parameter[:, BR_X] = np.inf add_edges(mg, indices, parameter, in_service, net, "dcline", calc_branch_impedances, branch_impedance_unit) trafo = get_edge_table(net, "trafo", include_trafos) if trafo is not None: indices, parameter, in_service = init_par(trafo, calc_branch_impedances) indices[:, F_BUS] = trafo.hv_bus.values indices[:, T_BUS] = trafo.lv_bus.values if respect_switches: mask = (net.switch.et.values == "t") & open_sw if mask.any(): open_trafos = net.switch.element.values[mask] open_trafos_mask = np.in1d(indices[:, INDEX], open_trafos) in_service &= ~open_trafos_mask if calc_branch_impedances: baseR = get_baseR(net, ppc, trafo.hv_bus.values) \ if branch_impedance_unit == "ohm" else 1 r, x, _, _, _ = _calc_branch_values_from_trafo_df(net, ppc, trafo) parameter[:, BR_R] = r * baseR parameter[:, BR_X] = x * baseR add_edges(mg, indices, parameter, in_service, net, "trafo", calc_branch_impedances, branch_impedance_unit) trafo3w = get_edge_table(net, "trafo3w", include_trafo3ws) if trafo3w is not None: sides = ["hv", "mv", "lv"] if calc_branch_impedances: trafo_df = _trafo_df_from_trafo3w(net) r_all, x_all, _, _, _ = _calc_branch_values_from_trafo_df( net, ppc, trafo_df) baseR = get_baseR(net, ppc, trafo3w.hv_bus.values) \ if branch_impedance_unit == "ohm" else 1 r = {side: r for side, r in zip(sides, np.split(r_all, 3))} x = {side: x for side, x in zip(sides, np.split(x_all, 3))} if respect_switches: # for trafo3ws the bus where the open switch is located also matters. Open switches # are therefore defined by the tuple (idx, b) where idx is the trafo3w index and b # is the bus. To make searching for the open 3w trafos a 1d problem, open 3w switches # are represented with imaginary numbers as idx + b*1j mask = (net.switch.et.values == "t3") & open_sw open_trafo3w_index = net.switch.element.values[mask] open_trafo3w_buses = net.switch.bus.values[mask] open_trafo3w = (open_trafo3w_index + open_trafo3w_buses * 1j).flatten() for f, t in combinations(sides, 2): indices, parameter, in_service = init_par(trafo3w, calc_branch_impedances) indices[:, F_BUS] = trafo3w["%s_bus" % f].values indices[:, T_BUS] = trafo3w["%s_bus" % t].values if respect_switches and len(open_trafo3w): for BUS in [F_BUS, T_BUS]: open_switch = np.in1d( indices[:, INDEX] + indices[:, BUS] * 1j, open_trafo3w) in_service &= ~open_switch if calc_branch_impedances: parameter[:, BR_R] = (r[f] + r[t]) * baseR parameter[:, BR_X] = (x[f] + x[t]) * baseR add_edges(mg, indices, parameter, in_service, net, "trafo3w", calc_branch_impedances, branch_impedance_unit) switch = net.switch if len(switch): if respect_switches: # add edges for closed bus-bus switches in_service = (switch.et.values == "b") & ~open_sw else: # add edges for any bus-bus switches in_service = (switch.et.values == "b") indices, parameter = init_par(switch, calc_branch_impedances) indices[:, F_BUS] = switch.bus.values indices[:, T_BUS] = switch.element.values add_edges(mg, indices, parameter, in_service, net, "switch", calc_branch_impedances, branch_impedance_unit) # add all buses that were not added when creating branches if len(mg.nodes()) < len(net.bus.index): if graph_tool_available and isinstance(mg, GraphToolInterface): mg.add_vertex(max(net.bus.index) + 1) else: for b in set(net.bus.index) - set(mg.nodes()): mg.add_node(b) # remove nogobuses if nogobuses is not None: for b in nogobuses: mg.remove_node(b) # remove the edges pointing away of notravbuses if notravbuses is not None: for b in notravbuses: for i in list(mg[b].keys()): try: del mg[b][i] # networkx versions < 2.0 except: del mg._adj[b][i] # networkx versions 2.0 # remove out of service buses if not include_out_of_service: for b in net.bus.index[~net.bus.in_service.values]: mg.remove_node(b) return mg
def multi_edge(): """Returns anm with input and physical as house graph""" from networkx.readwrite import json_graph import networkx as nx import autonetkit # returns a house graph data = {'directed': False, 'graph': [], 'links': [{'_ports': {'r4': 2, 'r5': 1}, 'raw_interfaces': {}, 'source': 0, 'target': 1}, {'_ports': {'r2': 3, 'r4': 1}, 'raw_interfaces': {}, 'source': 0, 'target': 3}, {'_ports': {'r2': 4, 'r4': 3}, 'raw_interfaces': {}, 'source': 0, 'target': 3}, {'_ports': {'r3': 3, 'r5': 2}, 'raw_interfaces': {}, 'source': 1, 'target': 4}, {'_ports': {'r1': 1, 'r2': 1}, 'raw_interfaces': {}, 'source': 2, 'target': 3}, {'_ports': {'r1': 3, 'r2': 5}, 'raw_interfaces': {}, 'source': 2, 'target': 3}, {'_ports': {'r1': 2, 'r3': 1}, 'raw_interfaces': {}, 'source': 2, 'target': 4}, {'_ports': {'r1': 4, 'r3': 4}, 'raw_interfaces': {}, 'source': 2, 'target': 4}, {'_ports': {'r1': 5, 'r3': 5}, 'raw_interfaces': {}, 'source': 2, 'target': 4}, {'_ports': {'r2': 2, 'r3': 2}, 'raw_interfaces': {}, 'source': 3, 'target': 4}], 'multigraph': True, 'nodes': [{'_ports': {0: {'category': 'physical', 'description': None}, 1: {'category': 'physical', 'description': 'r4 to r2', 'id': 'eth0'}, 2: {'category': 'physical', 'description': 'r4 to r5', 'id': 'eth1'}, 3: {'category': 'physical', 'description': 'r4 to r2', 'id': 'eth2'}}, 'asn': 2, 'device_type': 'router', 'id': 'r4', 'label': 'r4', 'x': 675, 'y': 300}, {'_ports': {0: {'category': 'physical', 'description': None}, 1: {'category': 'physical', 'description': 'r5 to r4', 'id': 'eth0'}, 2: {'category': 'physical', 'description': 'r5 to r3', 'id': 'eth1'}}, 'asn': 2, 'device_type': 'router', 'id': 'r5', 'label': 'r5', 'x': 675, 'y': 500}, {'_ports': {0: {'category': 'physical', 'description': None}, 1: {'category': 'physical', 'description': 'r1 to r2', 'id': 'eth0'}, 2: {'category': 'physical', 'description': 'r1 to r3', 'id': 'eth1'}, 3: {'category': 'physical', 'description': 'r1 to r2', 'id': 'eth2'}, 4: {'category': 'physical', 'description': 'r1 to r3', 'id': 'eth3'}, 5: {'category': 'physical', 'description': 'r1 to r3', 'id': 'eth4'}}, 'asn': 1, 'device_type': 'router', 'id': 'r1', 'label': 'r1', 'x': 350, 'y': 400}, {'_ports': {0: {'category': 'physical', 'description': None}, 1: {'category': 'physical', 'description': 'r2 to r1', 'id': 'eth0'}, 2: {'category': 'physical', 'description': 'r2 to r3', 'id': 'eth1'}, 3: {'category': 'physical', 'description': 'r2 to r4', 'id': 'eth2'}, 4: {'category': 'physical', 'description': 'r2 to r4', 'id': 'eth3'}, 5: {'category': 'physical', 'description': 'r2 to r1', 'id': 'eth4'}}, 'asn': 1, 'device_type': 'router', 'id': 'r2', 'label': 'r2', 'x': 500, 'y': 300}, {'_ports': {0: {'category': 'physical', 'description': None}, 1: {'category': 'physical', 'description': 'r3 to r1', 'id': 'eth0'}, 2: {'category': 'physical', 'description': 'r3 to r2', 'id': 'eth1'}, 3: {'category': 'physical', 'description': 'r3 to r5', 'id': 'eth2'}, 4: {'category': 'physical', 'description': 'r3 to r1', 'id': 'eth3'}, 5: {'category': 'physical', 'description': 'r3 to r1', 'id': 'eth4'}}, 'asn': 1, 'device_type': 'router', 'id': 'r3', 'label': 'r3', 'x': 500, 'y': 500}]} graph = json_graph.node_link_graph(data) anm = autonetkit.anm.NetworkModel() g_in = anm.add_overlay("input") g_in._replace_graph(nx.MultiGraph(graph)) # TODO: check if should build overlays here rather than clone in? g_phy = anm["phy"] g_phy._replace_graph(graph) return anm
def parse_pajek(lines): """Parse Pajek format graph from string or iterable. Parameters ---------- lines : string or iterable Data in Pajek format. Returns ------- G : NetworkX graph See Also -------- read_pajek() """ import shlex # multigraph=False if is_string_like(lines): lines = iter(lines.split('\n')) lines = iter([line.rstrip('\n') for line in lines]) G = nx.MultiDiGraph() # are multiedges allowed in Pajek? assume yes labels = [] # in the order of the file, needed for matrix while lines: try: l = next(lines) except: # EOF break if l.lower().startswith("*network"): try: label, name = l.split(None, 1) except ValueError: # Line was not of the form: *network NAME pass else: G.graph['name'] = name elif l.lower().startswith("*vertices"): nodelabels = {} l, nnodes = l.split() for i in range(int(nnodes)): l = next(lines) try: splitline = [ x.decode('utf-8') for x in shlex.split(make_str(l).encode('utf-8')) ] except AttributeError: splitline = shlex.split(str(l)) id, label = splitline[0:2] labels.append(label) G.add_node(label) nodelabels[id] = label G.nodes[label]['id'] = id try: x, y, shape = splitline[2:5] G.nodes[label].update({ 'x': float(x), 'y': float(y), 'shape': shape }) except: pass extra_attr = zip(splitline[5::2], splitline[6::2]) G.nodes[label].update(extra_attr) elif l.lower().startswith("*edges") or l.lower().startswith("*arcs"): if l.lower().startswith("*edge"): # switch from multidigraph to multigraph G = nx.MultiGraph(G) if l.lower().startswith("*arcs"): # switch to directed with multiple arcs for each existing edge G = G.to_directed() for l in lines: try: splitline = [ x.decode('utf-8') for x in shlex.split(make_str(l).encode('utf-8')) ] except AttributeError: splitline = shlex.split(str(l)) if len(splitline) < 2: continue ui, vi = splitline[0:2] u = nodelabels.get(ui, ui) v = nodelabels.get(vi, vi) # parse the data attached to this edge and put in a dictionary edge_data = {} try: # there should always be a single value on the edge? w = splitline[2:3] edge_data.update({'weight': float(w[0])}) except: pass # if there isn't, just assign a 1 # edge_data.update({'value':1}) extra_attr = zip(splitline[3::2], splitline[4::2]) edge_data.update(extra_attr) # if G.has_edge(u,v): # multigraph=True G.add_edge(u, v, **edge_data) elif l.lower().startswith("*matrix"): G = nx.DiGraph(G) adj_list = ((labels[row], labels[col], { 'weight': int(data) }) for (row, line) in enumerate(lines) for (col, data) in enumerate(line.split()) if int(data) != 0) G.add_edges_from(adj_list) return G
counts = index.value_counts() counts['2'] mylist = ['a', '1', '2', '2', '4', np.nan] 'a' in mylist roots = [['d', 'c', 'e'], ['c', 'd'], ['d', 'c'], ['d', 'e'], ['a', 'b'], ['b', 'a', 'f'], ['b', 'f', 'a'], ['a', 'c']] nodes = list(set(list(itertools.chain.from_iterable(roots)))) + ['h'] edges = list( itertools.chain.from_iterable( [[list(set(list(x))) for x in list(itertools.combinations(sets, 2))] for sets in roots])) G = nx.MultiGraph() G.add_nodes_from(nodes) G.add_edges_from(edges) plt.title('draw_networkx') pos = graphviz_layout(G, prog='dot') nx.draw(G, pos, with_labels=True, arrows=True) for i in G.nodes: print(i, G.edges(i)) pos = nx.kamada_kawai_layout(G) nx.draw_networkx_nodes(G, pos, node_color='r', node_size=100, alpha=1) ax = plt.gca() for e in G.edges: ax.annotate(
def test_multigraph(self): e = networkx.katz_centrality(networkx.MultiGraph(), 0.1)
def bipartite_configuration_model(aseq, bseq, create_using=None, seed=None): """Return a random bipartite graph from two given degree sequences. Parameters ---------- aseq : list or iterator Degree sequence for node set A. bseq : list or iterator Degree sequence for node set B. create_using : NetworkX graph instance, optional Return graph of this type. seed : integer, optional Seed for random number generator. Nodes from the set A are connected to nodes in the set B by choosing randomly from the possible free stubs, one in A and one in B. Notes ----- The sum of the two sequences must be equal: sum(aseq)=sum(bseq) If no graph type is specified use MultiGraph with parallel edges. If you want a graph with no parallel edges use create_using=Graph() but then the resulting degree sequences might not be exact. """ if create_using is None: create_using = networkx.MultiGraph() elif create_using.is_directed(): raise networkx.NetworkXError(\ "Directed Graph not supported") G = networkx.empty_graph(0, create_using) if not seed is None: random.seed(seed) # length and sum of each sequence lena = len(aseq) lenb = len(bseq) suma = sum(aseq) sumb = sum(bseq) if not suma == sumb: raise networkx.NetworkXError(\ 'invalid degree sequences, sum(aseq)!=sum(bseq),%s,%s'\ %(suma,sumb)) G.add_nodes_from(range(0, lena + lenb)) if max(aseq) == 0: return G # done if no edges # build lists of degree-repeated vertex numbers stubs = [] stubs.extend([[v] * aseq[v] for v in range(0, lena)]) astubs = [] astubs = [x for subseq in stubs for x in subseq] stubs = [] stubs.extend([[v] * bseq[v - lena] for v in range(lena, lena + lenb)]) bstubs = [] bstubs = [x for subseq in stubs for x in subseq] # shuffle lists random.shuffle(astubs) random.shuffle(bstubs) G.add_edges_from([[astubs[i], bstubs[i]] for i in xrange(suma)]) G.name = "bipartite_configuration_model" return G
def __init__(self, exchanges: list): self.exchanges = exchanges self.graph = nx.MultiGraph()
def bipartite_preferential_attachment_graph(aseq, p, create_using=None, seed=None): """Create a bipartite graph with a preferential attachment model from a given single degree sequence. Parameters ---------- aseq : list or iterator Degree sequence for node set A. p : float Probability that a new bottom node is added. create_using : NetworkX graph instance, optional Return graph of this type. seed : integer, optional Seed for random number generator. Notes ----- @article{guillaume-2004-bipartite, author = {Jean-Loup Guillaume and Matthieu Latapy}, title = {Bipartite structure of all complex networks}, journal = {Inf. Process. Lett.}, volume = {90}, number = {5}, year = {2004}, issn = {0020-0190}, pages = {215--221}, doi = {http://dx.doi.org/10.1016/j.ipl.2004.03.007}, publisher = {Elsevier North-Holland, Inc.}, address = {Amsterdam, The Netherlands, The Netherlands}, } """ if create_using is None: create_using = networkx.MultiGraph() elif create_using.is_directed(): raise networkx.NetworkXError(\ "Directed Graph not supported") if p > 1: raise networkx.NetworkXError("probability %s > 1" % (p)) G = networkx.empty_graph(0, create_using) if not seed is None: random.seed(seed) naseq = len(aseq) G.add_nodes_from(range(0, naseq)) vv = [[v] * aseq[v] for v in range(0, naseq)] while vv: while vv[0]: source = vv[0][0] vv[0].remove(source) if random.random() < p or G.number_of_nodes() == naseq: target = G.number_of_nodes() G.add_edge(source, target) else: bb = [[b] * G.degree(b) for b in range(naseq, G.number_of_nodes())] # flatten the list of lists into a list. bbstubs = reduce(lambda x, y: x + y, bb) # choose preferentially a bottom node. target = random.choice(bbstubs) G.add_edge(source, target) vv.remove(vv[0]) G.name = "bipartite_preferential_attachment_model" return G
def test_serialization(self): lat = Lattice.hexagonal(a=2.0, c=2.5) en1 = EnvironmentNode(central_site=PeriodicSite('Si', coords=np.array( [0.0, 0.0, 0.0]), lattice=lat), i_central_site=3, ce_symbol='T:4') en2 = EnvironmentNode(central_site=PeriodicSite('Ag', coords=np.array( [0.0, 0.0, 0.5]), lattice=lat), i_central_site=5, ce_symbol='T:4') en3 = EnvironmentNode(central_site=PeriodicSite('Ag', coords=np.array( [0.0, 0.5, 0.5]), lattice=lat), i_central_site=8, ce_symbol='O:6') graph = nx.MultiGraph() graph.add_nodes_from([en1, en2, en3]) graph.add_edge(en1, en2, start=en1.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(2, (0, 0, 1), (0, 0, 1)), (1, (0, 0, 1), (0, 0, 1))]) graph.add_edge(en1, en3, start=en1.isite, end=en2.isite, delta=(0, 0, 0), ligands=[(10, (0, 0, 1), (0, 0, 1)), (11, (0, 0, 1), (0, 0, 1))]) cc = ConnectedComponent(graph=graph) ref_sorted_edges = [[en1, en2], [en1, en3]] sorted_edges = sorted([sorted(e) for e in cc.graph.edges()]) assert sorted_edges == ref_sorted_edges ccfromdict = ConnectedComponent.from_dict(cc.as_dict()) ccfromjson = ConnectedComponent.from_dict( json.loads(json.dumps(cc.as_dict()))) loaded_cc_list = [ccfromdict, ccfromjson] if bson is not None: bson_data = bson.BSON.encode(cc.as_dict()) ccfrombson = ConnectedComponent.from_dict(bson_data.decode()) loaded_cc_list.append(ccfrombson) for loaded_cc in loaded_cc_list: assert loaded_cc.graph.number_of_nodes() == 3 assert loaded_cc.graph.number_of_edges() == 2 assert set(list(cc.graph.nodes())) == set( list(loaded_cc.graph.nodes())) assert sorted_edges == sorted( [sorted(e) for e in loaded_cc.graph.edges()]) for ii, e in enumerate(sorted_edges): assert cc.graph[e[0]][e[1]] == loaded_cc.graph[e[0]][e[1]] for node in loaded_cc.graph.nodes(): assert isinstance(node.central_site, PeriodicSite)
# Graph size len(T.nodes()) # First edge T.edges(data=True)[0] # Plot network nx.draw(T) plt.show() # Queries on graphs - extracting nodes and edges of interest noi = [n for n, d in T.nodes(data=True) if d['occupation'] == 'scientist'] eoi = [(u, v) for u, v, d in T.edges(data=True) if d['date'] < date(2010, 1, 1)] # Types of grahps undirected = nx.Graph() directed = nx.DiGraph() multiedge = nx.MultiGraph() multiedge_directed = nx.MultiDiGraph() # Specifying a weight on edges # Weights can be added to edges in a graph, typically indicating the "strength" of an edge. # In NetworkX, the weight is indicated by the 'weight' key in the metadata dictionary. T.edge[1][10] # Set the 'weight' attribute of the edge between node 1 and 10 of T to be equal to 2 T.edge[1][10]['weight'] = 2 T.edge[1][10] # Set the weight of every edge involving node 293 to be equal to 1.1 for u, v, d in T.edges(data=True): if 293 in [u, v]: T.edge[u][v]['weight'] = 1. # Checking whether there are self-loops in the graph