def edge_grab( two_qubit_gate_prob: float, connectivity_graph: nx.Graph, random_state: random.RandomState, ) -> nx.Graph: """Returns a set of edges for which two qubit gates are to be applied given a two qubit gate density and the connectivity graph that must be satisfied. Args: two_qubit_gate_prob: Probability of an edge being chosen from the set of candidate edges. connectivity_graph: The connectivity graph for the backend on which the circuit will be run. random_state: Random state to select edges (uniformly at random). """ connectivity_graph = connectivity_graph.copy() candidate_edges = nx.Graph() final_edges = nx.Graph() final_edges.add_nodes_from(connectivity_graph) while connectivity_graph.edges: num = random_state.randint(connectivity_graph.size()) edges = list(connectivity_graph.edges) curr_edge = edges[num] candidate_edges.add_edge(*curr_edge) connectivity_graph.remove_nodes_from(curr_edge) for edge in candidate_edges.edges: if random_state.uniform(0.0, 1.0) < two_qubit_gate_prob: final_edges.add_edge(*edge) return final_edges
def newman_girvan_modularity(graph: nx.Graph, communities: object, **kwargs: dict) -> object: """Difference the fraction of intra community edges of a partition with the expected number of such edges if distributed according to a null model. In the standard version of modularity, the null model preserves the expected degree sequence of the graph under consideration. In other words, the modularity compares the real network structure with a corresponding one where nodes are connected without any preference about their neighbors. .. math:: Q(S) = \\frac{1}{m}\\sum_{c \\in S}(m_S - \\frac{(2 m_S + l_S)^2}{4m}) where :math:`m` is the number of graph edges, :math:`m_S` is the number of community edges, :math:`l_S` is the number of edges from nodes in S to nodes outside S. :param graph: a networkx/igraph object :param communities: NodeClustering object :return: FitnessResult object Example: >>> from cdlib.algorithms import louvain >>> from cdlib import evaluation >>> g = nx.karate_club_graph() >>> communities = louvain(g) >>> mod = evaluation.newman_girvan_modularity(g,communities) :References: 1. Newman, M.E.J. & Girvan, M. `Finding and evaluating community structure in networks. <https://www.ncbi.nlm.nih.gov/pubmed/14995526/>`_ Physical Review E 69, 26113(2004). """ graph = convert_graph_formats(graph, nx.Graph) coms = {} for cid, com in enumerate(communities.communities): for node in com: coms[node] = cid inc = dict([]) deg = dict([]) links = graph.size(weight='weight') if links == 0: raise ValueError("A graph without link has an undefined modularity") for node in graph: try: com = coms[node] deg[com] = deg.get(com, 0.) + graph.degree(node, weight='weight') for neighbor, dt in graph[node].items(): weight = dt.get("weight", 1) if coms[neighbor] == com: if neighbor == node: inc[com] = inc.get(com, 0.) + float(weight) else: inc[com] = inc.get(com, 0.) + float(weight) / 2. except: pass res = 0. for com in set(coms.values()): res += (inc.get(com, 0.) / links) - (deg.get(com, 0.) / (2. * links))**2 return FitnessResult(score=res)
def __init__(self, graph: nx.Graph, dataset: str, model: str, iteration: int, trial: int): self.graph: nx.Graph = graph self.trial = trial self.dataset = dataset self.model = model self.iteration = iteration self.stats: Dict[str, Any] = { 'dataset': dataset, 'model': model, 'iteration': iteration, 'trial': trial, 'n': graph.order(), 'm': graph.size() }
def deltaModularity(graph: nx.Graph, nodeCommunities: dict, vertex: int, community: int, weight='weight') -> float: communities = reverseDict(nodeCommunities) m = graph.size(weight=weight) sEdgesIC = sumOfEdgesBetweenVertexAndCommunity(graph, vertex, communities[community], weight) sEdgesXC = sumOfEdgesBetweenCommunityAndGraph(graph, communities[community], weight) sEdgesIX = sumOfEdgesBetweenVertexAndGraph(graph, vertex, weight) return (sEdgesIC / (2 * m)) - ((sEdgesXC * sEdgesIX) / (2 * (m**2)))
def preprocess(graph: nx.Graph, reindex_nodes: bool, first_label: int = 0, take_lcc: bool = True) -> nx.Graph: """ Preprocess the graph - taking the largest connected components, re-index nodes if needed :return: """ #CP.print_none('Pre-processing graph....') #CP.print_none(f'Original graph "{self.gname}" n:{self.graph.order():,} ' # f'm:{self.graph.size():,} #components: {nx.number_connected_components(self.graph)}') if take_lcc and nx.number_connected_components(graph) > 1: ## Take the LCC component_sizes = [ len(c) for c in sorted( nx.connected_components(graph), key=len, reverse=True) ] #CP.print_none(f'Taking the largest component out of {len(component_sizes)} components: {component_sizes}') graph_lcc = nx.Graph( graph.subgraph(max(nx.connected_components(graph), key=len))) perc_nodes = graph_lcc.order() / graph.order() * 100 perc_edges = graph_lcc.size() / graph.size() * 100 #CP.print_orange(f'LCC has {print_float(perc_nodes)}% of nodes and {print_float(perc_edges)}% edges in the original graph') graph = graph_lcc selfloop_edges = list(nx.selfloop_edges(graph)) if len(selfloop_edges) > 0: #CP.print_none(f'Removing {len(selfloop_edges)} self-loops') graph.remove_edges_from(selfloop_edges) # remove self-loops if reindex_nodes: # re-index nodes, stores the old label in old_label graph = nx.convert_node_labels_to_integers(graph, first_label=first_label, label_attribute='old_label') #CP.print_none( # f'Re-indexing nodes to start from {first_label}, old labels are stored in node attr "old_label"') #CP.print_none(f'Pre-processed graph "{self.gname}" n:{self.graph.order():,} m:{self.graph.size():,}') return graph
def from_graph(cls, g: nx.Graph, json_path: Path = None, *, label: str = "") -> "Network": g = nx.convert_node_labels_to_integers(g) if g.size() == 0: edges = np.zeros((0, 2), dtype=np.int32) else: edges = np.array(g.edges(), dtype=np.int32) net = cls.from_edges( n=g.order(), edges=edges, directed=isinstance(g, nx.DiGraph), json_path=json_path, label=label, ) net._network = g return net
def __init__(self, graph: nx.Graph, vertexesCommunities=None, weight='weight'): self.m = graph.size(weight=weight) self.ma = 1 / self.m self.mb = 1 / (2 * self.m) self.vertexesDegrees = graph.degree(weight=weight) self.vertexesCommunities = vertexesCommunities if vertexesCommunities else {} self.communitiesVertexes = reverseDict(self.vertexesCommunities) self.communitiesWeightedDegreeSum = defaultdict(float) self.communitiesEdgeSum = defaultdict(float) for i in graph: com = vertexesCommunities[i] self.communitiesWeightedDegreeSum[com] += self.vertexesDegrees[i] for j, edge in graph[i].items(): w = edge.get(weight, 1) if i == j else edge.get(weight, 1) / 2 self.communitiesEdgeSum[com] += w
def modularity(graph: nx.Graph, partition: List[Set[int]], weight='weight') -> float: """ Calculates the modularity of a graph. Parameters ---------- graph: nx.Graph A NetworkX Graph. partition: List[Set[int]] A list of sets of ints, where each set represents a community and each int represents a vertex weight: str The name of the key used in the node to represent it's weight Returns ------- Q: float The modularity Examples ________ >>> g = nx.complete_graph(5) >>> q = modularity(g, [{0, 1, 2}, {3, 4}]) -0.12000000000000002 """ m = graph.size(weight=weight) norm = 1 / (2 * m) vertexWeightedDegrees = dict(graph.degree(weight=weight)) def val(i, j): edgeWeight = graph[i][j].get(weight, 1) if j in graph[i] else 0 w = edgeWeight * 2 if i == j else edgeWeight return w - (vertexWeightedDegrees[i] * vertexWeightedDegrees[j] * norm) return sum( val(i, j) for com in partition for i, j in product(com, repeat=2)) * norm
class NetworkXGraphBackend(GenericGraphBackend): """ A wrapper for NetworkX as the backend of a graph. TESTS:: sage: import sage.graphs.base.graph_backends """ _nxg = None def __init__(self, N=None): """ Initialize the backend with NetworkX graph N. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_edges([],True) <generator object iterator_edges at ...> """ if N is None: import networkx N = networkx.MultiGraph() self._nxg = N try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() def add_edge(self, u, v, l, directed): """ Add an edge (u,v) to self, with label l. If directed is True, this is interpreted as an arc from u to v. INPUT: - ``u,v`` -- vertices - ``l`` -- edge label - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_edge(1,2,'a',True) """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() if u is None: u = self.add_vertex(None) if v is None: v = self.add_vertex(None) if l: self._nxg.add_edge(u, v, weight=l) else: self._nxg.add_edge(u, v) def add_edges(self, edges, directed): """ Add a sequence of edges to self. If directed is True, these are interpreted as arcs. INPUT: - ``edges`` -- list/iterator of edges to be added. - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_edges([],True) """ for e in edges: try: u, v, l = e except ValueError: u, v = e l = None self.add_edge(u, v, l, directed) def add_vertex(self, name): """ Add a labelled vertex to self. INPUT: - ``name``: vertex label OUTPUT: If ``name=None``, the new vertex name is returned. ``None`` otherwise. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertex(0) """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() retval = None if name is None: # then find an integer to use as a key i = 0 while self.has_vertex(i): i = i + 1 name = i retval = name self._nxg.add_node(name) return retval def add_vertices(self, vertices): """ Add labelled vertices to self. INPUT: - ``vertices``: iterator of vertex labels. A new label is created, used and returned in the output list for all ``None`` values in ``vertices``. OUTPUT: Generated names of new vertices if there is at least one ``None`` value present in ``vertices``. ``None`` otherwise. EXAMPLES:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertices([1,2,3]) sage: G.add_vertices([4,None,None,5]) [0, 6] """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() vertices = list(vertices) nones = vertices.count(None) vertices = [v for v in vertices if v is not None] self._nxg.add_nodes_from(vertices) new_names = [] i = 0 while nones > 0: while self.has_vertex(i): i += 1 self._nxg.add_node(i) new_names.append(i) nones -= 1 i += 1 return new_names if new_names != [] else None def degree(self, v, directed): """ Returns the total number of vertices incident to v. INPUT: - ``v`` -- a vertex label - ``directed`` -- boolean OUTPUT: degree of v TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertices(range(3)) sage: G.degree(1, False) 0 """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.degree(v) def del_edge(self, u, v, l, directed): """ Deletes the edge (u,v) with label l. INPUT: - ``u,v`` -- vertices - ``l`` -- edge label - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.del_edge(1,2,'a',True) """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() import networkx try: if self._nxg.is_multigraph(): for k, d in self._nxg.edge[u][v].iteritems(): if d.get('weight', None) == l: self._nxg.remove_edge(u, v, k) break else: if l is None or self._nxg.edge[u][v].get('weight', None) == l: self._nxg.remove_edge(u, v) except (KeyError, networkx.NetworkXError): pass def del_vertex(self, v): """ Delete a labelled vertex in self. INPUT: - ``v`` -- vertex label TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.del_vertex(0) Traceback (most recent call last): ... NetworkXError: The node 0 is not in the graph. """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() self._nxg.remove_node(v) def del_vertices(self, vertices): """ Delete labelled vertices in self. INPUT: - ``vertices`` -- iterator of vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.del_vertices([1,2,3]) Traceback (most recent call last): ... NetworkXError: The node 1 is not in the graph. """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() for v in vertices: self._nxg.remove_node(v) def get_edge_label(self, u, v): """ Returns the edge label of (u,v). INPUT: - ``u,v`` -- vertex labels OUTPUT: label of (u,v) TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.get_edge_label(1,2) Traceback (most recent call last): ... NetworkXError: Edge (1,2) requested via get_edge_label does not exist. """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() try: E = self._nxg.edge[u][v] except KeyError: from networkx import NetworkXError raise NetworkXError( "Edge (%s,%s) requested via get_edge_label does not exist." % (u, v)) if self._nxg.is_multigraph(): return [e.get('weight', None) for e in E.itervalues()] else: return E.get('weight', None) def has_edge(self, u, v, l): """ True if self has an edge (u,v) with label l. INPUT: - ``u,v`` -- vertex labels - ``l`` -- label OUTPUT: boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.has_edge(1,2,'a') False """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() if not self._nxg.has_edge(u, v): return False if l is None: return True if self._nxg.is_multigraph(): return any( e.get('weight', None) == l for e in self._nxg.adj[u][v].itervalues()) else: return any(e == l for e in self._nxg.adj[u][v].itervalues()) def has_vertex(self, v): """ True if self has a vertex with label v. INPUT: - ``v`` -- vertex label OUTPUT: boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.has_vertex(0) False """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.has_node(v) def iterator_edges(self, vertices, labels): """ Iterate over the edges incident to a sequence of vertices. Edges are assumed to be undirected. INPUT: - ``vertices`` -- a list of vertex labels - ``labels`` -- boolean OUTPUT: a generator which yields edges, with or without labels depending on the labels parameter. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_edges([],True) <generator object iterator_edges at ...> """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() if labels: for u, v, d in self._nxg.edges_iter(data=True): if u in vertices or v in vertices: yield (u, v, d.get('weight', None)) else: for u, v in self._nxg.edges_iter(): if u in vertices or v in vertices: yield (u, v) def _iterator_in_edges_with_labels(self, vertices): """ Iterate over the incoming edges incident to a sequence of vertices. Special case, only for internal use. EXAMPLE:: sage: g = DiGraph(graphs.PetersenGraph(), implementation="networkx")._backend sage: sorted(list(g.iterator_in_edges([0,1], True))) [(0, 1, None), (1, 0, None), (2, 1, None), (4, 0, None), (5, 0, None), (6, 1, None)] """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() for u, v, d in self._nxg.in_edges_iter(vertices, data=True): yield (u, v, d.get('weight', None)) def iterator_in_edges(self, vertices, labels): """ Iterate over the incoming edges incident to a sequence of vertices. INPUT: - ``vertices`` -- a list of vertex labels - ``labels`` -- boolean OUTPUT: a generator which yields edges, with or without labels depending on the labels parameter. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: i = G.iterator_in_edges([],True) """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() if self._nxg.is_directed(): if labels: return self._iterator_in_edges_with_labels(vertices) else: return self._nxg.in_edges_iter(vertices) else: return self.iterator_edges(vertices, labels) def _iterator_out_edges_with_labels(self, vertices): """ Iterate over the outbound edges incident to a sequence of vertices. Special case, only for internal use. EXAMPLE:: sage: g = DiGraph(graphs.PetersenGraph(), implementation="networkx")._backend sage: sorted(list(g.iterator_out_edges([0,1], True))) [(0, 1, None), (0, 4, None), (0, 5, None), (1, 0, None), (1, 2, None), (1, 6, None)] """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() for u, v, d in self._nxg.out_edges_iter(vertices, data=True): yield (u, v, d.get('weight', None)) def iterator_out_edges(self, vertices, labels): """ Iterate over the outbound edges incident to a sequence of vertices. INPUT: - ``vertices`` -- a list of vertex labels - ``labels`` -- boolean OUTPUT: a generator which yields edges, with or without labels depending on the labels parameter. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: i = G.iterator_out_edges([],True) """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() if self._nxg.is_directed(): if labels: return self._iterator_out_edges_with_labels(vertices) else: return self._nxg.out_edges_iter(vertices) else: return self.iterator_edges(vertices, labels) def iterator_nbrs(self, v): """ Iterate over the vertices adjacent to v. INPUT: - ``v`` -- vertex label OUTPUT: a generator which yields vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertex(0) sage: G.iterator_nbrs(0) <dictionary-keyiterator object at ...> """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.neighbors_iter(v) def iterator_in_nbrs(self, v): """ Iterate over the vertices u such that the edge (u,v) is in self (that is, predecessors of v). INPUT: - ``v`` -- vertex label OUTPUT: a generator which yields vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_in_nbrs(0) Traceback (most recent call last): ... AttributeError: 'MultiGraph' object has no attribute 'predecessors_iter' """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.predecessors_iter(v) def iterator_out_nbrs(self, v): """ Iterate over the vertices u such that the edge (v,u) is in self (that is, successors of v). INPUT: - ``v`` -- vertex label OUTPUT: a generator which yields vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_out_nbrs(0) Traceback (most recent call last): ... AttributeError: 'MultiGraph' object has no attribute 'successors_iter' """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.successors_iter(v) def iterator_verts(self, verts): """ Iterate over the vertices v with labels in verts. INPUT: - ``vertex`` -- vertex labels OUTPUT: a generator which yields vertices TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_verts(0) <generator object bunch_iter at ...> """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.nbunch_iter(verts) def loops(self, new=None): """ Get/set whether or not self allows loops. INPUT: - ``new`` -- can be a boolean (in which case it sets the value) or ``None``, in which case the current value is returned. It is set to ``None`` by default. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.loops(True) sage: G.loops(None) True """ if new is None: return self._loops if new: self._loops = True else: self._loops = False def multiple_edges(self, new=None): """ Get/set whether or not self allows multiple edges. INPUT: - ``new`` -- can be a boolean (in which case it sets the value) or ``None``, in which case the current value is returned. It is set to ``None`` by default. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.multiple_edges(True) sage: G.multiple_edges(None) True """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() from networkx import Graph, MultiGraph, DiGraph, MultiDiGraph if new is None: return self._nxg.is_multigraph() if new == self._nxg.is_multigraph(): return if new: if self._nxg.is_directed(): self._nxg = MultiDiGraph(self._nxg) else: self._nxg = MultiGraph(self._nxg) else: if self._nxg.is_directed(): self._nxg = DiGraph(self._nxg) else: self._nxg = Graph(self._nxg) def name(self, new=None): """ Get/set name of self. INPUT: - ``new`` -- can be a string (in which case it sets the value) or ``None``, in which case the current value is returned. It is set to ``None`` by default. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.name("A NetworkX Graph") sage: G.name(None) 'A NetworkX Graph' """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() if new is None: return self._nxg.name self._nxg.name = new def num_edges(self, directed): """ The number of edges in self INPUT: - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.num_edges(True) 0 sage: G.num_edges(False) 0 """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.size() def num_verts(self): """ The number of vertices in self TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.num_verts() 0 """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() return self._nxg.order() def relabel(self, perm, directed): """ Relabel the vertices of self by a permutation. INPUT: - ``perm`` -- permutation - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.relabel([],False) """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() from networkx import relabel_nodes name = self._nxg.name self._nxg = relabel_nodes(self._nxg, perm) self._nxg.name = name def set_edge_label(self, u, v, l, directed): """ Label the edge (u,v) by l. INPUT: - ``u,v`` -- vertices - ``l`` -- edge label - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.set_edge_label(1,2,'a',True) """ try: assert (not isinstance( self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated))) except AssertionError: self._nxg = self._nxg.mutate() if not self.has_edge(u, v, None): return if self.multiple_edges(None): self._nxg[u][v].clear() self._nxg[u][v][0] = dict(weight=l) if directed is False: self._nxg[v][u].clear() self._nxg[v][u][0] = dict(weight=l) else: self._nxg[u][v]['weight'] = l if directed is False: self._nxg[v][u]['weight'] = l
class NetworkXGraphBackend(GenericGraphBackend): """ A wrapper for NetworkX as the backend of a graph. TESTS:: sage: import sage.graphs.base.graph_backends """ _nxg = None def __init__(self, N=None): """ Initialize the backend with NetworkX graph N. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_edges([],True) <generator object iterator_edges at ...> """ if N is None: import networkx N = networkx.MultiGraph() self._nxg = N if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() def add_edge(self, u, v, l, directed): """ Add an edge (u,v) to self, with label l. If directed is True, this is interpreted as an arc from u to v. INPUT: - ``u,v`` -- vertices - ``l`` -- edge label - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_edge(1,2,'a',True) """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() if u is None: u = self.add_vertex(None) if v is None: v = self.add_vertex(None) if l: self._nxg.add_edge(u, v, weight=l) else: self._nxg.add_edge(u, v) def add_edges(self, edges, directed): """ Add a sequence of edges to self. If directed is True, these are interpreted as arcs. INPUT: - ``edges`` -- list/iterator of edges to be added. - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_edges([],True) """ for e in edges: try: u,v,l = e except ValueError: u,v = e l = None self.add_edge(u,v,l,directed) def add_vertex(self, name): """ Add a labelled vertex to self. INPUT: - ``name``: vertex label OUTPUT: If ``name=None``, the new vertex name is returned. ``None`` otherwise. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertex(0) """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() retval = None if name is None: # then find an integer to use as a key i = 0 while self.has_vertex(i): i=i+1 name = i retval = name self._nxg.add_node(name) return retval def add_vertices(self, vertices): """ Add labelled vertices to self. INPUT: - ``vertices``: iterator of vertex labels. A new label is created, used and returned in the output list for all ``None`` values in ``vertices``. OUTPUT: Generated names of new vertices if there is at least one ``None`` value present in ``vertices``. ``None`` otherwise. EXAMPLES:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertices([1,2,3]) sage: G.add_vertices([4,None,None,5]) [0, 6] """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() vertices = list(vertices) nones = vertices.count(None) vertices = [v for v in vertices if v is not None] self._nxg.add_nodes_from(vertices) new_names = [] i = 0 while nones > 0: while self.has_vertex(i): i += 1 self._nxg.add_node(i) new_names.append(i) nones -= 1 i += 1 return new_names if new_names != [] else None def degree(self, v, directed): """ Returns the total number of vertices incident to v. INPUT: - ``v`` -- a vertex label - ``directed`` -- boolean OUTPUT: degree of v TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertices(range(3)) sage: G.degree(1, False) 0 """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.degree(v) def in_degree(self, v): """ Returns the in-degree of v. INPUT: - ``v`` -- a vertex label OUTPUT: degree of v TESTS:: sage: G = DiGraph(digraphs.Path(5),implementation="networkx") sage: G = G._backend sage: G.in_degree(0) 0 sage: G.in_degree(4) 1 """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.in_degree(v) def out_degree(self, v): """ Returns the out-degree of v. INPUT: - ``v`` -- a vertex label OUTPUT: degree of v TESTS:: sage: G = DiGraph(digraphs.Path(5),implementation="networkx") sage: G = G._backend sage: G.out_degree(0) 1 sage: G.out_degree(4) 0 """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.out_degree(v) def del_edge(self, u, v, l, directed): """ Deletes the edge (u,v) with label l. INPUT: - ``u,v`` -- vertices - ``l`` -- edge label - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.del_edge(1,2,'a',True) """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() import networkx try: if self._nxg.is_multigraph(): for k,d in self._nxg.edge[u][v].iteritems(): if d.get('weight',None) == l: self._nxg.remove_edge(u,v,k) break else: if l is None or self._nxg.edge[u][v].get('weight',None) == l: self._nxg.remove_edge(u,v) except (KeyError, networkx.NetworkXError): pass def del_vertex(self, v): """ Delete a labelled vertex in self. INPUT: - ``v`` -- vertex label TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.del_vertex(0) Traceback (most recent call last): ... NetworkXError: The node 0 is not in the graph. """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() self._nxg.remove_node(v) def del_vertices(self, vertices): """ Delete labelled vertices in self. INPUT: - ``vertices`` -- iterator of vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.del_vertices([1,2,3]) Traceback (most recent call last): ... NetworkXError: The node 1 is not in the graph. """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() for v in vertices: self._nxg.remove_node(v) def get_edge_label(self, u, v): """ Returns the edge label of (u,v). INPUT: - ``u,v`` -- vertex labels OUTPUT: label of (u,v) TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.get_edge_label(1,2) Traceback (most recent call last): ... NetworkXError: Edge (1,2) requested via get_edge_label does not exist. """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() try: E = self._nxg.edge[u][v] except KeyError: from networkx import NetworkXError raise NetworkXError("Edge (%s,%s) requested via get_edge_label does not exist."%(u,v)) if self._nxg.is_multigraph(): return [ e.get('weight',None) for e in E.itervalues() ] else: return E.get('weight',None) def has_edge(self, u, v, l): """ True if self has an edge (u,v) with label l. INPUT: - ``u,v`` -- vertex labels - ``l`` -- label OUTPUT: boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.has_edge(1,2,'a') False """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() if not self._nxg.has_edge(u, v): return False if l is None: return True if self._nxg.is_multigraph(): return any( e.get('weight',None) == l for e in self._nxg.adj[u][v].itervalues() ) else: return any( e == l for e in self._nxg.adj[u][v].itervalues() ) def has_vertex(self, v): """ True if self has a vertex with label v. INPUT: - ``v`` -- vertex label OUTPUT: boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.has_vertex(0) False """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.has_node(v) def iterator_edges(self, vertices, labels): """ Iterate over the edges incident to a sequence of vertices. Edges are assumed to be undirected. INPUT: - ``vertices`` -- a list of vertex labels - ``labels`` -- boolean OUTPUT: a generator which yields edges, with or without labels depending on the labels parameter. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_edges([],True) <generator object iterator_edges at ...> """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() if labels: for u,v,d in self._nxg.edges_iter(data=True): if u in vertices or v in vertices: yield (u,v,d.get('weight',None)) else: for u,v in self._nxg.edges_iter(): if u in vertices or v in vertices: yield (u,v) def _iterator_in_edges_with_labels(self, vertices): """ Iterate over the incoming edges incident to a sequence of vertices. Special case, only for internal use. EXAMPLE:: sage: g = DiGraph(graphs.PetersenGraph(), implementation="networkx")._backend sage: sorted(list(g.iterator_in_edges([0,1], True))) [(0, 1, None), (1, 0, None), (2, 1, None), (4, 0, None), (5, 0, None), (6, 1, None)] """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() for u,v,d in self._nxg.in_edges_iter(vertices,data=True): yield (u,v,d.get('weight',None)) def iterator_in_edges(self, vertices, labels): """ Iterate over the incoming edges incident to a sequence of vertices. INPUT: - ``vertices`` -- a list of vertex labels - ``labels`` -- boolean OUTPUT: a generator which yields edges, with or without labels depending on the labels parameter. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: i = G.iterator_in_edges([],True) """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() if self._nxg.is_directed(): if labels: return self._iterator_in_edges_with_labels(vertices) else: return self._nxg.in_edges_iter(vertices) else: return self.iterator_edges(vertices,labels) def _iterator_out_edges_with_labels(self, vertices): """ Iterate over the outbound edges incident to a sequence of vertices. Special case, only for internal use. EXAMPLE:: sage: g = DiGraph(graphs.PetersenGraph(), implementation="networkx")._backend sage: sorted(list(g.iterator_out_edges([0,1], True))) [(0, 1, None), (0, 4, None), (0, 5, None), (1, 0, None), (1, 2, None), (1, 6, None)] """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() for u,v,d in self._nxg.out_edges_iter(vertices,data=True): yield (u,v,d.get('weight',None)) def iterator_out_edges(self, vertices, labels): """ Iterate over the outbound edges incident to a sequence of vertices. INPUT: - ``vertices`` -- a list of vertex labels - ``labels`` -- boolean OUTPUT: a generator which yields edges, with or without labels depending on the labels parameter. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: i = G.iterator_out_edges([],True) """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() if self._nxg.is_directed(): if labels: return self._iterator_out_edges_with_labels(vertices) else: return self._nxg.out_edges_iter(vertices) else: return self.iterator_edges(vertices,labels) def iterator_nbrs(self, v): """ Iterate over the vertices adjacent to v. INPUT: - ``v`` -- vertex label OUTPUT: a generator which yields vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.add_vertex(0) sage: G.iterator_nbrs(0) <dictionary-keyiterator object at ...> """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.neighbors_iter(v) def iterator_in_nbrs(self, v): """ Iterate over the vertices u such that the edge (u,v) is in self (that is, predecessors of v). INPUT: - ``v`` -- vertex label OUTPUT: a generator which yields vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_in_nbrs(0) Traceback (most recent call last): ... AttributeError: 'MultiGraph' object has no attribute 'predecessors_iter' """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.predecessors_iter(v) def iterator_out_nbrs(self, v): """ Iterate over the vertices u such that the edge (v,u) is in self (that is, successors of v). INPUT: - ``v`` -- vertex label OUTPUT: a generator which yields vertex labels TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_out_nbrs(0) Traceback (most recent call last): ... AttributeError: 'MultiGraph' object has no attribute 'successors_iter' """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.successors_iter(v) def iterator_verts(self, verts): """ Iterate over the vertices v with labels in verts. INPUT: - ``vertex`` -- vertex labels OUTPUT: a generator which yields vertices TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.iterator_verts(0) <generator object bunch_iter at ...> """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.nbunch_iter(verts) def loops(self, new=None): """ Get/set whether or not self allows loops. INPUT: - ``new`` -- can be a boolean (in which case it sets the value) or ``None``, in which case the current value is returned. It is set to ``None`` by default. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.loops(True) sage: G.loops(None) True """ if new is None: return self._loops if new: self._loops = True else: self._loops = False def multiple_edges(self, new=None): """ Get/set whether or not self allows multiple edges. INPUT: - ``new`` -- can be a boolean (in which case it sets the value) or ``None``, in which case the current value is returned. It is set to ``None`` by default. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.multiple_edges(True) sage: G.multiple_edges(None) True """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() from networkx import Graph,MultiGraph,DiGraph,MultiDiGraph if new is None: return self._nxg.is_multigraph() if new == self._nxg.is_multigraph(): return if new: if self._nxg.is_directed(): self._nxg = MultiDiGraph(self._nxg) else: self._nxg = MultiGraph(self._nxg) else: if self._nxg.is_directed(): self._nxg = DiGraph(self._nxg) else: self._nxg = Graph(self._nxg) def name(self, new=None): """ Get/set name of self. INPUT: - ``new`` -- can be a string (in which case it sets the value) or ``None``, in which case the current value is returned. It is set to ``None`` by default. TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.name("A NetworkX Graph") sage: G.name(None) 'A NetworkX Graph' """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() if new is None: return self._nxg.name self._nxg.name = new def num_edges(self, directed): """ The number of edges in self INPUT: - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.num_edges(True) 0 sage: G.num_edges(False) 0 """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.size() def num_verts(self): """ The number of vertices in self TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.num_verts() 0 """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() return self._nxg.order() def relabel(self, perm, directed): """ Relabel the vertices of self by a permutation. INPUT: - ``perm`` -- permutation - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.relabel([],False) """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() from networkx import relabel_nodes name = self._nxg.name self._nxg = relabel_nodes(self._nxg,perm) self._nxg.name = name def set_edge_label(self, u, v, l, directed): """ Label the edge (u,v) by l. INPUT: - ``u,v`` -- vertices - ``l`` -- edge label - ``directed`` -- boolean TESTS:: sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend() sage: G.set_edge_label(1,2,'a',True) """ if isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)): self._nxg = self._nxg.mutate() if not self.has_edge(u, v, None): return if self.multiple_edges(None): self._nxg[u][v].clear() self._nxg[u][v][0] = dict(weight=l) if directed is False: self._nxg[v][u].clear() self._nxg[v][u][0] = dict(weight=l) else: self._nxg[u][v]['weight'] = l if directed is False: self._nxg[v][u]['weight'] = l
def edge_sum(u, v): Guv = Graph(G.subgraph(list(u) + list(v))) Guv.remove_edges_from(G.subgraph(list(u)).edges) Guv.remove_edges_from(G.subgraph(list(v)).edges) return {'weight': Guv.size(weight='weight')}
def pick_random_node(tree: nx.Graph) -> int: """ Picks a random node from the given graph and returns it. """ size = tree.size() return tree.nodes()[random.randint(0, size - 1)]
def spin_glass(graph: nx.Graph, interaction_dist: Callable[[int], List[float]]) -> dimod.BinaryQuadraticModel: int_arr = interaction_dist(graph.size()) bqm = dimod.BinaryQuadraticModel.empty(dimod.SPIN) for u, v in graph.edges(): bqm.add_interaction(u, v, int_arr.pop()) return bqm