ó
 ,µ[c           @   sr   d  Z  d d l Z d d l m Z d d l m Z d d g Z e d ƒ d d „ ƒ Z	 e d	 ƒ d d
 „ ƒ Z
 d S(   sø   Functions for generating graphs based on the "duplication" method.

These graph generators start with a small initial graph then duplicate
nodes and (partially) duplicate their edges. These functions are
generally inspired by biological networks.

iÿÿÿÿN(   t   py_random_state(   t   NetworkXErrort   partial_duplication_grapht   duplication_divergence_graphi   c   
      C   s  | d k  s0 | d k s0 | d k  s0 | d k rE d } t  | ƒ ‚ n  | |  k r` t  d ƒ ‚ n  t j | ƒ } x£ t | |  ƒ D]’ } | j | ƒ | j d | ƒ } | j ƒ  | k  rÉ | j | | ƒ n  xE t t j	 | | ƒ ƒ D]+ }	 | j ƒ  | k  râ | j | |	 ƒ qâ qâ Wq W| S(   sÊ  Return a random graph using the partial duplication model.

    Parameters
    ----------
    N : int
        The total number of nodes in the final graph.

    n : int
        The number of nodes in the initial clique.

    p : float
        The probability of joining each neighbor of a node to the
        duplicate node. Must be a number in the between zero and one,
        inclusive.

    q : float
        The probability of joining the source node to the duplicate
        node. Must be a number in the between zero and one, inclusive.

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

    Notes
    -----
    A graph of nodes is grown by creating a fully connected graph
    of size `n`. The following procedure is then repeated until
    a total of `N` nodes have been reached.

    1. A random node, *u*, is picked and a new node, *v*, is created.
    2. For each neighbor of *u* an edge from the neighbor to *v* is created
       with probability `p`.
    3. An edge from *u* to *v* is created with probability `q`.

    This algorithm appears in [1].

    This implementation allows the possibility of generating
    disconnected graphs.

    References
    ----------
    .. [1] Knudsen Michael, and Carsten Wiuf. "A Markov chain approach to
           randomly grown graphs." Journal of Applied Mathematics 2008.
           <https://doi.org/10.1155/2008/190836>

    i    i   s3   partial duplication graph must have 0 <= p, q <= 1.s+   partial duplication graph must have n <= N.(
   R   t   nxt   complete_grapht   ranget   add_nodet   randintt   randomt   add_edget   listt   all_neighbors(
   t   Nt   nt   pt   qt   seedt   msgt   Gt   new_nodet   src_nodet   neighbor_node(    (    s>   lib/python2.7/site-packages/networkx/generators/duplication.pyR      s    00i   c   	      C   s#  | d k s | d k  r9 d j  | ƒ } t j | ƒ ‚ n  |  d k  r] d } t j | ƒ ‚ n  t j ƒ  } | j d d ƒ d } x | |  k  r| j t | ƒ ƒ } | j | ƒ t } xB | j	 | ƒ D]1 } | j
 ƒ  | k  rÆ | j | | ƒ t } qÆ qÆ W| s| j | ƒ q‚ | d 7} q‚ W| S(   s  Returns an undirected graph using the duplication-divergence model.

    A graph of `n` nodes is created by duplicating the initial nodes
    and retaining edges incident to the original nodes with a retention
    probability `p`.

    Parameters
    ----------
    n : int
        The desired number of nodes in the graph.
    p : float
        The probability for retaining the edge of the replicated node.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Returns
    -------
    G : Graph

    Raises
    ------
    NetworkXError
        If `p` is not a valid probability.
        If `n` is less than 2.

    Notes
    -----
    This algorithm appears in [1].

    This implementation disallows the possibility of generating
    disconnected graphs.

    References
    ----------
    .. [1] I. Ispolatov, P. L. Krapivsky, A. Yuryev,
       "Duplication-divergence model of protein interaction network",
       Phys. Rev. E, 71, 061911, 2005.

    i   i    s$   NetworkXError p={0} is not in [0,1].i   s$   n must be greater than or equal to 2(   t   formatR   R   t   GraphR
   t   choiceR   R   t   Falset	   neighborsR	   t   Truet   remove_node(	   R   R   R   R   R   t   it   random_nodet   flagt   nbr(    (    s>   lib/python2.7/site-packages/networkx/generators/duplication.pyR   e   s*    *(   t   __doc__t   networkxR   t   networkx.utilsR    t   networkx.exceptionR   t   __all__t   NoneR   R   (    (    (    s>   lib/python2.7/site-packages/networkx/generators/duplication.pyt   <module>   s   	I	