ó žÃÒYc@s•dZddlZddlmZdjdddgƒZdd d d d d gZddd„Z d„Z d„Z d„Z d„Z dd„ZdS(sA Operations on graphs including union, intersection, difference. iÿÿÿÿN(tis_string_likes s%Aric Hagberg sPieter Swart (swart@lanl.gov)sDan Schult(dschult@colgate.edu)tuniontcomposetdisjoint_uniont intersectiont differencetsymmetric_differencec Csæ|jƒ|jƒks*tjdƒ‚n|jƒ}|d kr[d|j|jf}n||_d„}|||dƒ}|||dƒ}t|ƒt|ƒ@r¾tjddƒ‚n|jƒrå|jdtd tƒ}n|jd tƒ}|jƒr|jdtd tƒ}n|jd tƒ}|j |ƒ|j |ƒ|j |ƒ|j |ƒx)|D]!}|j |j |j |ƒqkWx)|D]!}|j |j |j |ƒq—W|j j |j ƒ|j j |j ƒ|S( sØ Return the union of graphs G and H. Graphs G and H must be disjoint, otherwise an exception is raised. Parameters ---------- G,H : graph A NetworkX graph create_using : NetworkX graph Use specified graph for result. Otherwise rename : bool , default=(None, None) Node names of G and H can be changed by specifying the tuple rename=('G-','H-') (for example). Node "u" in G is then renamed "G-u" and "v" in H is renamed "H-v". name : string Specify the name for the union graph Returns ------- U : A union graph with the same type as G. Notes ----- To force a disjoint union with node relabeling, use disjoint_union(G,H) or convert_node_labels_to integers(). Graph, edge, and node attributes are propagated from G and H to the union graph. If a graph attribute is present in both G and H the value from H is used. See Also -------- disjoint_union s+G and H must both be graphs or multigraphs.sunion( %s, %s )cs/ˆdkr|S‡fd†}tj||ƒS(Ncs-t|ƒrˆ|}nˆt|ƒ}|S(N(Rtrepr(txtname(tprefix(sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pytlabelHs  (tNonetnxt relabel_nodes(tgraphR R ((R sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyt add_prefixDs iis*The node sets of G and H are not disjoint.sCUse appropriate rename=(Gprefix,Hprefix)or use disjoint_union(G,H).tkeystdataN(t is_multigraphR t NetworkXErrort fresh_copyR R tsettedgestTruetadd_nodes_fromtadd_edges_fromtnodestupdateR( tGtHtrenameR tRRtG_edgestH_edgestn((sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyRs:&              cCs|tj|ƒ}tj|dt|ƒƒ}t||ƒ}d|j|jf|_|jj|jƒ|jj|jƒ|S(s­ Return the disjoint union of graphs G and H. This algorithm forces distinct integer node labels. Parameters ---------- G,H : graph A NetworkX graph Returns ------- U : A union graph with the same type as G. Notes ----- A new graph is created, of the same class as G. It is recommended that G and H be either both directed or both undirected. The nodes of G are relabeled 0 to len(G)-1, and the nodes of H are relabeled len(G) to len(G)+len(H)-1. Graph, edge, and node attributes are propagated from G and H to the union graph. If a graph attribute is present in both G and H the value from H is used. t first_labelsdisjoint_union( %s, %s )(R tconvert_node_labels_to_integerstlenRR RR(RRtR1tR2R ((sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyRpscCsUtj|ƒ}d|j|jf|_|jƒ|jƒksRtjdƒ‚nt|ƒt|ƒkr|tjdƒ‚n|jƒ|jƒkrô|jƒrµ|jdtƒ}n |jƒ}x|D]%}|j |ŒrÈ|j |ŒqÈqÈWn]|jƒr|jdtƒ}n |jƒ}x-|D]%}|j |Œr(|j |Œq(q(W|S(sºReturn a new graph that contains only the edges that exist in both G and H. The node sets of H and G must be the same. Parameters ---------- G,H : graph A NetworkX graph. G and H must have the same node sets. Returns ------- GH : A new graph with the same type as G. Notes ----- Attributes from the graph, nodes, and edges are not copied to the new graph. If you want a new graph of the intersection of G and H with the attributes (including edge data) from G use remove_nodes_from() as follows >>> G=nx.path_graph(3) >>> H=nx.path_graph(5) >>> R=G.copy() >>> R.remove_nodes_from(n for n in G if n not in H) sIntersection of (%s and %s)s+G and H must both be graphs or multigraphs.s!Node sets of graphs are not equalR( R tcreate_empty_copyR RRRtnumber_of_edgesRRthas_edgetadd_edge(RRR Rte((sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyR“s(      cCsÝ|jƒ|jƒks*tjdƒ‚ntj|ƒ}d|j|jf|_t|ƒt|ƒkr|tjdƒ‚n|jƒr|jdtƒ}n |jƒ}x-|D]%}|j|Œs°|j |Œq°q°W|S(s¸Return a new graph that contains the edges that exist in G but not in H. The node sets of H and G must be the same. Parameters ---------- G,H : graph A NetworkX graph. G and H must have the same node sets. Returns ------- D : A new graph with the same type as G. Notes ----- Attributes from the graph, nodes, and edges are not copied to the new graph. If you want a new graph of the difference of G and H with with the attributes (including edge data) from G use remove_nodes_from() as follows: >>> G = nx.path_graph(3) >>> H = nx.path_graph(5) >>> R = G.copy() >>> R.remove_nodes_from(n for n in G if n in H) s+G and H must both be graphs or multigraphs.sDifference of (%s and %s)sNode sets of graphs not equalR( RR RR)R RRRR+R,(RRR RR-((sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyRËs   cCsn|jƒ|jƒks*tjdƒ‚ntj|ƒ}d|j|jf|_t|ƒt|ƒkr|tjdƒ‚nt|ƒ}t|ƒ}|j|ƒ}|j|ƒ|jƒrÑ|jdt ƒ}n |jƒ}x-|D]%}|j |Œsä|j |ŒqäqäW|jƒr.|jdt ƒ}n |jƒ}x-|D]%}|j |ŒsA|j |ŒqAqAW|S(s™Return new graph with edges that exist in either G or H but not both. The node sets of H and G must be the same. Parameters ---------- G,H : graph A NetworkX graph. G and H must have the same node sets. Returns ------- D : A new graph with the same type as G. Notes ----- Attributes from the graph, nodes, and edges are not copied to the new graph. s+G and H must both be graphs or multigraphs.s#Symmetric difference of (%s and %s)sNode sets of graphs not equalR( RR RR)R RRRRRR+R,(RRR tgnodesthnodesRRR-((sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyRøs.         cCsN|jƒ|jƒks*tjdƒ‚n|dkrOd|j|jf}n|jƒ}||_|j|jdtƒƒ|j|jdtƒƒ|jƒrÄ|j |j dtdtƒƒn|j |j dtƒƒ|jƒr |j |j dtdtƒƒn|j |j dtƒƒ|j j |j ƒ|j j |j ƒ|S(söReturn a new graph of G composed with H. Composition is the simple union of the node sets and edge sets. The node sets of G and H do not need to be disjoint. Parameters ---------- G,H : graph A NetworkX graph name : string Specify name for new graph Returns ------- C: A new graph with the same type as G Notes ----- It is recommended that G and H be either both directed or both undirected. Attributes from H take precedent over attributes from G. For MultiGraphs, the edges are identified by incident nodes AND edge-key. This can cause surprises (i.e., edge `(1, 2)` may or may not be the same in two graphs) if you use MultiGraph without keeping track of edge keys. s+G and H must both be graphs or multigraphs.scompose( %s, %s )RRN( RR RR R RRRRRRRR(RRR R ((sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyR-s"    " "(NN(t__doc__tnetworkxR tnetworkx.utilsRtjoint __author__t__all__R RRRRRR(((sz/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/operators/binary.pyts     ] # 8 - 5