ó žÃÒYc@s`dZddlmZmZddlmZddlmZddlm Z ddl Z ddl m Z mZdd d d gZed ƒed eeed„ƒZd eeed„Zd eeed„Zied6ed6ed6ed6Zedƒdd eeed„ƒZedƒdd eeed„ƒZd ded„Zd ded„ZdS(s= Algorithms for calculating min/max spanning trees/forests. iÿÿÿÿ(theappoptheappush(t itemgetter(tcount(tisnanN(t UnionFindtnot_implemented_fortminimum_spanning_edgestmaximum_spanning_edgestminimum_spanning_treetmaximum_spanning_treet multigraphtweightc #stˆƒ}‡‡‡‡fd†‰‡fd†|jƒDƒ}g|D]}|dk rG|^qG}x®|r‡fd†|jƒDƒ}g|D]}|dk r‘|^q‘}x`|D]X\} } } || || kr¶|rð| | | fVn | | fV|j| | ƒq¶q¶WqhWdS(sIterate over edges of a Borůvka's algorithm min/max spanning tree. Parameters ---------- G : NetworkX Graph The edges of `G` must have distinct weights, otherwise the edges may not form a tree. minimum : bool (default: True) Find the minimum (True) or maximum (False) spanning tree. weight : string (default: 'weight') The name of the edge attribute holding the edge weights. keys : bool (default: True) This argument is ignored since this function is not implemented for multigraphs; it exists only for consistency with the other minimum spanning tree functions. data : bool (default: True) Flag for whether to yield edge attribute dicts. If True, yield edges `(u, v, d)`, where `d` is the attribute dict. If False, yield edges `(u, v)`. ignore_nan : bool (default: False) If a NaN is found as an edge weight normally an exception is raised. If `ignore_nan is True` then that edge is ignored instead. cs´ˆr dnd}tdƒ}d}x‰tjˆ|dtƒD]o}|djˆdƒ|}t|ƒr‘ˆruq=nd}t||fƒ‚n||kr=|}|}q=q=W|S(s°Returns the optimum (minimum or maximum) edge on the edge boundary of the given set of nodes. A return value of ``None`` indicates an empty boundary. iiÿÿÿÿtinftdatas$NaN found as an edge weight. Edge %sN(tfloattNonetnxt edge_boundarytTruetgetRt ValueError(t componenttsigntminwttboundarytetwttmsg(tGt ignore_nantminimumR (sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pyt best_edge?s    c3s|]}ˆ|ƒVqdS(N((t.0R(R (sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pys Wsc3s|]}ˆ|ƒVqdS(N((R!R(R (sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pys ksN(Rtto_setsRtunion( RRR tkeysRRtforestt best_edgestedgetutvtd((RR RRR sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pytboruvka_mst_edgess" % % c#s tƒ}|jƒrH|jdtdtƒ}||‡‡fd†}n*|jdtƒ}||‡‡fd†}t|ƒdtdƒƒ}|jƒr6x|D]�\} } } } } || || kr |rú|ré| | | | fVq| | | fVn"|r| | | fVn | | fV|j| | ƒq q Wnfxc|D][\} } } } || || kr=|rz| | | fVn | | fV|j| | ƒq=q=WdS(s–Iterate over edges of a Kruskal's algorithm min/max spanning tree. Parameters ---------- G : NetworkX Graph The graph holding the tree of interest. minimum : bool (default: True) Find the minimum (True) or maximum (False) spanning tree. weight : string (default: 'weight') The name of the edge attribute holding the edge weights. keys : bool (default: True) If `G` is a multigraph, `keys` controls whether edge keys ar yielded. Otherwise `keys` is ignored. data : bool (default: True) Flag for whether to yield edge attribute dicts. If True, yield edges `(u, v, d)`, where `d` is the attribute dict. If False, yield edges `(u, v)`. ignore_nan : bool (default: False) If a NaN is found as an edge weight normally an exception is raised. If `ignore_nan is True` then that edge is ignored instead. R$Rc 3s ˆr dnd}x‡|D]\}}}}|j|dƒ|}t|ƒr„ˆrYqnd}t|||t||ffƒ‚n|||||fVqWdS(Niiÿÿÿÿs$NaN found as an edge weight. Edge %s(RRRtf( tedgesR RR(R)tkR*RR(RR(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pytfilter_nan_edgesœs %c3s”ˆr dnd}x{|D]s\}}}|j|dƒ|}t|ƒr{ˆrVqnd}t||||ffƒ‚n||||fVqWdS(Niiÿÿÿÿs$NaN found as an edge weight. Edge %s(RRR(R-R RR(R)R*RR(RR(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pyR/©s tkeyiN(Rt is_multigraphR-RtsortedRR#(RRR R$RRtsubtreesR-R/RR(R)R.R*((RRsr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pytkruskal_mst_edges{s0       c cs¥|jƒ}t}t}t|ƒ} tƒ} |r9dnd} x_| r | jdƒ} g} | g}|r+xU|j| jƒD]¤\}}x•|jƒD]‡\}}|j|dƒ| }t |ƒrû|rÓq™nd}t || |||ffƒ‚n|| |t | ƒ| |||fƒq™Wq€Wn™x–|j| jƒD]�\}}|j|dƒ| }t |ƒrž|ryq?nd}t || ||ffƒ‚n|| |t | ƒ| ||fƒq?WxÖ| rœ|rô|| ƒ\}}} }}}n|| ƒ\}}} }}||kr!qÇn|rX|rX|rG| |||fVqz| ||fVn"|ro| ||fVn | |fV|j |ƒ| j |ƒ|r+xü|j|jƒD]v\}}||krÌq®nxU|jƒD]G\}}|j|dƒ| }|| |t | ƒ||||fƒqÙWq®WqÇxk|j|jƒD]V\}}||kr]q?n|j|dƒ| }|| |t | ƒ|||fƒq?WqÇWqBWdS(s‘Iterate over edges of Prim's algorithm min/max spanning tree. Parameters ---------- G : NetworkX Graph The graph holding the tree of interest. minimum : bool (default: True) Find the minimum (True) or maximum (False) spanning tree. weight : string (default: 'weight') The name of the edge attribute holding the edge weights. keys : bool (default: True) If `G` is a multigraph, `keys` controls whether edge keys ar yielded. Otherwise `keys` is ignored. data : bool (default: True) Flag for whether to yield edge attribute dicts. If True, yield edges `(u, v, d)`, where `d` is the attribute dict. If False, yield edges `(u, v)`. ignore_nan : bool (default: False) If a NaN is found as an edge weight normally an exception is raised. If `ignore_nan is True` then that edge is ignored instead. iiÿÿÿÿis$NaN found as an edge weight. Edge %sN(R1RRtlistRtpoptadjtitemsRRRtnexttappendtremove(RRR R$RRR1tpushR6tnodestcRR(tfrontiertvisitedR)tkeydictR.R*RRtWt_twtk2td2t new_weight((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pytprim_mst_edgesÍsn       "0  & !       0  tboruvkauborůvkatkruskaltprimtdirectedc Cseyt|}Wn,tk r<dj|ƒ}t|ƒ‚nX||dtd|d|d|d|ƒS(s¨ Generate edges in a minimum spanning forest of an undirected weighted graph. A minimum spanning tree is a subgraph of the graph (a tree) with the minimum sum of edge weights. A spanning forest is a union of the spanning trees for each connected component of the graph. Parameters ---------- G : undirected Graph An undirected graph. If `G` is connected, then the algorithm finds a spanning tree. Otherwise, a spanning forest is found. algorithm : string The algorithm to use when finding a minimum spanning tree. Valid choices are 'kruskal', 'prim', or 'boruvka'. The default is 'kruskal'. weight : string Edge data key to use for weight (default 'weight'). keys : bool Whether to yield edge key in multigraphs in addition to the edge. If `G` is not a multigraph, this is ignored. data : bool, optional If True yield the edge data along with the edge. ignore_nan : bool (default: False) If a NaN is found as an edge weight normally an exception is raised. If `ignore_nan is True` then that edge is ignored instead. Returns ------- edges : iterator An iterator over edges in a maximum spanning tree of `G`. Edges connecting nodes `u` and `v` are represented as tuples: `(u, v, k, d)` or `(u, v, k)` or `(u, v, d)` or `(u, v)` If `G` is a multigraph, `keys` indicates whether the edge key `k` will be reported in the third position in the edge tuple. `data` indicates whether the edge datadict `d` will appear at the end of the edge tuple. If `G` is not a multigraph, the tuples are `(u, v, d)` if `data` is True or `(u, v)` if `data` is False. Examples -------- >>> from networkx.algorithms import tree Find minimum spanning edges by Kruskal's algorithm >>> G = nx.cycle_graph(4) >>> G.add_edge(0, 3, weight=2) >>> mst = tree.minimum_spanning_edges(G, algorithm='kruskal', data=False) >>> edgelist = list(mst) >>> sorted(edgelist) [(0, 1), (1, 2), (2, 3)] Find minimum spanning edges by Prim's algorithm >>> G = nx.cycle_graph(4) >>> G.add_edge(0, 3, weight=2) >>> mst = tree.minimum_spanning_edges(G, algorithm='prim', data=False) >>> edgelist = list(mst) >>> sorted(edgelist) [(0, 1), (1, 2), (2, 3)] Notes ----- For Borůvka's algorithm, each edge must have a weight attribute, and each edge weight must be distinct. For the other algorithms, if the graph edges do not have a weight attribute a default weight of 1 will be used. Modified code from David Eppstein, April 2006 http://www.ics.uci.edu/~eppstein/PADS/ s*{} is not a valid choice for an algorithm.RR R$RR(t ALGORITHMStKeyErrortformatRR(Rt algorithmR R$RRtalgoR((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pyR6sR !c Cseyt|}Wn,tk r<dj|ƒ}t|ƒ‚nX||dtd|d|d|d|ƒS(sÎ Generate edges in a maximum spanning forest of an undirected weighted graph. A maximum spanning tree is a subgraph of the graph (a tree) with the maximum possible sum of edge weights. A spanning forest is a union of the spanning trees for each connected component of the graph. Parameters ---------- G : undirected Graph An undirected graph. If `G` is connected, then the algorithm finds a spanning tree. Otherwise, a spanning forest is found. algorithm : string The algorithm to use when finding a maximum spanning tree. Valid choices are 'kruskal', 'prim', or 'boruvka'. The default is 'kruskal'. weight : string Edge data key to use for weight (default 'weight'). keys : bool Whether to yield edge key in multigraphs in addition to the edge. If `G` is not a multigraph, this is ignored. data : bool, optional If True yield the edge data along with the edge. ignore_nan : bool (default: False) If a NaN is found as an edge weight normally an exception is raised. If `ignore_nan is True` then that edge is ignored instead. Returns ------- edges : iterator An iterator over edges in a maximum spanning tree of `G`. Edges connecting nodes `u` and `v` are represented as tuples: `(u, v, k, d)` or `(u, v, k)` or `(u, v, d)` or `(u, v)` If `G` is a multigraph, `keys` indicates whether the edge key `k` will be reported in the third position in the edge tuple. `data` indicates whether the edge datadict `d` will appear at the end of the edge tuple. If `G` is not a multigraph, the tuples are `(u, v, d)` if `data` is True or `(u, v)` if `data` is False. Examples -------- >>> from networkx.algorithms import tree Find maximum spanning edges by Kruskal's algorithm >>> G = nx.cycle_graph(4) >>> G.add_edge(0, 3, weight=2) >>> mst = tree.maximum_spanning_edges(G, algorithm='kruskal', data=False) >>> edgelist = list(mst) >>> sorted(edgelist) [(0, 1), (0, 3), (1, 2)] Find maximum spanning edges by Prim's algorithm >>> G = nx.cycle_graph(4) >>> G.add_edge(0, 3, weight=2) # assign weight 2 to edge 0-3 >>> mst = tree.maximum_spanning_edges(G, algorithm='prim', data=False) >>> edgelist = list(mst) >>> sorted(edgelist) [(0, 1), (0, 3), (3, 2)] Notes ----- For Borůvka's algorithm, each edge must have a weight attribute, and each edge weight must be distinct. For the other algorithms, if the graph edges do not have a weight attribute a default weight of 1 will be used. Modified code from David Eppstein, April 2006 http://www.ics.uci.edu/~eppstein/PADS/ s*{} is not a valid choice for an algorithm.RR R$RR(RMRNRORtFalse(RRPR R$RRRQR((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pyR’sQ !c Csjt|||dtdtd|ƒ}|jƒ}|jj|jƒ|j|jjƒƒ|j|ƒ|S(sÆReturns a minimum spanning tree or forest on an undirected graph `G`. Parameters ---------- G : undirected graph An undirected graph. If `G` is connected, then the algorithm finds a spanning tree. Otherwise, a spanning forest is found. weight : str Data key to use for edge weights. algorithm : string The algorithm to use when finding a minimum spanning tree. Valid choices are 'kruskal', 'prim', or 'boruvka'. The default is 'kruskal'. ignore_nan : bool (default: False) If a NaN is found as an edge weight normally an exception is raised. If `ignore_nan is True` then that edge is ignored instead. Returns ------- G : NetworkX Graph A minimum spanning tree or forest. Examples -------- >>> G = nx.cycle_graph(4) >>> G.add_edge(0, 3, weight=2) >>> T = nx.minimum_spanning_tree(G) >>> sorted(T.edges(data=True)) [(0, 1, {}), (1, 2, {}), (2, 3, {})] Notes ----- For Borůvka's algorithm, each edge must have a weight attribute, and each edge weight must be distinct. For the other algorithms, if the graph edges do not have a weight attribute a default weight of 1 will be used. There may be more than one tree with the same minimum or maximum weight. See :mod:`networkx.tree.recognition` for more detailed definitions. Isolated nodes with self-loops are in the tree as edgeless isolated nodes. R$RR( RRt fresh_copytgraphtupdatetadd_nodes_fromR=R8tadd_edges_from(RR RPRR-tT((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pyR ís2  c Csvt|||dtdtd|ƒ}t|ƒ}|jƒ}|jj|jƒ|j|jjƒƒ|j |ƒ|S(sÓReturns a maximum spanning tree or forest on an undirected graph `G`. Parameters ---------- G : undirected graph An undirected graph. If `G` is connected, then the algorithm finds a spanning tree. Otherwise, a spanning forest is found. weight : str Data key to use for edge weights. algorithm : string The algorithm to use when finding a minimum spanning tree. Valid choices are 'kruskal', 'prim', or 'boruvka'. The default is 'kruskal'. ignore_nan : bool (default: False) If a NaN is found as an edge weight normally an exception is raised. If `ignore_nan is True` then that edge is ignored instead. Returns ------- G : NetworkX Graph A minimum spanning tree or forest. Examples -------- >>> G = nx.cycle_graph(4) >>> G.add_edge(0, 3, weight=2) >>> T = nx.maximum_spanning_tree(G) >>> sorted(T.edges(data=True)) [(0, 1, {}), (0, 3, {'weight': 2}), (1, 2, {})] Notes ----- For Borůvka's algorithm, each edge must have a weight attribute, and each edge weight must be distinct. For the other algorithms, if the graph edges do not have a weight attribute a default weight of 1 will be used. There may be more than one tree with the same minimum or maximum weight. See :mod:`networkx.tree.recognition` for more detailed definitions. Isolated nodes with self-loops are in the tree as edgeless isolated nodes. R$RR( RRR5RSRTRURVR=R8RW(RR RPRR-RX((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pyR (s4   (t__doc__theapqRRtoperatorRt itertoolsRtmathRtnetworkxRtnetworkx.utilsRRt__all__RRRR+R4RHRMRRR R (((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/tree/mst.pyt s<   ^Q`  Z Y :