def _analyze_lsdb_graph(self): for ns in self.nses: for name in [srv.name for srv in self.services if nx.get_edge_attributes(self.graphs[ns], srv.name)]: G = nx.Graph([(s, d, data) for s, d, data in self.graphs[ns].edges(data=True) if data[name] == True]) if G.nodes: self.ns[ns][f'{name}_number_of_nodes'] = len(G.nodes) self.ns[ns][f'{name}_number_of_edges'] = len(G.edges) if not nx.is_connected(G): self.ns[ns][f'{name}_is_fully_connected'] = False self.ns[ns][f'{name}_center'] = False else: self.ns[ns][f'{name}_is_fully_connected'] = True self.ns[ns][f'{name}_center'] = nx.barycenter(G) self.ns[ns][f'{name}_self_loops'] = list(nx.nodes_with_selfloops(G)) self.ns[ns][f'{name}_number_of_disjoint_sets'] = len(list(nx.connected_components(G))) self.ns[ns][f'{name}_degree_histogram'] = nx.degree_histogram(G) # if there are too many degrees than the column gets too big if len(self.ns[ns][f'{name}_degree_histogram']) > 6: self.ns[ns][f'{name}_degree_histogram'] = '...' else: for k in [f'{name}_is_fully_connected', f'{name}_center', f'{name}_self_loops', f'{name}_number_of_disjoint_sets', f'{name}_degree_histogram', f'{name}_number_of_nodes', f'{name}_number_of_edges']: self.ns[ns][k] = None
def extract_simple_features(self, graph): res = {} try: print('diameter: ', nx.diameter(graph)) print('eccentricity: ', nx.eccentricity(graph)) print('center: ', nx.center(graph)) print('periphery: ', nx.periphery(graph)) res['connected'] = True except Exception as e: print('Graph not connected') res['connected'] = False res['density'] = '{:.6f}'.format(nx.density(graph)) res['Avg_degree'] = '{:.6f}'.format( sum([i[1] for i in nx.degree(graph)]) / len(nx.degree(graph))) res['Avg_weight'] = '{:.6f}'.format( sum([graph[edge[0]][edge[1]]['weight'] for edge in graph.edges]) / len([graph[edge[0]][edge[1]]['weight'] for edge in graph.edges])) res['edges'] = len(graph.edges) res['nodes'] = len(graph.nodes) res['self_loops'] = len(list(nx.nodes_with_selfloops(graph))) res['edge_to_node_ratio'] = '{:.6f}'.format( len(graph.nodes) / len(graph.edges)) res['negative_edges'] = nx.is_negatively_weighted(graph) return res
def test_selfloops(graph_type): G = nx.complete_graph(3, create_using=graph_type) G.add_edge(0, 0) assert nodes_equal(nx.nodes_with_selfloops(G), [0]) assert edges_equal(nx.selfloop_edges(G), [(0, 0)]) assert edges_equal(nx.selfloop_edges(G, data=True), [(0, 0, {})]) assert nx.number_of_selfloops(G) == 1
def print_graph_features(self, graph): res = {} try: print('diameter: ', nx.diameter(graph)) print('eccentricity: ', nx.eccentricity(graph)) print('center: ', nx.center(graph)) print('periphery: ', nx.periphery(graph)) res['connected'] = True except Exception as e: print('Graph not connected') res['connected'] = False res['density'] = '{:.6f}'.format(nx.density(graph)) res['Avg_degree'] = '{:.6f}'.format(sum([i[1] for i in nx.degree(graph)]) / len(nx.degree(graph))) res['Avg_weight'] = '{:.6f}'.format(sum([graph[edge[0]][edge[1]]['weight'] for edge in graph.edges]) / len( [graph[edge[0]][edge[1]]['weight'] for edge in graph.edges])) res['edges'] = len(graph.edges) res['nodes'] = len(graph.nodes) res['self_loops'] = len(list(nx.nodes_with_selfloops(graph))) res['edge_to_node_ratio'] = '{:.6f}'.format(len(graph.nodes) / len(graph.edges)) res['negative_edges'] = nx.is_negatively_weighted(graph) print(algo.max_clique(graph)) # print('density: ', res['density']) # print('Average degree: ', res['Avg_degree']) # print('Average weight: ', res['Avg_weight']) # print('edges: ', len(graph.edges)) # print('Nodes: ', len(graph.nodes)) # print('self loops: ', res['self_loops']) # print('edges to nodes ratio: ', res['edge_to_node_ratio']) # print('negative edges: ', res['negative_edges']) # nodes = [node for node in graph.nodes] # print(nodes) return res
def read_graph(self, input, enforce_connectivity=True, weighted=False, directed=False): ''' Reads the input network in networkx. ''' if weighted: G = nx.read_edgelist(input, nodetype=int, data=(('weight', float),), create_using=nx.DiGraph()) else: G = nx.read_edgelist(input, nodetype=int, create_using=nx.DiGraph()) for edge in G.edges(): G[edge[0]][edge[1]]['weight'] = 1 if not directed: G = G.to_undirected() # Take largest connected subgraph if enforce_connectivity and not nx.is_connected(G): #pass G = max(nx.connected_component_subgraphs(G), key=len) print("Input graph not connected: using largest connected subgraph") # Remove nodes with self-edges # I'm not sure what these imply in the dataset for se in nx.nodes_with_selfloops(G): G.remove_edge(se, se) print("Read graph, nodes: %d, edges: %d" % (G.number_of_nodes(), G.number_of_edges())) self.G = G
def _selfloop(directed_graph, S): """ """ remove_set = list(nx.nodes_with_selfloops(directed_graph)) S = S.union(set(remove_set)) directed_graph.remove_nodes_from(remove_set) return directed_graph, S, len(remove_set) == 0
def christofides(G, weight="weight", tree=None): """Approximate a solution of the traveling salesman problem Compute a 3/2-approximation of the traveling salesman problem in a complete undirected graph using Christofides [1]_ algorithm. Parameters ---------- G : Graph `G` should be a complete weighted undirected graph. The distance between all pairs of nodes should be included. weight : string, optional (default="weight") Edge data key corresponding to the edge weight. If any edge does not have this attribute the weight is set to 1. tree : NetworkX graph or None (default: None) A minimum spanning tree of G. Or, if None, the minimum spanning tree is computed using :func:`networkx.minimum_spanning_tree` Returns ------- list List of nodes in `G` along a cycle with a 3/2-approximation of the minimal Hamiltonian cycle. References ---------- .. [1] Christofides, Nicos. "Worst-case analysis of a new heuristic for the travelling salesman problem." No. RR-388. Carnegie-Mellon Univ Pittsburgh Pa Management Sciences Research Group, 1976. """ # Remove selfloops if necessary loop_nodes = nx.nodes_with_selfloops(G) try: node = next(loop_nodes) except StopIteration: pass else: G = G.copy() G.remove_edge(node, node) G.remove_edges_from((n, n) for n in loop_nodes) # Check that G is a complete graph N = len(G) - 1 # This check ignores selfloops which is what we want here. if any(len(nbrdict) != N for n, nbrdict in G.adj.items()): raise nx.NetworkXError("G must be a complete graph.") if tree is None: tree = nx.minimum_spanning_tree(G, weight=weight) L = G.copy() L.remove_nodes_from([v for v, degree in tree.degree if not (degree % 2)]) MG = nx.MultiGraph() MG.add_edges_from(tree.edges) edges = nx.min_weight_matching(L, maxcardinality=True, weight=weight) MG.add_edges_from(edges) return _shortcutting(nx.eulerian_circuit(MG))
def _extract_features_for_subgraph(self, graph): res = {} deg_list = [i[1] for i in nx.degree(graph)] weights_list = [ graph[edge[0]][edge[1]]['weight'] for edge in graph.edges ] res['connected'] = [1 if nx.is_connected(graph) else 0] res['density'] = ['{:.6f}'.format(nx.density(graph))] res['Avg_CC'] = [aprox.average_clustering(graph)] res['Median_deg'] = ['{:.6f}'.format(np.median(deg_list))] res['Variance_deg'] = ['{:.6f}'.format(np.var(deg_list))] res['Median_wights'] = [ '{:.6f}'.format( np.median(weights_list) if len(weights_list) > 0 else -1) ] res['Variance_wights'] = [ '{:.6f}'.format( np.var(weights_list) if len(weights_list) > 0 else 0) ] res['Avg_degree'] = [ '{:.6f}'.format(sum(deg_list) / len(nx.degree(graph))) ] res['Avg_weight'] = [ '{:.6f}'.format( sum(weights_list) / len(weights_list) if len(weights_list) > 0 else -1) ] res['Avg_weight_abs'] = [ '{:.6f}'.format( abs( sum(weights_list) / len(weights_list) if len(weights_list) > 0 else -1)) ] res['edges'] = [len(graph.edges)] res['nodes'] = [len(graph.nodes)] res['self_loops'] = [len(list(nx.nodes_with_selfloops(graph)))] res['edge_to_node_ratio'] = [ '{:.6f}'.format( len(graph.nodes) / len(graph.edges) if len(graph.edges) > 0 else len(graph.nodes)) ] res['negative_edges'] = [ len([ edge for edge in graph.edges if graph[edge[0]][edge[1]]['weight'] < 0 ]) ] res['Num_of_zero_weights'] = [ len([ e for e in graph.edges if 0.005 > abs(graph[e[0]][e[1]]['weight'] > 0) ]) ] res['min_vc'] = [len(aprox.min_weighted_vertex_cover(graph))] for key in res.keys(): res[key] = [float(res[key][0])] return res
def test_selfloops(self): G = self.K3.copy() G.add_edge(0, 0) assert_nodes_equal(nx.nodes_with_selfloops(G), [0]) assert_edges_equal(nx.selfloop_edges(G), [(0, 0)]) assert_equal(nx.number_of_selfloops(G), 1) G.remove_edge(0, 0) G.add_edge(0, 0) G.remove_edges_from([(0, 0)]) G.add_edge(1, 1) G.remove_node(1) G.add_edge(0, 0) G.add_edge(1, 1) G.remove_nodes_from([0, 1])
def ancestors(DiGraph, X): """ Return all nodes having a path to one of the nodes in X. """ if X in DiGraph: return networkx.ancestors(DiGraph,X) else: # bugfix for networkx.ancestors (it doesn't recognize self-loops) ancs = set([x for x in X if x in networkx.nodes_with_selfloops(DiGraph)]) for x in X: ancs.add(x) ancs.update(networkx.ancestors(DiGraph,x)) return ancs
def test_selfloops(): graphs = [nx.Graph(), nx.DiGraph(), nx.MultiGraph(), nx.MultiDiGraph()] for graph in graphs: G = nx.complete_graph(3, create_using=graph) G.add_edge(0, 0) assert_nodes_equal(nx.nodes_with_selfloops(G), [0]) assert_edges_equal(nx.selfloop_edges(G), [(0, 0)]) assert_edges_equal(nx.selfloop_edges(G, data=True), [(0, 0, {})]) assert_equal(nx.number_of_selfloops(G), 1) # test selfloop attr G.add_edge(1, 1, weight=2) assert_edges_equal(nx.selfloop_edges(G, data=True), [(0, 0, {}), (1, 1, {'weight': 2})]) assert_edges_equal(nx.selfloop_edges(G, data='weight'), [(0, 0, None), (1, 1, 2)])
def test_selfloops(): graphs = [nx.Graph(), nx.DiGraph(), nx.MultiGraph(), nx.MultiDiGraph()] for graph in graphs: G = nx.complete_graph(3, create_using=graph) G.add_edge(0, 0) assert_nodes_equal(nx.nodes_with_selfloops(G), [0]) assert_edges_equal(nx.selfloop_edges(G), [(0, 0)]) assert_edges_equal(nx.selfloop_edges(G, data=True), [(0, 0, {})]) assert nx.number_of_selfloops(G) == 1 # test selfloop attr G.add_edge(1, 1, weight=2) assert_edges_equal(nx.selfloop_edges(G, data=True), [(0, 0, {}), (1, 1, {'weight': 2})]) assert_edges_equal(nx.selfloop_edges(G, data='weight'), [(0, 0, None), (1, 1, 2)])
def prune(complete, essential, required): pruned = complete.copy() # Detect corridors corridors = set() for node in pruned.nodes: if int(node) == 20: corridors.add(node) # Merge distributed spaces merge = {node: int(node) for node in pruned.nodes if isinstance(node, float) and node not in corridors} _ = nx.relabel_nodes(pruned, merge, copy=False) # Remove self loops for node in nx.nodes_with_selfloops(pruned): pruned.remove_edge(node, node) # Remove corridors for corridor in corridors: set_of_edges = set(pruned.edges) # necessary to avoid side effects adj2corr = set() for (first, second) in set_of_edges: if corridor == first: adj2corr.add(second) if first in pruned.nodes: pruned.remove_node(first) elif corridor == second: adj2corr.add(first) if second in pruned.nodes: pruned.remove_node(second) for orig, dest in itertools.combinations(adj2corr, 2): pruned.add_edge(orig, dest) # Remove edges incident on non essential nodes edgeless = set(complete.nodes).difference(essential).difference(corridors).union(required) for (start, end) in list(pruned.edges): # Beware of side effects if start in edgeless or end in edgeless: pruned.remove_edge(start, end) # Sort nodes lexicographically for proper representation out = nx.Graph() out.name = pruned.name out.add_nodes_from(sorted(pruned.nodes)) out.add_edges_from(sorted(pruned.edges)) return out
def find_ancestors(digraph: networkx.DiGraph, node_or_nodes): """ Return all nodes having a path to one of the nodes in *node_or_nodes*. """ if node_or_nodes in digraph: return networkx.ancestors(digraph, node_or_nodes) else: # bugfix for networkx.ancestors (it doesn't recognize self-loops) ancestors = set([ x for x in node_or_nodes if x in networkx.nodes_with_selfloops(digraph) ]) for x in node_or_nodes: ancestors.add(x) ancestors.update(networkx.ancestors(digraph, x)) return ancestors
def get_features(self): feature_vector = {} feature_vector['g_nodes'] = len(self.graph.nodes.keys()) feature_vector['g_edges'] = len(self.graph.edges.keys()) feature_vector['g_selfloops'] = len( list(nx.nodes_with_selfloops(self.graph))) feature_vector['g_max_degree'] = max( [d for n, d in self.graph.degree()]) feature_vector['g_mean_degree'] = np.mean( [d for n, d in self.graph.degree()]) feature_vector['g_sd_degree'] = np.std( [d for n, d in self.graph.degree()]) feature_vector['g_max_in_degree'] = max( [d for n, d in self.graph.in_degree()]) feature_vector['g_mean_in_degree'] = np.mean( [d for n, d in self.graph.in_degree()]) feature_vector['g_sd_in_degree'] = np.std( [d for n, d in self.graph.in_degree()]) feature_vector['g_max_out_degree'] = max( [d for n, d in self.graph.out_degree()]) feature_vector['g_mean_out_degree'] = np.mean( [d for n, d in self.graph.out_degree()]) feature_vector['g_sd_out_degree'] = np.std( [d for n, d in self.graph.out_degree()]) feature_vector['g_density'] = nx.density(self.graph) feature_vector['g_independent'] = sum( [1 if d == 0 else 0 for n, d in self.graph.in_degree()]) feature_vector['g_dependent'] = sum( [1 if d != 0 else 0 for n, d in self.graph.in_degree()]) feature_vector['g_leaves'] = sum( [1 if d == 0 else 0 for n, d in self.graph.out_degree()]) scc = filter(lambda x: len(x) > 1, list(nx.strongly_connected_components(self.graph))) feature_vector['g_scc'] = len(scc) feature_vector['g_succ_size_max'] = max([len(x) for x in scc ]) if len(scc) > 0 else 0 feature_vector['g_succ_size_mean'] = np.mean([len(x) for x in scc ]) if len(scc) > 0 else 0 feature_vector['g_succ_size_sd'] = np.std([len(x) for x in scc ]) if len(scc) > 0 else 0 return feature_vector
def fvs_bruteforce(directed_graph, max_search=5, keep_self_loops=True): """The Feedback Vertex Set bruteforce implementation. Args: directed_graph (networkx.DiGraph) : The structure graph. max_search (int) : Maximum number of additional variables to include in the search. keep_self_loops (bool) : If self-loops are used in the computation. By FVS theory, all self-loop nodes are needed for control. Returns: (list) : A list of sets with with the driver nodes. Warning: Use the GRASP method for large graphs. See also: :func:`fvs_grasp`. """ if keep_self_loops: minfvc = set(nx.nodes_with_selfloops(directed_graph)) else: directed_graph = copy.deepcopy(directed_graph) directed_graph.remove_edges_from(directed_graph.selfloop_edges()) minfvc = set([]) root_var = _root_variables(directed_graph, keep_self_loops=keep_self_loops) minfvc = minfvc.union(root_var) if _is_acyclic(directed_graph): return [minfvc] else: FVC_sets = [] nonfvc_variables = set(directed_graph.nodes()) - minfvc num_additional_var = 0 while num_additional_var <= max_search and len(FVC_sets) == 0: for an_combo in itertools.combinations(nonfvc_variables, num_additional_var): possible_fvs = minfvc.union(an_combo) if _is_acyclic(_graph_minus(directed_graph, possible_fvs)): FVC_sets.append(possible_fvs) num_additional_var += 1 return FVC_sets
def extract_graph_features(self, graph): """ ref: https://networkx.github.io/documentation/stable/_modules/networkx/algorithms/approximation/vertex_cover.html ref: https://networkx.github.io/documentation/stable/reference/algorithms/approximation.html#module-networkx.algorithms.approximation """ res = {} deg_list = [i[1] for i in nx.degree(graph)] weights_list = [ graph[edge[0]][edge[1]]['weight'] for edge in graph.edges ] if len(weights_list) == 0: return None # try: # weights_list = [graph[edge[0]][edge[1]]['weight'] for edge in graph.edges] # except: # return None res['connected'] = 1 if nx.is_connected(graph) else 0 res['density'] = '{:.6f}'.format(nx.density(graph)) res['Avg_CC'] = aprox.average_clustering(graph) res['Median_deg'] = '{:.6f}'.format(np.median(deg_list)) res['Variance_deg'] = '{:.6f}'.format(np.var(deg_list)) res['Median_wights'] = '{:.6f}'.format(np.median(weights_list)) res['Variance_wights'] = '{:.6f}'.format(np.var(weights_list)) res['Avg_degree'] = '{:.6f}'.format( sum(deg_list) / len(nx.degree(graph))) res['Avg_weight'] = '{:.6f}'.format( sum(weights_list) / len(weights_list)) res['Avg_weight_abs'] = '{:.6f}'.format( abs(sum(weights_list) / len(weights_list))) res['edges'] = len(graph.edges) res['nodes'] = len(graph.nodes) res['self_loops'] = len(list(nx.nodes_with_selfloops(graph))) res['edge_to_node_ratio'] = '{:.6f}'.format( len(graph.nodes) / len(graph.edges)) res['negative_edges'] = len([ edge for edge in graph.edges if graph[edge[0]][edge[1]]['weight'] < 0 ]) res['Num_of_zero_weights'] = len([ e for e in graph.edges if 0.005 > abs(graph[e[0]][e[1]]['weight'] > 0) ]) res['min_vc'] = len(aprox.min_weighted_vertex_cover(graph)) return res
def test_selfloops(): graphs = [nx.Graph(), nx.DiGraph(), nx.MultiGraph(), nx.MultiDiGraph()] for graph in graphs: G = nx.complete_graph(3, create_using=graph) G.add_edge(0, 0) assert_nodes_equal(nx.nodes_with_selfloops(G), [0]) assert_edges_equal(nx.selfloop_edges(G), [(0, 0)]) assert_edges_equal(nx.selfloop_edges(G, data=True), [(0, 0, {})]) assert nx.number_of_selfloops(G) == 1 # test selfloop attr G.add_edge(1, 1, weight=2) assert_edges_equal(nx.selfloop_edges(G, data=True), [(0, 0, {}), (1, 1, { "weight": 2 })]) assert_edges_equal(nx.selfloop_edges(G, data="weight"), [(0, 0, None), (1, 1, 2)]) # test removing selfloops behavior vis-a-vis altering a dict while iterating G.add_edge(0, 0) G.remove_edges_from(nx.selfloop_edges(G)) if G.is_multigraph(): G.add_edge(0, 0) pytest.raises(RuntimeError, G.remove_edges_from, nx.selfloop_edges(G, keys=True)) G.add_edge(0, 0) pytest.raises(TypeError, G.remove_edges_from, nx.selfloop_edges(G, data=True)) G.add_edge(0, 0) pytest.raises( RuntimeError, G.remove_edges_from, nx.selfloop_edges(G, data=True, keys=True), ) else: G.add_edge(0, 0) G.remove_edges_from(nx.selfloop_edges(G, keys=True)) G.add_edge(0, 0) G.remove_edges_from(nx.selfloop_edges(G, data=True)) G.add_edge(0, 0) G.remove_edges_from(nx.selfloop_edges(G, keys=True, data=True))
def fvs_grasp(directed_graph, max_iter=100, keep_self_loops=True): """The Feedback Vertex Set GRASP implementation. This implementation is not exact but it is recommended for very large graphs. Args: directed_graph (networkx.DiGraph) : The structure graph. max_iter (int) : Maximum number of iterations for the search. keep_self_loops (bool) : If self-loops are used in the computation. By FVS theory, all self-loop nodes are needed for control. Returns: (list) : A list of sets with the driver nodes. See also: :func:`fvs_bruteforce`. """ if keep_self_loops: S = set(nx.nodes_with_selfloops(directed_graph)) else: directed_graph = copy.deepcopy(directed_graph) directed_graph.remove_edges_from(directed_graph.selfloop_edges()) S = set([]) root_var = _root_variables(directed_graph, keep_self_loops=keep_self_loops) S = S.union(root_var) minfvc = set([frozenset(directed_graph.nodes())]) reduced_graph = directed_graph.copy() for i_iter in range(max_iter): alpha = np.random.random() S = _construct_greedy_randomized_solution(reduced_graph, alpha, S) S = _local_search(directed_graph.copy(), S) compare_set = next(iter(minfvc)) if len(S) == len(compare_set): minfvc.add(frozenset(S)) elif len(S) < len(compare_set): minfvc = set([frozenset(S)]) return list(minfvc)
def has_self_loops(self): """ means that there are two consecutive stops that are the same :return: """ return list(nx.nodes_with_selfloops(self.graph()))
def has_self_loops(self): return list(nx.nodes_with_selfloops(self.graph()))
def compute_periodicity_all_simple_paths_algorithm(self): """ Returns: """ self_loop_nodes = list(nx.nodes_with_selfloops(self._connected_subgraph)) all_nodes_independent_cell_image_vectors = [] my_simple_graph = nx.Graph(self._connected_subgraph) for test_node in self._connected_subgraph.nodes(): # TODO: do we need to go through all test nodes ? this_node_cell_img_vectors = [] if test_node in self_loop_nodes: for key, edge_data in self._connected_subgraph[test_node][test_node].items(): if edge_data["delta"] == (0, 0, 0): raise ValueError("There should not be self loops with delta image = (0, 0, 0).") this_node_cell_img_vectors.append(edge_data["delta"]) for d1, d2 in itertools.combinations(this_node_cell_img_vectors, 2): if d1 == d2 or d1 == tuple(-ii for ii in d2): raise ValueError("There should not be self loops with the same (or opposite) delta image.") this_node_cell_img_vectors = get_linearly_independent_vectors(this_node_cell_img_vectors) # Here, we adopt a cutoff equal to the size of the graph, contrary to the default of networkX (size - 1), # because otherwise, the all_simple_paths algorithm fail when the source node is equal to the target node. paths = [] # TODO: its probably possible to do just a dfs or bfs traversal instead of taking all simple paths! test_node_neighbors = my_simple_graph.neighbors(test_node) breaknodeloop = False for test_node_neighbor in test_node_neighbors: # Special case for two nodes if len(self._connected_subgraph[test_node][test_node_neighbor]) > 1: this_path_deltas = [] node_node_neighbor_edges_data = list( self._connected_subgraph[test_node][test_node_neighbor].values() ) for edge1_data, edge2_data in itertools.combinations(node_node_neighbor_edges_data, 2): delta1 = get_delta(test_node, test_node_neighbor, edge1_data) delta2 = get_delta(test_node_neighbor, test_node, edge2_data) this_path_deltas.append(delta1 + delta2) this_node_cell_img_vectors.extend(this_path_deltas) this_node_cell_img_vectors = get_linearly_independent_vectors(this_node_cell_img_vectors) if len(this_node_cell_img_vectors) == 3: break for path in nx.all_simple_paths( my_simple_graph, test_node, test_node_neighbor, cutoff=len(self._connected_subgraph), ): path_indices = [nodepath.isite for nodepath in path] if path_indices == [test_node.isite, test_node_neighbor.isite]: continue path_indices.append(test_node.isite) path_indices = tuple(path_indices) if path_indices not in paths: paths.append(path_indices) else: continue path.append(test_node) # TODO: there are some paths that appears twice for cycles, and there are some paths that should # probably not be considered this_path_deltas = [np.zeros(3, np.int_)] for (node1, node2) in [(node1, path[inode1 + 1]) for inode1, node1 in enumerate(path[:-1])]: this_path_deltas_new = [] for key, edge_data in self._connected_subgraph[node1][node2].items(): delta = get_delta(node1, node2, edge_data) for current_delta in this_path_deltas: this_path_deltas_new.append(current_delta + delta) this_path_deltas = this_path_deltas_new this_node_cell_img_vectors.extend(this_path_deltas) this_node_cell_img_vectors = get_linearly_independent_vectors(this_node_cell_img_vectors) if len(this_node_cell_img_vectors) == 3: breaknodeloop = True break if breaknodeloop: break this_node_cell_img_vectors = get_linearly_independent_vectors(this_node_cell_img_vectors) independent_cell_img_vectors = this_node_cell_img_vectors all_nodes_independent_cell_image_vectors.append(independent_cell_img_vectors) # If we have found that the sub structure network is 3D-connected, we can stop ... if len(independent_cell_img_vectors) == 3: break self._periodicity_vectors = [] if len(all_nodes_independent_cell_image_vectors) != 0: for independent_cell_img_vectors in all_nodes_independent_cell_image_vectors: if len(independent_cell_img_vectors) > len(self._periodicity_vectors): self._periodicity_vectors = independent_cell_img_vectors if len(self._periodicity_vectors) == 3: break
def get_long_self_loops(G, min_length, seqs, bamfile, use_scores=True, use_genes=True, max_k_val=55, score_thresh=0.9, mate_thresh=0.1): """ returns set of self loop nodes paths that are longer than min length and satisfy mate pair requirements; removes those and short self loops from G """ potential_plasmids = set([]) to_remove = [] for nd in list(nx.nodes_with_selfloops(G)): if (rc_node(nd), ) in potential_plasmids: continue nd_path = (nd, ) path_len = len(get_seq_from_path(nd_path, seqs, max_k_val)) # check whether it is isolated or connected to other nodes: isolated_loop = False if G.in_degree(nd) == 1 and G.out_degree(nd) == 1: isolated_loop = True if isolated_loop: if path_len < min_length: to_remove.append(nd) continue # take nodes that have plasmid genes or very high plasmid scores if use_scores and use_genes: logger.info("SLS: %f" % PARAMS.SELF_LOOP_SCORE_THRESH) if G.nodes[nd][ 'score'] > PARAMS.SELF_LOOP_SCORE_THRESH or G.nodes[ nd]['gene'] == True: potential_plasmids.add(nd_path) logger.info( "Added path: %s - high scoring long self-loop" % nd) to_remove.append(nd) continue off_node_mate_count, on_node_mate_count = count_selfloop_mates( nd, bamfile, G) if float( off_node_mate_count ) > PARAMS.SELF_LOOP_MATE_THRESH * float(on_node_mate_count): logger.info( 'Self loop %s has %2f percent off-node mate-pairs. Removing' % (nd, PARAMS.SELF_LOOP_MATE_THRESH)) to_remove.append(nd) else: potential_plasmids.add(nd_path) logger.info("Added path: %s - long self loop" % nd) to_remove.append(nd) else: # non-isolated loop if path_len < min_length: continue off_node_mate_count, on_node_mate_count = count_selfloop_mates( nd, bamfile, G) if float(off_node_mate_count ) > PARAMS.SELF_LOOP_MATE_THRESH * float( on_node_mate_count ): # TODO: could be different than for isolated loop # Maybe - func of node length (and read length, insert size???) logger.info( 'Self loop %s has %2f percent off-node mate-pairs.' % (nd, PARAMS.SELF_LOOP_MATE_THRESH)) else: potential_plasmids.add(nd_path) logger.info("Added path: %s - long self loop" % nd) to_remove.append(nd) for nd in to_remove: update_node_coverage(G, nd, 0) logger.info("Removing %d self-loop nodes" % len(to_remove)) return potential_plasmids
# importing networkx import networkx as nx # importing matplotlib.pyplot import matplotlib.pyplot as plt edges = [(1, 2), (1, 6), (2, 3), (2, 4), (2, 6), (3, 4), (3, 5), (4, 8), (4, 9), (6, 7)] G = nx.Graph() G.add_edges_from(edges) print("Total number of nodes: ", int(G.number_of_nodes())) print("Total number of edges: ", int(G.number_of_edges())) print("List of all nodes: ", list(G.nodes())) print("List of all edges: ", list(G.edges(data=True))) print("Degree for all nodes: ", dict(G.degree())) nx.selfloop_edges(G) print("Total number of self-loops: ", (nx.selfloop_edges(G))) print("List of all nodes with self-loops: ", list(nx.nodes_with_selfloops(G))) print("List of all nodes we can go to in a single step from node 2: ", list(G.neighbors(2))) nx.draw_networkx(G, with_label=True) plt.savefig("uwork.png")
def graph_properties(graph, weight_label="weight"): """ Calculates properties of edge weights. Parameters ---------- graph: nx.Graph Graph to calculate the properties from weight_label: str Optional, which label to use as edge-weight If None no edge weight related statistics get collected Returns ------- properties: dict A dict with the following calculated properties: num_nodes: int Number of nodes of the graph num_edges: int Number of edges of the graph avg_degree: float Average degree of node density: float Number of edges divided by the number of possible edges planar: bool Whether the graph is planar or not max_edgeweight: float Maximum weights of an edge min_edgeweight: float Minimum weight of an edge num_of_zero_weights: int Number of edges with zero weight num_of_connected_components: int Number of connected components in the graph max_degree: int Maximum degree of a node in the graph assortativity_coeff: float The degree assortativity coefficient as defined in [1] number_of_triangles: int Number of traingles in the graph average_clustering_coeff: float Average clustering coefficient as defined in [2] max_k_core: int Maximum k-core as defined in [3] number_of_selfloop_nodes: int Number of nodes that have a self-loop number_of_selfloops: int Total number of selfloops in the graph References ---------- ..[1] https://networkx.org/documentation/stable//reference/algorithms/generated/networkx.algorithms.assortativity.degree_assortativity_coefficient.html ..[2] https://networkx.org/documentation/networkx-2.4/reference/algorithms/generated/networkx.algorithms.cluster.average_clustering.html ..[3] https://networkx.org/documentation/networkx-1.9/reference/generated/networkx.algorithms.core.core_number.html """ avg_degree = sum( (deg for node, deg in graph.degree)) / graph.number_of_nodes() density = graph.number_of_edges() / ( (graph.number_of_nodes() * graph.number_of_nodes() - graph.number_of_nodes()) / 2) planar, _ = nx.algorithms.check_planarity(graph) num_of_connected_components = nx.number_connected_components(graph) number_of_triangles = sum(nx.triangles(graph).values()) // 3 max_degree = max(degree for _, degree in graph.degree) assortativity_coeff = ( None # TODO (JC): bug - nx.degree_assortativity_coefficient(g) ) average_clustering_coeff = nx.average_clustering(graph) max_k_core = max(nx.core_number(graph).values()) number_of_selfloop_nodes = len(list(nx.nodes_with_selfloops(graph))) number_of_selfloops = len(list(nx.selfloop_edges(graph))) d = { "num_nodes": graph.number_of_nodes(), "num_edges": graph.number_of_edges(), "avg_degree": avg_degree, "density": density, "planar": planar, "num_of_connected_components": num_of_connected_components, "max_degree": max_degree, "assortativity_coeff": assortativity_coeff, "number_of_triangles": number_of_triangles, "average_clustering_coeff": average_clustering_coeff, "max_k_core": max_k_core, "number_of_selfloop_nodes": number_of_selfloop_nodes, "number_of_selfloops": number_of_selfloops, } if weight_label: max_edgeweight, min_edgeweight, num_of_zero_edgeweights = edgeweight_properties( graph, weight_label) d = { **d, "max_edgeweight": max_edgeweight, "min_edgeweight": min_edgeweight, "num_of_zero_edgeweights": num_of_zero_edgeweights } return d
fig2 = plt.figure() ax2 = fig2.add_subplot(111) ax2.loglog([overlap_value for (overlap_value, frequency) in overlap_map], [frequency for (overlap_value, frequency) in overlap_map], 'b.') plt.legend("Todos nos") plt.xlabel('Overlap') plt.ylabel('Numero de nos') plt.title("Distribuição do overlap da vizinhança") fig2.savefig("overlap.png") #Path print("Removing isolates nodes and self loops") tempgraph = G.copy() isolate_list = list(nx.isolates(tempgraph)) self_edges = list(nx.nodes_with_selfloops(tempgraph)) #Removing isolates nodes and self loops for loop in self_edges: tempgraph.remove_edge(loop, loop) for isolated_node in isolate_list: tempgraph.remove_node(isolated_node) print("Calculating average path and all pairs shortest path") print(nx.average_shortest_path_length(tempgraph)) #Insert print(all_paths) here all_paths = dict(nx.all_pairs_shortest_path_length(tempgraph, None)) paths = {} for key, dict2 in all_paths.items():
def removeSelfLoops(G): selfLoopNodes = list(nx.nodes_with_selfloops(G)) for selfLoopNode in selfLoopNodes: G.remove_edge(selfLoopNode, selfLoopNode)
def is_valid_nxgraph(nxgraph, raise_errors=True, ignore_cell_type=False, allow_selfloops=False): """Check if a given graph is a valid GraphLSTMNet graph. Args: nxgraph (any): The graph to be checked. raise_errors (bool): If True, the method raises an error as soon as a problem is detected. ignore_cell_type (bool): If True, the graph will not be considered 'bad' if its cells are not GraphLSTMCells. allow_selfloops (bool): If True, the graph will not be considered 'bad' if it contains selfloops. Returns: True if graph is fine, False otherwise. Raises: TypeError: If something inside the graph (or the graph itself) is of the wrong type. ValueError: If graph contains no nodes, or the _INDEX attributes don't form the expected well-defined list. LookupError: If a node misses the _CELL, _CONFIDENCE or _INDEX attribute. """ try: if not isinstance(nxgraph, nx.classes.graph.Graph): raise TypeError( "nxgraph is of type %s, but should be an instance of networkx.classes.graph.Graph." % str(nxgraph)) if nxgraph.number_of_nodes() < 1: raise ValueError("nxgraph needs at least one node.") if not allow_selfloops and nx.number_of_selfloops(nxgraph) != 0: raise ValueError( "nxgraph has %i selfloops. " "If this is expected, consider running is_valid_nxgraph with allow_selfloops=True.\n" "Nodes with selfloops: %r" % (nx.number_of_selfloops(nxgraph), list(nx.nodes_with_selfloops(nxgraph)))) node_attr_lookuperr = None index_list = [] for node_name in nxgraph.nodes: if _CELL not in nxgraph.nodes[node_name]: node_attr_lookuperr = "_CELL" elif _INDEX not in nxgraph.nodes[node_name]: node_attr_lookuperr = "_INDEX" elif _CONFIDENCE not in nxgraph.nodes[node_name]: node_attr_lookuperr = "_CONFIDENCE" if node_attr_lookuperr is not None: raise KeyError("Node '%s' has no attribute %s" % (node_name, node_attr_lookuperr)) if not ignore_cell_type: # todo: verify same output size for all cells? does that make sense? if not isinstance(nxgraph.nodes[node_name][_CELL], GraphLSTMCell): raise TypeError( "Cell of node '%s' is not a GraphLSTMCell. " "If this is expected, consider running is_valid_nxgraph with " "ignore_cell_type=True." % node_name) if not isinstance(nxgraph.nodes[node_name][_INDEX], int): raise TypeError( "_INDEX attribute should always be an integer, but is not for node '%s'" % node_name) else: index_list.append(nxgraph.nodes[node_name][_INDEX]) if not isinstance(nxgraph.nodes[node_name][_CONFIDENCE], float): raise TypeError( "_CONFIDENCE attribute should always be float, but is not for node '%s'" % node_name) if sorted(index_list) != list(range(len(index_list))): raise ValueError( "The values of all _INDEX attributes have to form a well-sorted list, " "starting at 0 and ending at number of nodes - 1.\n" "Expected 0 ... %i, but found:\n%s" % (len(index_list) - 1, sorted(index_list))) except (TypeError, ValueError, KeyError): if raise_errors: raise return False else: return True
from itertools import chain import networkx as nx from networkx.utils import not_implemented_for import matplotlib matplotlib.use("agg") import matplotlib.pyplot as plt import bridges as bridges print("Loading graph file") GraphFile = "graphs/graph_version6.gexf" G = nx.read_gexf(GraphFile) print("Removing self loops and isolated nodes") isolate_list = list(nx.isolates(G)) self_edges = list(nx.nodes_with_selfloops(G)) for loop in self_edges: G.remove_edge(loop, loop) for isolated_node in isolate_list: G.remove_node(isolated_node) print("Calculating bridges, local brigdes and span") print(list(bridges.bridges(G))) print(list(bridges.local_bridges(G, True))) print("Calculating clustering") clustering = {} index = 0 for node in G.nodes():
# 10. Заданий граф (орграф) у вигляді матриці суміжності. Скласти програму: # а) перевірки, чи є в графі петлі; # б) пошуку в графі ізольованої вершини (не суміжної з іншими); # в) визначення ступеня графа; # г) отримання послідовності ребер. import networkx as nx import matplotlib.pyplot as plt G = nx.gnm_random_graph(6,6) G.add_edge(1, 1)#петля plt.subplot(121) nx.draw(G, with_labels=True, font_weight='bold') print(G.edges) print( "a)петлі: ",list(nx.nodes_with_selfloops(G))) print( "б)ізольованої вершини: ",list(nx.isolates(G))) print( "г)ребра: ",list(nx.edges(G))) plt.show()
def assert_no_selfloops(graph): """Raise an error if the graph graph has any selfloops. """ if len(list(nx.nodes_with_selfloops(graph))) > 0: raise ValueError("input graph can not have selfloops")