ó
 ,µ[c           @   s`  d  Z  d d l m Z m Z d d l m Z d d l m Z d d l m	 Z	 d d l
 Z d d l m Z m Z d d	 d
 d g Z e d  e d e e e d   Z d e e e d  Z d e e e d  Z i e d 6e d 6e d 6e d 6Z e d  d d e e e d   Z e d  d d e e e d   Z d d e d  Z d d e d  Z d S(   s=   
Algorithms for calculating min/max spanning trees/forests.

i’’’’(   t   heappopt   heappush(   t
   itemgetter(   t   count(   t   isnanN(   t	   UnionFindt   not_implemented_fort   minimum_spanning_edgest   maximum_spanning_edgest   minimum_spanning_treet   maximum_spanning_treet
   multigrapht   weightc         #   s  t     }      f d     f d   | j   D } g  | D] } | d k	 rG | ^ qG } x® | r f d   | j   D } g  | D] } | d k	 r | ^ q } x` | D]X \ }	 }
 } | |	 | |
 k r¶ | rš |	 |
 | f Vn |	 |
 f V| j |	 |
  q¶ q¶ Wqh Wd S(   s  Iterate 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.

    c            s“    r d n d } t  d  } d } x t j   |  d t D]o } | d j  d  | } t |  r  ru q= n  d } t | | f   n  | | k  r= | } | } 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.

        i   i’’’’t   inft   datas$   NaN found as an edge weight. Edge %sN(   t   floatt   Nonet   nxt   edge_boundaryt   Truet   getR   t
   ValueError(   t	   componentt   signt   minwtt   boundaryt   et   wtt   msg(   t   Gt
   ignore_nant   minimumR   (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyt	   best_edge?   s    c         3   s   |  ] }   |  Vq d  S(   N(    (   t   .0R   (   R    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pys	   <genexpr>W   s    c         3   s   |  ] }   |  Vq d  S(   N(    (   R!   R   (   R    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pys	   <genexpr>k   s    N(   R   t   to_setsR   t   union(   R   R   R   t   keysR   R   t   forestt
   best_edgest   edget   ut   vt   d(    (   R   R    R   R   R   s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyt   boruvka_mst_edges   s    "%	%c         #   s   t    } |  j   rH |  j d t d t  } | |    f d  } n* |  j d t  } | |    f d  } t |   d t d  } |  j   r6x | D] \ }	 }
 } } } | |
 | | k r  | rś | ré |
 | | | f Vq|
 | | f Vn" | r|
 | | f Vn |
 | f V| j |
 |  q  q  Wnf xc | D][ \ }	 }
 } } | |
 | | k r=| rz|
 | | f Vn |
 | f V| j |
 |  q=q=Wd S(   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$   R   c   	      3   s    r d n d } x |  D]| \ } } } } | j  | d  | } t |  r   rY q n  d } t | | | | | f f   n  | | | | | f Vq Wd  S(   Ni   i’’’’s$   NaN found as an edge weight. Edge %s(   R   R   R   (	   t   edgesR   R   R(   R)   t   kR*   R   R   (   R   R   (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyt   filter_nan_edges   s    "c         3   s    r d n d } x{ |  D]s \ } } } | j  | d  | } t |  r{   rV q n  d } t | | | | f f   n  | | | | f Vq Wd  S(   Ni   i’’’’s$   NaN found as an edge weight. Edge %s(   R   R   R   (   R,   R   R   R(   R)   R*   R   R   (   R   R   (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyR.   ©   s    t   keyi    N(   R   t   is_multigraphR,   R   t   sortedR   R#   (   R   R   R   R$   R   R   t   subtreesR,   R.   R   R(   R)   R-   R*   (    (   R   R   s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyt   kruskal_mst_edges{   s0    	
c      
   c   s„  |  j    } t } t } t |   }	 t   }
 | r9 d n d } x_|	 r |	 j d  } g  } | g } | r+xU|  j | j   D]¤ \ } } x | j   D] \ } } | j | d  | } t	 |  rū | rÓ q n  d } t
 | | | | | f f   n  | | | t |
  | | | | f  q Wq Wn x |  j | j   D] \ } } | j | d  | } t	 |  r| ryq?n  d } t
 | | | | f f   n  | | | t |
  | | | f  q?WxÖ| r| rō| |  \ } } } } } } n | |  \ } } } } } | | k r!qĒn  | rX| rX| rG| | | | f Vqz| | | f Vn" | ro| | | f Vn | | f V| j |  |	 j |  | r+xü |  j | j   D]v \ } } | | k rĢq®n  xU | j   D]G \ } } | j | d  | } | | | t |
  | | | | f  qŁWq®WqĒxk |  j | j   D]V \ } } | | k r]q?n  | j | d  | } | | | t |
  | | | f  q?WqĒWqB Wd S(   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.

    i   i’’’’i    s$   NaN found as an edge weight. Edge %sN(   R0   R   R    t   listR   t   popt   adjt   itemsR   R   R   t   nextt   appendt   remove(   R   R   R   R$   R   R   R0   t   pushR5   t   nodest   cR   R(   t   frontiert   visitedR)   t   keydictR-   R*   R   R   t   Wt   _t   wt   k2t   d2t
   new_weight(    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyt   prim_mst_edgesĶ   sn    			 "0 &	! 0 t   boruvkau   borÅÆvkat   kruskalt   primt   directedc         C   se   y t  | } Wn, t k
 r< d j |  } t |   n X| |  d t d | 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.R   R   R$   R   R   (   t
   ALGORITHMSt   KeyErrort   formatR   R   (   R   t	   algorithmR   R$   R   R   t   algoR   (    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyR   6  s    R!c         C   se   y t  | } Wn, t k
 r< d j |  } t |   n X| |  d t d | 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.R   R   R$   R   R   (   RL   RM   RN   R   t   False(   R   RO   R   R$   R   R   RP   R   (    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyR     s    Q!c      
   C   sj   t  |  | | d t d t d | } |  j   } | j j |  j  | j |  j j    | 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$   R   R   (	   R   R   t	   __class__t   grapht   updatet   add_nodes_fromR<   R7   t   add_edges_from(   R   R   RO   R   R,   t   T(    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyR	   ķ  s    2c      
   C   sv   t  |  | | d t d t d | } t |  } |  j   } | j j |  j  | j |  j j    | 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 maximum 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 maximum 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$   R   R   (
   R   R   R4   RR   RS   RT   RU   R<   R7   RV   (   R   R   RO   R   R,   RW   (    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyR
   (  s    4(   t   __doc__t   heapqR    R   t   operatorR   t	   itertoolsR   t   mathR   t   networkxR   t   networkx.utilsR   R   t   __all__R   RQ   R+   R3   RG   RL   R   R   R	   R
   (    (    (    s;   lib/python2.7/site-packages/networkx/algorithms/tree/mst.pyt   <module>   s<   	^Q`
	Z	Y: