ó
 ,µ[c        	   @   sB  d  Z  d d l m Z d d l m Z d d l Z d d l m Z d d l	 m
 Z
 d d l	 m Z d d l	 m Z d	 d
 d d d g Z e d ƒ d d d d „ ƒ Z e d ƒ d d d „ ƒ Z e d ƒ d d d „ ƒ Z e d ƒ d d d d d d d d „ ƒ Z e d ƒ e e d d „ ƒ Z e d ƒ e d d „ ƒ Z d S(   sd   
Generators for some directed graphs, including growing network (GN) graphs and
scale-free graphs.

iÿÿÿÿ(   t   division(   t   CounterN(   t   empty_graph(   t   discrete_sequence(   t   weighted_choice(   t   py_random_statet   gn_grapht	   gnc_grapht	   gnr_grapht   random_k_out_grapht   scale_free_graphi   c   
      C   s   t  d | d t j ƒ} | j ƒ  s6 t j d ƒ ‚ n  | d	 k rN d „  } n  |  d k r^ | S| j d d ƒ d d g } x t d |  ƒ D]n } g  | D] } | | ƒ ^ q— } t d d | d | ƒd }	 | j | |	 ƒ | j	 d ƒ | |	 c d 7<qŠ W| S(
   sC  Return the growing network (GN) digraph with `n` nodes.

    The GN graph is built by adding nodes one at a time with a link to one
    previously added node.  The target node for the link is chosen with
    probability based on degree.  The default attachment kernel is a linear
    function of the degree of a node.

    The graph is always a (directed) tree.

    Parameters
    ----------
    n : int
        The number of nodes for the generated graph.
    kernel : function
        The attachment kernel.
    create_using : NetworkX graph constructor, optional (default DiGraph)
        Graph type to create. If graph instance, then cleared before populated.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Examples
    --------
    To create the undirected GN graph, use the :meth:`~DiGraph.to_directed`
    method::

    >>> D = nx.gn_graph(10)  # the GN graph
    >>> G = D.to_undirected()  # the undirected version

    To specify an attachment kernel, use the `kernel` keyword argument::

    >>> D = nx.gn_graph(10, kernel=lambda x: x ** 1.5)  # A_k = k^1.5

    References
    ----------
    .. [1] P. L. Krapivsky and S. Redner,
           Organization of Growing Random Networks,
           Phys. Rev. E, 63, 066123, 2001.
    i   t   defaults+   create_using must indicate a Directed Graphc         S   s   |  S(   N(    (   t   x(    (    s;   lib/python2.7/site-packages/networkx/generators/directed.pyt   kernelM   s    i    i   t   distributiont   seedN(
   R   t   nxt   DiGrapht   is_directedt   NetworkXErrort   Nonet   add_edget   rangeR   t   append(
   t   nR   t   create_usingR   t   Gt   dst   sourcet   dt   distt   target(    (    s;   lib/python2.7/site-packages/networkx/generators/directed.pyR      s     )c         C   s¼   t  d | d t j ƒ} | j ƒ  s6 t j d ƒ ‚ n  |  d k rF | Sxo t d |  ƒ D]^ } | j d | ƒ } | j ƒ  | k  r¤ | d k r¤ t | j	 | ƒ ƒ } n  | j
 | | ƒ qV W| S(   sì  Return the growing network with redirection (GNR) digraph with `n`
    nodes and redirection probability `p`.

    The GNR graph is built by adding nodes one at a time with a link to one
    previously added node.  The previous target node is chosen uniformly at
    random.  With probabiliy `p` the link is instead "redirected" to the
    successor node of the target.

    The graph is always a (directed) tree.

    Parameters
    ----------
    n : int
        The number of nodes for the generated graph.
    p : float
        The redirection probability.
    create_using : NetworkX graph constructor, optional (default DiGraph)
        Graph type to create. If graph instance, then cleared before populated.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Examples
    --------
    To create the undirected GNR graph, use the :meth:`~DiGraph.to_directed`
    method::

    >>> D = nx.gnr_graph(10, 0.5)  # the GNR graph
    >>> G = D.to_undirected()  # the undirected version

    References
    ----------
    .. [1] P. L. Krapivsky and S. Redner,
           Organization of Growing Random Networks,
           Phys. Rev. E, 63, 066123, 2001.
    i   R   s+   create_using must indicate a Directed Graphi    (   R   R   R   R   R   R   t	   randranget   randomt   nextt
   successorsR   (   R   t   pR   R   R   R   R   (    (    s;   lib/python2.7/site-packages/networkx/generators/directed.pyR   `   s    &i   c         C   s°   t  d | d t j ƒ} | j ƒ  s6 t j d ƒ ‚ n  |  d k rF | Sxc t d |  ƒ D]R } | j d | ƒ } x' | j | ƒ D] } | j | | ƒ q~ W| j | | ƒ qV W| S(   s#  Return the growing network with copying (GNC) digraph with `n` nodes.

    The GNC graph is built by adding nodes one at a time with a link to one
    previously added node (chosen uniformly at random) and to all of that
    node's successors.

    Parameters
    ----------
    n : int
        The number of nodes for the generated graph.
    create_using : NetworkX graph constructor, optional (default DiGraph)
        Graph type to create. If graph instance, then cleared before populated.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    References
    ----------
    .. [1] P. L. Krapivsky and S. Redner,
           Network Growth by Copying,
           Phys. Rev. E, 71, 036118, 2005k.},
    i   R   s+   create_using must indicate a Directed Graphi    (	   R   R   R   R   R   R   R    R#   R   (   R   R   R   R   R   R   t   succ(    (    s;   lib/python2.7/site-packages/networkx/generators/directed.pyR   •   s    i   g=
×£p=Ú?gHáz®Gá?gš™™™™™©?gš™™™™™É?i    c            s*  ‡  f d †  } | d k s+ t | d ƒ r_ t j d | d t j ƒ}	 |	 j d d d g ƒ n | }	 |	 j ƒ  oz |	 j ƒ  s t j d ƒ ‚ n  | d k rª t	 d	 ƒ ‚ n  | d k rÅ t	 d
 ƒ ‚ n  | d k rà t	 d
 ƒ ‚ n  t
 | | | d ƒ d k rt	 d ƒ ‚ n  |	 j ƒ  }
 x
t |	 ƒ |  k  r%|
 | t |	 ƒ } |
 | t |	 ƒ } ˆ  j ƒ  } | | k  r˜t |	 ƒ } | |	 |	 j ƒ  | | ƒ } np | | | k  rá| |	 |	 j ƒ  | | ƒ } | |	 |	 j ƒ  | | ƒ } n' | |	 |	 j ƒ  | | ƒ } t |	 ƒ } |	 j | | ƒ |
 d 7}
 qW|	 S(   sŒ  Returns a scale-free directed graph.

    Parameters
    ----------
    n : integer
        Number of nodes in graph
    alpha : float
        Probability for adding a new node connected to an existing node
        chosen randomly according to the in-degree distribution.
    beta : float
        Probability for adding an edge between two existing nodes.
        One existing node is chosen randomly according the in-degree
        distribution and the other chosen randomly according to the out-degree
        distribution.
    gamma : float
        Probability for adding a new node connected to an existing node
        chosen randomly according to the out-degree distribution.
    delta_in : float
        Bias for choosing ndoes from in-degree distribution.
    delta_out : float
        Bias for choosing ndoes from out-degree distribution.
    create_using : NetworkX graph constructor, optional
        The default is a MultiDiGraph 3-cycle.
        If a graph instance, use it without clearing first.
        If a graph constructor, call it to construct an empty graph.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Examples
    --------
    Create a scale-free graph on one hundred nodes::

    >>> G = nx.scale_free_graph(100)

    Notes
    -----
    The sum of `alpha`, `beta`, and `gamma` must be 1.

    References
    ----------
    .. [1] B. BollobÃ¡s, C. Borgs, J. Chayes, and O. Riordan,
           Directed scale-free graphs,
           Proceedings of the fourteenth annual ACM-SIAM Symposium on
           Discrete Algorithms, 132--139, 2003.
    c            sO   d } ˆ  j  ƒ  } x6 | D]. \ } } | | | | 7} | | k  r Pq q W| S(   Ng        (   R!   (   R   R   t   deltat   psumt   cumsumt   rR   R   (   R   (    s;   lib/python2.7/site-packages/networkx/generators/directed.pyt   _choose_nodeî   s    t   _adji   R   i    i   i   s%   MultiDiGraph required in create_usings   alpha must be >= 0.s   beta must be >= 0.g      ð?g•Ö&è.>s   alpha+beta+gamma must equal 1.N(   i    i   (   i   i   (   i   i    (   R   t   hasattrR   R   t   MultiDiGrapht   add_edges_fromR   t   is_multigraphR   t
   ValueErrort   abst   number_of_edgest   lenR!   t	   in_degreet
   out_degreeR   (   R   t   alphat   betat   gammat   delta_int	   delta_outR   R   R*   R   R2   t   psum_int   psum_outR)   t   vt   w(    (   R   s;   lib/python2.7/site-packages/networkx/generators/directed.pyR
   ¼   s>    2
i   c   	         s¤   | r* t  j ƒ  } ‡  ‡ ‡ f d †  } n! t  j ƒ  } ‡  ‡ ‡ f d †  } t  j |  | ƒ } t | ƒ } x4 | D], ‰ | j ‡ f d †  | ˆ | ƒ Dƒ ƒ qp W| S(   s_  Returns a random `k`-out graph with uniform attachment.

    A random `k`-out graph with uniform attachment is a multidigraph
    generated by the following algorithm. For each node *u*, choose
    `k` nodes *v* uniformly at random (with replacement). Add a
    directed edge joining *u* to *v*.

    Parameters
    ----------
    n : int
        The number of nodes in the returned graph.

    k : int
        The out-degree of each node in the returned graph.

    self_loops : bool
        If True, self-loops are allowed when generating the graph.

    with_replacement : bool
        If True, neighbors are chosen with replacement and the
        returned graph will be a directed multigraph. Otherwise,
        neighbors are chosen without replacement and the returned graph
        will be a directed graph.

    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Returns
    -------
    NetworkX graph
        A `k`-out-regular directed graph generated according to the
        above algorithm. It will be a multigraph if and only if
        `with_replacement` is True.

    Raises
    ------
    ValueError
        If `with_replacement` is False and `k` is greater than
        `n`.

    See also
    --------
    random_k_out_graph

    Notes
    -----
    The return digraph or multidigraph may not be strongly connected, or
    even weakly connected.

    If `with_replacement` is True, this function is similar to
    :func:`random_k_out_graph`, if that function had parameter `alpha`
    set to positive infinity.

    c            s3   ˆ s ˆ  |  h ‰  n  ‡  ‡ f d †  t  ˆ ƒ Dƒ S(   Nc         3   s$   |  ] } ˆ j  t ˆ  ƒ ƒ Vq d  S(   N(   t   choicet   list(   t   .0t   i(   t   nodesR   (    s;   lib/python2.7/site-packages/networkx/generators/directed.pys	   <genexpr>h  s    (   R   (   R=   RC   (   t   kR   t
   self_loops(   RC   s;   lib/python2.7/site-packages/networkx/generators/directed.pyt   samplee  s    c            s&   ˆ s | |  h } n  ˆ j  | ˆ  ƒ S(   N(   RF   (   R=   RC   (   RD   R   RE   (    s;   lib/python2.7/site-packages/networkx/generators/directed.pyRF   m  s    c         3   s   |  ] } ˆ  | f Vq d  S(   N(    (   RA   R=   (   t   u(    s;   lib/python2.7/site-packages/networkx/generators/directed.pys	   <genexpr>u  s    (   R   R-   R   R   t   setR.   (	   R   RD   RE   t   with_replacementR   R   RF   R   RC   (    (   RD   R   RE   RG   s;   lib/python2.7/site-packages/networkx/generators/directed.pyt   random_uniform_k_out_graph(  s    :*c            s  ˆ  d k  r t  d ƒ ‚ n  t j |  d t j ƒ} t ‡  f d †  | Dƒ ƒ } x± t | |  ƒ D]Ÿ } | j g  | j ƒ  D] \ } }	 |	 | k  ry | ^ qy ƒ }
 | sÀ t i | |
 |
 6ƒ } n	 t ƒ  } t | | d | ƒ} | j	 |
 | ƒ | | c d 7<q` W| S(   sK  Returns a random `k`-out graph with preferential attachment.

    A random `k`-out graph with preferential attachment is a
    multidigraph generated by the following algorithm.

    1. Begin with an empty digraph, and initially set each node to have
       weight `alpha`.
    2. Choose a node `u` with out-degree less than `k` uniformly at
       random.
    3. Choose a node `v` from with probability proportional to its
       weight.
    4. Add a directed edge from `u` to `v`, and increase the weight
       of `v` by one.
    5. If each node has out-degree `k`, halt, otherwise repeat from
       step 2.

    For more information on this model of random graph, see [1].

    Parameters
    ----------
    n : int
        The number of nodes in the returned graph.

    k : int
        The out-degree of each node in the returned graph.

    alpha : float
        A positive :class:`float` representing the initial weight of
        each vertex. A higher number means that in step 3 above, nodes
        will be chosen more like a true uniformly random sample, and a
        lower number means that nodes are more likely to be chosen as
        their in-degree increases. If this parameter is not positive, a
        :exc:`ValueError` is raised.

    self_loops : bool
        If True, self-loops are allowed when generating the graph.

    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Returns
    -------
    :class:`~networkx.classes.MultiDiGraph`
        A `k`-out-regular multidigraph generated according to the above
        algorithm.

    Raises
    ------
    ValueError
        If `alpha` is not positive.

    Notes
    -----
    The returned multidigraph may not be strongly connected, or even
    weakly connected.

    References
    ----------
    [1]: Peterson, Nicholas R., and Boris Pittel.
         "Distance between two random `k`-out digraphs, with and without
         preferential attachment."
         arXiv preprint arXiv:1311.5961 (2013).
         <https://arxiv.org/abs/1311.5961>

    i    s   alpha must be positiveR   c            s   i  |  ] } ˆ  | “ q S(    (    (   RA   R=   (   R6   (    s;   lib/python2.7/site-packages/networkx/generators/directed.pys
   <dictcomp>À  s   	 R   i   (
   R0   R   R   R-   R   R   R?   R5   R   R   (   R   RD   R6   RE   R   R   t   weightsRB   R=   R   RG   t
   adjustment(    (   R6   s;   lib/python2.7/site-packages/networkx/generators/directed.pyR	   y  s    D:	(   t   __doc__t
   __future__R    t   collectionsR   t   networkxR   t   networkx.generators.classicR   t   networkx.utilsR   R   R   t   __all__R   R   R   R   R
   t   TrueRJ   R	   (    (    (    s;   lib/python2.7/site-packages/networkx/generators/directed.pyt   <module>   s.   		@	4	&	j	O	