Path: blob/master/src/sage/graphs/base/graph_backends.py
8815 views
"""1Implements various backends for Sage graphs.23"""45#*******************************************************************************6# Copyright (C) 2008 Robert L. Miller <[email protected]>7#8# Distributed under the terms of the GNU General Public License (GPL)9# http://www.gnu.org/licenses/10#*******************************************************************************1112from sage.structure.sage_object import SageObject1314class GenericGraphBackend(SageObject):15"""16A generic wrapper for the backend of a graph. Various graph classes use17extensions of this class. Note, this graph has a number of placeholder18functions, so the doctests are rather silly.1920TESTS::2122sage: import sage.graphs.base.graph_backends2324"""25_loops = False26_multiple_edges = False27_name = ''28def add_edge(self, u, v, l, directed):29"""30Add an edge (u,v) to self, with label l. If directed is True, this is31interpreted as an arc from u to v.3233INPUT::3435- ``u,v`` -- vertices36- ``l`` -- edge label37- ``directed`` -- boolean3839TESTS::4041sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()42sage: G.add_edge(1,2,'a',True)43Traceback (most recent call last):44...45NotImplementedError46"""47raise NotImplementedError()48def add_edges(self, edges, directed):49"""50Add a sequence of edges to self. If directed is True, these are51interpreted as arcs.5253INPUT:5455- ``edges`` -- list/iterator of edges to be added.5657- ``directed`` -- boolean5859TESTS::6061sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()62sage: G.add_edges([],True)63Traceback (most recent call last):64...65NotImplementedError66"""67raise NotImplementedError()6869def add_vertex(self, name):70"""71Add a labelled vertex to self.7273INPUT:7475- ``name`` -- vertex label7677OUTPUT:7879If ``name=None``, the new vertex name is returned, ``None`` otherwise.8081TESTS::8283sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()84sage: G.add_vertex(0)85Traceback (most recent call last):86...87NotImplementedError88"""89raise NotImplementedError()90def add_vertices(self, vertices):91"""92Add labelled vertices to self.9394INPUT:9596- ``vertices`` -- iterator of vertex labels. A new label is created,97used and returned in the output list for all ``None`` values in98``vertices``.99100OUTPUT:101102Generated names of new vertices if there is at least one ``None`` value103present in ``vertices``. ``None`` otherwise.104105EXAMPLES::106107sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()108sage: G.add_vertices([1,2,3])109Traceback (most recent call last):110...111NotImplementedError112"""113raise NotImplementedError()114def degree(self, v, directed):115"""116Returns the total number of vertices incident to v.117118INPUT:119120- ``v`` -- a vertex label121- ``directed`` -- boolean122123OUTPUT:124125degree of v126127TESTS::128129sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()130sage: G.degree(1, False)131Traceback (most recent call last):132...133NotImplementedError134"""135raise NotImplementedError()136def del_edge(self, u, v, l, directed):137"""138Deletes the edge (u,v) with label l.139140INPUT:141142- ``u,v`` -- vertices143- ``l`` -- edge label144- ``directed`` -- boolean145146TESTS::147148sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()149sage: G.del_edge(1,2,'a',True)150Traceback (most recent call last):151...152NotImplementedError153"""154raise NotImplementedError()155def del_vertex(self, v):156"""157Delete a labelled vertex in self.158159INPUT:160161- ``v`` -- vertex label162163TESTS::164165sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()166sage: G.del_vertex(0)167Traceback (most recent call last):168...169NotImplementedError170"""171raise NotImplementedError()172def del_vertices(self, vertices):173"""174Delete labelled vertices in self.175176INPUT:177178- ``vertices`` -- iterator of vertex labels179180TESTS::181182sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()183sage: G.del_vertices([1,2,3])184Traceback (most recent call last):185...186NotImplementedError187"""188raise NotImplementedError()189def get_edge_label(self, u, v):190"""191Returns the edge label of (u,v).192193INPUT:194195- ``u,v`` -- vertex labels196197OUTPUT:198199label of (u,v)200201TESTS::202203sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()204sage: G.get_edge_label(1,2)205Traceback (most recent call last):206...207NotImplementedError208"""209raise NotImplementedError()210def has_edge(self, u, v, l):211"""212True if self has an edge (u,v) with label l.213214INPUT:215216- ``u,v`` -- vertex labels217- ``l`` -- label218219OUTPUT:220221boolean222223TESTS::224225sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()226sage: G.has_edge(1,2,'a')227Traceback (most recent call last):228...229NotImplementedError230"""231raise NotImplementedError()232def has_vertex(self, v):233"""234True if self has a vertex with label v.235236INPUT:237238- ``v`` -- vertex label239240OUTPUT:241boolean242243TESTS::244245sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()246sage: G.has_vertex(0)247Traceback (most recent call last):248...249NotImplementedError250"""251raise NotImplementedError()252def iterator_edges(self, vertices, labels):253"""254Iterate over the edges incident to a sequence of vertices. Edges are255assumed to be undirected.256257INPUT:258259- ``vertices`` -- a list of vertex labels260- ``labels`` -- boolean261262OUTPUT:263264a generator which yields edges, with or without labels265depending on the labels parameter.266267TESTS::268269sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()270sage: G.iterator_edges([],True)271Traceback (most recent call last):272...273NotImplementedError274"""275raise NotImplementedError()276def iterator_in_edges(self, vertices, labels):277"""278Iterate over the incoming edges incident to a sequence of vertices.279280INPUT:281282- ``vertices`` -- a list of vertex labels283- ``labels`` -- boolean284285OUTPUT:286a generator which yields edges, with or without labels287depending on the labels parameter.288289TESTS::290291sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()292sage: G.iterator_in_edges([],True)293Traceback (most recent call last):294...295NotImplementedError296"""297raise NotImplementedError()298def iterator_out_edges(self, vertices, labels):299"""300Iterate over the outbound edges incident to a sequence of vertices.301302INPUT:303304- ``vertices`` -- a list of vertex labels305- ``labels`` -- boolean306307OUTPUT:308309a generator which yields edges, with or without labels310depending on the labels parameter.311312TESTS::313314sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()315sage: G.iterator_out_edges([],True)316Traceback (most recent call last):317...318NotImplementedError319"""320raise NotImplementedError()321def iterator_nbrs(self, v):322"""323Iterate over the vertices adjacent to v.324325INPUT:326327- ``v`` -- vertex label328329OUTPUT:330331a generator which yields vertex labels332333TESTS::334335sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()336sage: G.iterator_nbrs(0)337Traceback (most recent call last):338...339NotImplementedError340"""341raise NotImplementedError()342def iterator_in_nbrs(self, v):343"""344Iterate over the vertices u such that the edge (u,v) is in self345(that is, predecessors of v).346347INPUT:348349- ``v`` -- vertex label350351OUTPUT:352353a generator which yields vertex labels354355TESTS::356357sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()358sage: G.iterator_in_nbrs(0)359Traceback (most recent call last):360...361NotImplementedError362"""363raise NotImplementedError()364def iterator_out_nbrs(self, v):365"""366Iterate over the vertices u such that the edge (v,u) is in self367(that is, successors of v).368369INPUT:370371- ``v`` -- vertex label372373OUTPUT:374375a generator which yields vertex labels376377TESTS::378379sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()380sage: G.iterator_out_nbrs(0)381Traceback (most recent call last):382...383NotImplementedError384"""385raise NotImplementedError()386def iterator_verts(self, verts):387"""388Iterate over the vertices v with labels in verts.389390INPUT:391392- ``vertex`` -- vertex labels393394OUTPUT:395396a generator which yields vertices397398TESTS::399400sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()401sage: G.iterator_verts(0)402Traceback (most recent call last):403...404NotImplementedError405"""406raise NotImplementedError()407408def loops(self, new=None):409"""410Get/set whether or not self allows loops.411412INPUT:413414- ``new`` -- can be a boolean (in which case it sets the value) or415``None``, in which case the current value is returned. It is set to416``None`` by default.417418TESTS::419420sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()421sage: G.loops(True)422Traceback (most recent call last):423...424NotImplementedError425sage: G.loops(None)426Traceback (most recent call last):427...428NotImplementedError429"""430raise NotImplementedError()431def multiple_edges(self, new=None):432"""433Get/set whether or not self allows multiple edges.434435INPUT:436437- ``new`` -- can be a boolean (in which case it sets the value) or438``None``, in which case the current value is returned. It is set to439``None`` by default.440441TESTS::442443sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()444sage: G.multiple_edges(True)445Traceback (most recent call last):446...447NotImplementedError448sage: G.multiple_edges(None)449Traceback (most recent call last):450...451NotImplementedError452"""453raise NotImplementedError()454def name(self, new=None):455"""456Get/set name of self.457458INPUT:459460- ``new`` -- can be a string (in which case it sets the value) or461``None``, in which case the current value is returned. It is set to462``None`` by default.463464TESTS::465466sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()467sage: G.name("A Generic Graph")468Traceback (most recent call last):469...470NotImplementedError471sage: G.name(None)472Traceback (most recent call last):473...474NotImplementedError475"""476raise NotImplementedError()477def num_edges(self, directed):478"""479The number of edges in self480481INPUT:482483- ``directed`` -- boolean484485TESTS::486487sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()488sage: G.num_edges(True)489Traceback (most recent call last):490...491NotImplementedError492sage: G.num_edges(False)493Traceback (most recent call last):494...495NotImplementedError496"""497raise NotImplementedError()498def num_verts(self):499"""500The number of vertices in self501502TESTS::503504sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()505sage: G.num_verts()506Traceback (most recent call last):507...508NotImplementedError509"""510raise NotImplementedError()511def relabel(self, perm, directed):512"""513Relabel the vertices of self by a permutation.514515INPUT:516517- ``perm`` -- permutation518- ``directed`` -- boolean519520TESTS::521522sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()523sage: G.relabel([],False)524Traceback (most recent call last):525...526NotImplementedError527"""528raise NotImplementedError()529def set_edge_label(self, u, v, l, directed):530"""531Label the edge (u,v) by l.532533INPUT:534535- ``u,v`` -- vertices536- ``l`` -- edge label537- ``directed`` -- boolean538539TESTS::540541sage: G = sage.graphs.base.graph_backends.GenericGraphBackend()542sage: G.set_edge_label(1,2,'a',True)543Traceback (most recent call last):544...545NotImplementedError546"""547raise NotImplementedError()548549class NetworkXGraphDeprecated(SageObject):550"""551Class for unpickling old networkx.XGraph formats552553TESTS::554555sage: from sage.graphs.base.graph_backends import NetworkXGraphDeprecated as NXGD556sage: X = NXGD()557doctest:...558559"""560561def __init__(self):562"""563Issue deprecation warnings for the old networkx XGraph formats564565EXAMPLE::566567sage: from sage.graphs.base.graph_backends import NetworkXGraphDeprecated568sage: NetworkXGraphDeprecated()569doctest:...570<class 'sage.graphs.base.graph_backends.NetworkXGraphDeprecated'>571"""572from sage.misc.superseded import deprecation573deprecation(10900, "Your graph object is saved in an old format since networkx "+574"was updated to 1.0.1. You can re-save your graph by typing "+575"graph.save(filename) to make this warning go away.")576577def mutate(self):578"""579Change the old networkx XGraph format into the new one.580581OUTPUT:582583- The networkx.Graph or networkx.MultiGraph corresponding to the584unpickled data.585586EXAMPLES::587588sage: from sage.graphs.base.graph_backends import NetworkXGraphDeprecated as NXGD589sage: X = NXGD()590doctest:...591sage: X.adj = {1:{2:7}, 2:{1:7}, 3:{2:[4,5,6,7]}, 2:{3:[4,5,6,7]}}592sage: X.multiedges = True593sage: G = X.mutate()594sage: G.edges()595[(1, 2), (2, 3)]596sage: G.edges(data=True)597[(1, 2, {'weight': 7}), (2, 3, {4: {}, 5: {}, 6: {}, 7: {}})]598599"""600import networkx601new_adj = {}602603for node1, edges in self.adj.iteritems():604new_adj[node1] = {}605for node2, weights in edges.iteritems():606new_adj[node1][node2] = {}607if weights is not None:608try:609for weight in weights:610new_adj[node1][node2][weight] = {}611except TypeError:612new_adj[node1][node2]['weight'] = weights613614if self.multiedges:615G = networkx.MultiGraph(new_adj)616else:617G = networkx.Graph(new_adj)618619return G620621class NetworkXDiGraphDeprecated(SageObject):622"""623Class for unpickling old networkx.XDiGraph formats624625TESTS::626627sage: import sage.graphs.base.graph_backends628"""629630def __init__(self):631"""632Issue deprecation warnings for the old networkx XDiGraph formats633634EXAMPLE::635636sage: from sage.graphs.base.graph_backends import NetworkXDiGraphDeprecated637sage: NetworkXDiGraphDeprecated()638doctest:...639<class 'sage.graphs.base.graph_backends.NetworkXDiGraphDeprecated'>640"""641from sage.misc.superseded import deprecation642deprecation(10900, "Your digraph object is saved in an old format since networkx "+643"was updated to 1.0.1. You can re-save your digraph by typing "+644"digraph.save(filename) to make this warning go away.")645646def mutate(self):647"""648Change the old networkx XDiGraph format into the new one.649650OUTPUT:651652- The networkx.DiGraph or networkx.MultiDiGraph corresponding to the653unpickled data.654655EXAMPLES::656657sage: from sage.graphs.base.graph_backends import NetworkXDiGraphDeprecated as NXDGD658sage: X = NXDGD()659doctest:...660sage: X.adj = {1:{2:7}, 2:{1:[7,8], 3:[4,5,6,7]}}661sage: X.multiedges = True662sage: G = X.mutate()663sage: G.edges()664[(1, 2), (2, 1), (2, 3)]665sage: G.edges(data=True)666[(1, 2, {'weight': 7}), (2, 1, {8: {}, 7: {}}), (2, 3, {4: {}, 5: {}, 6: {}, 7: {}})]667668"""669import networkx670new_adj = {}671672for node1, edges in self.adj.iteritems():673new_adj[node1] = {}674for node2, weights in edges.iteritems():675new_adj[node1][node2] = {}676if weights is not None:677try:678for weight in weights:679new_adj[node1][node2][weight] = {}680except TypeError:681new_adj[node1][node2]['weight'] = weights682683if self.multiedges:684G = networkx.MultiDiGraph(new_adj)685else:686G = networkx.DiGraph(new_adj)687688return G689690from sage.structure.sage_object import register_unpickle_override691register_unpickle_override('networkx.xgraph','XGraph', NetworkXGraphDeprecated)692register_unpickle_override('networkx.xdigraph','XDiGraph', NetworkXDiGraphDeprecated)693694class NetworkXGraphBackend(GenericGraphBackend):695"""696A wrapper for NetworkX as the backend of a graph.697698TESTS::699700sage: import sage.graphs.base.graph_backends701702"""703704_nxg = None705706def __init__(self, N=None):707"""708Initialize the backend with NetworkX graph N.709710TESTS::711712sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()713sage: G.iterator_edges([],True)714<generator object iterator_edges at ...>715"""716if N is None:717import networkx718N = networkx.MultiGraph()719self._nxg = N720721try:722assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))723except AssertionError:724self._nxg = self._nxg.mutate()725726def add_edge(self, u, v, l, directed):727"""728Add an edge (u,v) to self, with label l. If directed is True, this is729interpreted as an arc from u to v.730731INPUT:732733- ``u,v`` -- vertices734- ``l`` -- edge label735- ``directed`` -- boolean736737TESTS::738739sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()740sage: G.add_edge(1,2,'a',True)741"""742743try:744assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))745except AssertionError:746self._nxg = self._nxg.mutate()747748if u is None: u = self.add_vertex(None)749if v is None: v = self.add_vertex(None)750751if l:752self._nxg.add_edge(u, v, weight=l)753else:754self._nxg.add_edge(u, v)755756def add_edges(self, edges, directed):757"""758Add a sequence of edges to self. If directed is True, these are759interpreted as arcs.760761INPUT:762763- ``edges`` -- list/iterator of edges to be added.764- ``directed`` -- boolean765766TESTS::767768sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()769sage: G.add_edges([],True)770"""771for e in edges:772try:773u,v,l = e774except ValueError:775u,v = e776l = None777self.add_edge(u,v,l,directed)778779def add_vertex(self, name):780"""781Add a labelled vertex to self.782783INPUT:784785- ``name``: vertex label786787OUTPUT:788789If ``name=None``, the new vertex name is returned. ``None`` otherwise.790791TESTS::792793sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()794sage: G.add_vertex(0)795"""796try:797assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))798except AssertionError:799self._nxg = self._nxg.mutate()800801retval = None802if name is None: # then find an integer to use as a key803i = 0804while self.has_vertex(i):805i=i+1806name = i807retval = name808809self._nxg.add_node(name)810811return retval812813def add_vertices(self, vertices):814"""815Add labelled vertices to self.816817INPUT:818819- ``vertices``: iterator of vertex labels. A new label is created, used and returned in820the output list for all ``None`` values in ``vertices``.821822OUTPUT:823824Generated names of new vertices if there is at least one ``None`` value825present in ``vertices``. ``None`` otherwise.826827EXAMPLES::828829sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()830sage: G.add_vertices([1,2,3])831sage: G.add_vertices([4,None,None,5])832[0, 6]833"""834try:835assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))836except AssertionError:837self._nxg = self._nxg.mutate()838839vertices = list(vertices)840nones = vertices.count(None)841vertices = filter(lambda v: v is not None, vertices)842self._nxg.add_nodes_from(vertices)843844new_names = []845i = 0846while nones > 0:847while self.has_vertex(i):848i += 1849self._nxg.add_node(i)850new_names.append(i)851852nones -= 1853i += 1854855return new_names if new_names != [] else None856857def degree(self, v, directed):858"""859Returns the total number of vertices incident to v.860861INPUT:862863- ``v`` -- a vertex label864- ``directed`` -- boolean865866OUTPUT:867868degree of v869870TESTS::871872sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()873sage: G.add_vertices(range(3))874sage: G.degree(1, False)8750876"""877try:878assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))879except AssertionError:880self._nxg = self._nxg.mutate()881882return self._nxg.degree(v)883884def del_edge(self, u, v, l, directed):885"""886Deletes the edge (u,v) with label l.887888INPUT:889890- ``u,v`` -- vertices891- ``l`` -- edge label892- ``directed`` -- boolean893894TESTS::895896sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()897sage: G.del_edge(1,2,'a',True)898"""899try:900assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))901except AssertionError:902self._nxg = self._nxg.mutate()903904import networkx905try:906if self._nxg.is_multigraph():907for k,d in self._nxg.edge[u][v].iteritems():908if d.get('weight',None) == l:909self._nxg.remove_edge(u,v,k)910break911else:912if l is None or self._nxg.edge[u][v].get('weight',None) == l:913self._nxg.remove_edge(u,v)914except (KeyError, networkx.NetworkXError):915pass916917918def del_vertex(self, v):919"""920Delete a labelled vertex in self.921922INPUT:923924- ``v`` -- vertex label925926TESTS::927928sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()929sage: G.del_vertex(0)930Traceback (most recent call last):931...932NetworkXError: The node 0 is not in the graph.933"""934try:935assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))936except AssertionError:937self._nxg = self._nxg.mutate()938939self._nxg.remove_node(v)940941def del_vertices(self, vertices):942"""943Delete labelled vertices in self.944945INPUT:946947- ``vertices`` -- iterator of vertex labels948949TESTS::950951sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()952sage: G.del_vertices([1,2,3])953Traceback (most recent call last):954...955NetworkXError: The node 1 is not in the graph.956"""957try:958assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))959except AssertionError:960self._nxg = self._nxg.mutate()961962for v in vertices:963self._nxg.remove_node(v)964965def get_edge_label(self, u, v):966"""967Returns the edge label of (u,v).968969INPUT:970971- ``u,v`` -- vertex labels972973OUTPUT:974label of (u,v)975976TESTS::977978sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()979sage: G.get_edge_label(1,2)980Traceback (most recent call last):981...982NetworkXError: Edge (1,2) requested via get_edge_label does not exist.983"""984try:985assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))986except AssertionError:987self._nxg = self._nxg.mutate()988989try:990E = self._nxg.edge[u][v]991except KeyError:992from networkx import NetworkXError993raise NetworkXError("Edge (%s,%s) requested via get_edge_label does not exist."%(u,v))994995if self._nxg.is_multigraph():996return [ e.get('weight',None) for e in E.itervalues() ]997else:998return E.get('weight',None)9991000def has_edge(self, u, v, l):1001"""1002True if self has an edge (u,v) with label l.10031004INPUT:10051006- ``u,v`` -- vertex labels1007- ``l`` -- label10081009OUTPUT:1010boolean10111012TESTS::10131014sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1015sage: G.has_edge(1,2,'a')1016False1017"""1018try:1019assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1020except AssertionError:1021self._nxg = self._nxg.mutate()10221023if not self._nxg.has_edge(u, v):1024return False1025if l is None:1026return True1027if self._nxg.is_multigraph():1028return any( e.get('weight',None) == l for e in self._nxg.adj[u][v].itervalues() )1029else:1030return any( e == l for e in self._nxg.adj[u][v].itervalues() )10311032def has_vertex(self, v):1033"""1034True if self has a vertex with label v.10351036INPUT:10371038- ``v`` -- vertex label10391040OUTPUT:1041boolean10421043TESTS::10441045sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1046sage: G.has_vertex(0)1047False1048"""1049try:1050assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1051except AssertionError:1052self._nxg = self._nxg.mutate()10531054return self._nxg.has_node(v)10551056def iterator_edges(self, vertices, labels):1057"""1058Iterate over the edges incident to a sequence of vertices. Edges are1059assumed to be undirected.10601061INPUT:10621063- ``vertices`` -- a list of vertex labels1064- ``labels`` -- boolean10651066OUTPUT:1067a generator which yields edges, with or without labels1068depending on the labels parameter.10691070TESTS::10711072sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1073sage: G.iterator_edges([],True)1074<generator object iterator_edges at ...>1075"""1076try:1077assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1078except AssertionError:1079self._nxg = self._nxg.mutate()10801081if labels:1082for u,v,d in self._nxg.edges_iter(data=True):1083if u in vertices or v in vertices:1084yield (u,v,d.get('weight',None))1085else:1086for u,v in self._nxg.edges_iter():1087if u in vertices or v in vertices:1088yield (u,v)10891090def _iterator_in_edges_with_labels(self, vertices):1091"""1092Iterate over the incoming edges incident to a sequence of vertices.1093Special case, only for internal use.10941095EXAMPLE::10961097sage: g = DiGraph(graphs.PetersenGraph(), implementation="networkx")._backend1098sage: sorted(list(g.iterator_in_edges([0,1], True)))1099[(0, 1, None), (1, 0, None), (2, 1, None), (4, 0, None), (5, 0, None), (6, 1, None)]1100"""1101try:1102assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1103except AssertionError:1104self._nxg = self._nxg.mutate()11051106for u,v,d in self._nxg.in_edges_iter(vertices,data=True):1107yield (u,v,d.get('weight',None))11081109def iterator_in_edges(self, vertices, labels):1110"""1111Iterate over the incoming edges incident to a sequence of vertices.11121113INPUT:11141115- ``vertices`` -- a list of vertex labels1116- ``labels`` -- boolean11171118OUTPUT:1119a generator which yields edges, with or without labels1120depending on the labels parameter.11211122TESTS::11231124sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1125sage: i = G.iterator_in_edges([],True)1126"""1127try:1128assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1129except AssertionError:1130self._nxg = self._nxg.mutate()11311132if self._nxg.is_directed():1133if labels:1134return self._iterator_in_edges_with_labels(vertices)1135else:1136return self._nxg.in_edges_iter(vertices)1137else:1138return self.iterator_edges(vertices,labels)11391140def _iterator_out_edges_with_labels(self, vertices):1141"""1142Iterate over the outbound edges incident to a sequence of vertices.1143Special case, only for internal use.11441145EXAMPLE::11461147sage: g = DiGraph(graphs.PetersenGraph(), implementation="networkx")._backend1148sage: sorted(list(g.iterator_out_edges([0,1], True)))1149[(0, 1, None), (0, 4, None), (0, 5, None), (1, 0, None), (1, 2, None), (1, 6, None)]1150"""1151try:1152assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1153except AssertionError:1154self._nxg = self._nxg.mutate()11551156for u,v,d in self._nxg.out_edges_iter(vertices,data=True):1157yield (u,v,d.get('weight',None))11581159def iterator_out_edges(self, vertices, labels):1160"""1161Iterate over the outbound edges incident to a sequence of vertices.11621163INPUT:11641165- ``vertices`` -- a list of vertex labels1166- ``labels`` -- boolean11671168OUTPUT:1169a generator which yields edges, with or without labels1170depending on the labels parameter.11711172TESTS::11731174sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1175sage: i = G.iterator_out_edges([],True)1176"""1177try:1178assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1179except AssertionError:1180self._nxg = self._nxg.mutate()11811182if self._nxg.is_directed():1183if labels:1184return self._iterator_out_edges_with_labels(vertices)1185else:1186return self._nxg.out_edges_iter(vertices)1187else:1188return self.iterator_edges(vertices,labels)11891190def iterator_nbrs(self, v):1191"""1192Iterate over the vertices adjacent to v.11931194INPUT:11951196- ``v`` -- vertex label11971198OUTPUT:1199a generator which yields vertex labels12001201TESTS::12021203sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1204sage: G.add_vertex(0)1205sage: G.iterator_nbrs(0)1206<dictionary-keyiterator object at ...>1207"""1208try:1209assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1210except AssertionError:1211self._nxg = self._nxg.mutate()12121213return self._nxg.neighbors_iter(v)12141215def iterator_in_nbrs(self, v):1216"""1217Iterate over the vertices u such that the edge (u,v) is in self1218(that is, predecessors of v).12191220INPUT:12211222- ``v`` -- vertex label12231224OUTPUT:1225a generator which yields vertex labels12261227TESTS::12281229sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1230sage: G.iterator_in_nbrs(0)1231Traceback (most recent call last):1232...1233AttributeError: 'MultiGraph' object has no attribute 'predecessors_iter'1234"""1235try:1236assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1237except AssertionError:1238self._nxg = self._nxg.mutate()12391240return self._nxg.predecessors_iter(v)12411242def iterator_out_nbrs(self, v):1243"""1244Iterate over the vertices u such that the edge (v,u) is in self1245(that is, successors of v).12461247INPUT:12481249- ``v`` -- vertex label12501251OUTPUT:1252a generator which yields vertex labels12531254TESTS::12551256sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1257sage: G.iterator_out_nbrs(0)1258Traceback (most recent call last):1259...1260AttributeError: 'MultiGraph' object has no attribute 'successors_iter'1261"""1262try:1263assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1264except AssertionError:1265self._nxg = self._nxg.mutate()12661267return self._nxg.successors_iter(v)12681269def iterator_verts(self, verts):1270"""1271Iterate over the vertices v with labels in verts.12721273INPUT:12741275- ``vertex`` -- vertex labels12761277OUTPUT:1278a generator which yields vertices12791280TESTS::12811282sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1283sage: G.iterator_verts(0)1284<generator object bunch_iter at ...>1285"""1286try:1287assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1288except AssertionError:1289self._nxg = self._nxg.mutate()12901291return self._nxg.nbunch_iter(verts)12921293def loops(self, new=None):1294"""1295Get/set whether or not self allows loops.12961297INPUT:12981299- ``new`` -- can be a boolean (in which case it sets the value) or1300``None``, in which case the current value is returned. It is set to1301``None`` by default.13021303TESTS::13041305sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1306sage: G.loops(True)1307sage: G.loops(None)1308True1309"""1310if new is None:1311return self._loops1312if new:1313self._loops = True1314else:1315self._loops = False13161317def multiple_edges(self, new=None):1318"""1319Get/set whether or not self allows multiple edges.13201321INPUT:13221323- ``new`` -- can be a boolean (in which case it sets the value) or1324``None``, in which case the current value is returned. It is set to1325``None`` by default.13261327TESTS::13281329sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1330sage: G.multiple_edges(True)1331sage: G.multiple_edges(None)1332True1333"""1334try:1335assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1336except AssertionError:1337self._nxg = self._nxg.mutate()13381339from networkx import Graph,MultiGraph,DiGraph,MultiDiGraph1340if new is None:1341return self._nxg.is_multigraph()1342if new == self._nxg.is_multigraph():1343return1344if new:1345if self._nxg.is_directed():1346self._nxg = MultiDiGraph(self._nxg)1347else:1348self._nxg = MultiGraph(self._nxg)1349else:1350if self._nxg.is_directed():1351self._nxg = DiGraph(self._nxg)1352else:1353self._nxg = Graph(self._nxg)13541355def name(self, new=None):1356"""1357Get/set name of self.13581359INPUT:13601361- ``new`` -- can be a string (in which case it sets the value) or1362``None``, in which case the current value is returned. It is set to1363``None`` by default.13641365TESTS::13661367sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1368sage: G.name("A NetworkX Graph")1369sage: G.name(None)1370'A NetworkX Graph'1371"""1372try:1373assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1374except AssertionError:1375self._nxg = self._nxg.mutate()13761377if new is None:1378return self._nxg.name1379self._nxg.name = new13801381def num_edges(self, directed):1382"""1383The number of edges in self13841385INPUT:13861387- ``directed`` -- boolean13881389TESTS::13901391sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1392sage: G.num_edges(True)139301394sage: G.num_edges(False)139501396"""1397try:1398assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1399except AssertionError:1400self._nxg = self._nxg.mutate()14011402return self._nxg.size()14031404def num_verts(self):1405"""1406The number of vertices in self14071408TESTS::14091410sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1411sage: G.num_verts()141201413"""1414try:1415assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1416except AssertionError:1417self._nxg = self._nxg.mutate()14181419return self._nxg.order()14201421def relabel(self, perm, directed):1422"""1423Relabel the vertices of self by a permutation.14241425INPUT:14261427- ``perm`` -- permutation1428- ``directed`` -- boolean14291430TESTS::14311432sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1433sage: G.relabel([],False)1434"""1435try:1436assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1437except AssertionError:1438self._nxg = self._nxg.mutate()14391440from networkx import relabel_nodes1441name = self._nxg.name1442self._nxg = relabel_nodes(self._nxg,perm)1443self._nxg.name = name14441445def set_edge_label(self, u, v, l, directed):1446"""1447Label the edge (u,v) by l.14481449INPUT:14501451- ``u,v`` -- vertices1452- ``l`` -- edge label1453- ``directed`` -- boolean14541455TESTS::14561457sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()1458sage: G.set_edge_label(1,2,'a',True)1459"""1460try:1461assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))1462except AssertionError:1463self._nxg = self._nxg.mutate()14641465if not self.has_edge(u, v, None):1466return1467if self.multiple_edges(None):1468self._nxg[u][v].clear()1469self._nxg[u][v][0] = dict(weight=l)1470if directed is False:1471self._nxg[v][u].clear()1472self._nxg[v][u][0] = dict(weight=l)1473else:1474self._nxg[u][v]['weight'] = l1475if directed is False:1476self._nxg[v][u]['weight'] = l147714781479