
    wg                        d Z ddlZddl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mZmZmZ dd	lmZ g d
Z ed       ej&                  dd      d#ddd              Z ed       ej&                  dd      d#ddd              ZeZeZ ed       ej&                  dd      d$ddd              Z ed       ej&                  dd      d#ddd              Z ed       ej&                  dd      d$ddd              Z ed       ej&                  dd      d$ddd              Z ed       ej&                  dd      d%ddd              Z ed       ej&                  dd      d$ddd              Zd Z ed       ej&                  dd      d&ddd              Z ed       ej&                  dd      	 d&ddd              Z  ed       ej&                  dd      d$ddd              Z! ed       ej&                  dd      d$ddd              Z" ed       ej&                  dd      d$ddd              Z# ed       ej&                  dd      d$ddd              Z$ ed       ej&                  dd      d'ddd              Z% ed       ej&                  d       d'd!              Z& ed       ej&                  dd      	 d&ddd"              Z'y)(z 
Generators for random graphs.

    N)defaultdict)py_random_state   )check_create_using   )complete_graphempty_graph
path_graph
star_graph)degree_sequence_tree)fast_gnp_random_graphgnp_random_graphdense_gnm_random_graphgnm_random_grapherdos_renyi_graphbinomial_graphnewman_watts_strogatz_graphwatts_strogatz_graphconnected_watts_strogatz_graphrandom_regular_graphbarabasi_albert_graphdual_barabasi_albert_graphextended_barabasi_albert_graphpowerlaw_cluster_graphrandom_lobsterrandom_shell_graphrandom_powerlaw_treerandom_powerlaw_tree_sequencerandom_kernel_graphT)graphsreturns_graphcreate_usingc                   |rt         j                  nt         j                  }t        ||d|      }|dk  s|dk\  rt        j                  | ||||      S t        | |      }t        j                  d|z
        }|rd}d}	|| k  rvt        j                  d|j                         z
        }
|	dz   t        |
|z        z   }	|	|k\  r|| k  r|	|z
  }	|dz   }|	|k\  r|| k  r|| k  r|j                  |	|       || k  rvd}d}	|| k  rvt        j                  d|j                         z
        }
|	dz   t        |
|z        z   }	|	|k\  r|| k  r|	|z
  }	|dz   }|	|k\  r|| k  r|| k  r|j                  ||	       || k  rv|S )	u  Returns a $G_{n,p}$ random graph, also known as an Erdős-Rényi graph or
    a binomial graph.

    Parameters
    ----------
    n : int
        The number of nodes.
    p : float
        Probability for edge creation.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    directed : bool, optional (default=False)
        If True, this function returns a directed graph.
    create_using : Graph constructor, optional (default=nx.Graph or nx.DiGraph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph types are not supported and raise a ``NetworkXError``.
        By default NetworkX Graph or DiGraph are used depending on `directed`.

    Notes
    -----
    The $G_{n,p}$ graph algorithm chooses each of the $[n (n - 1)] / 2$
    (undirected) or $n (n - 1)$ (directed) possible edges with probability $p$.

    This algorithm [1]_ runs in $O(n + m)$ time, where `m` is the expected number of
    edges, which equals $p n (n - 1) / 2$. This should be faster than
    :func:`gnp_random_graph` when $p$ is small and the expected number of edges
    is small (that is, the graph is sparse).

    See Also
    --------
    gnp_random_graph

    References
    ----------
    .. [1] Vladimir Batagelj and Ulrik Brandes,
       "Efficient generation of large random networks",
       Phys. Rev. E, 71, 036113, 2005.
    Fdirected
multigraphdefaultr   r   )seedr&   r#   r"   g      ?)nxDiGraphGraphr   r   r	   mathlograndomintadd_edge)npr)   r&   r#   r(   Glpvwlrs              f/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/generators/random_graphs.pyr   r   (   s   T %bjj"((G%xE7L 	Ava""qth\
 	
 	AL1A	#'	B!e#-.BABG$Aq&QUEE q&QU 1u

1a  !e 	
A
A
a%XXcDKKM)*ECRL 1fQAAAA 1fQ q5JJq! a% H    c                   |rt         j                  nt         j                  }t        ||d|      }|dk\  rt	        | |      S t        j
                  | |      }|dk  r|S |rt        j                  nt        j                  } |t        |       d      D ]%  }|j                         |k  s |j                  |  ' |S )u  Returns a $G_{n,p}$ random graph, also known as an Erdős-Rényi graph
    or a binomial graph.

    The $G_{n,p}$ model chooses each of the possible edges with probability $p$.

    Parameters
    ----------
    n : int
        The number of nodes.
    p : float
        Probability for edge creation.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    directed : bool, optional (default=False)
        If True, this function returns a directed graph.
    create_using : Graph constructor, optional (default=nx.Graph or nx.DiGraph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph types are not supported and raise a ``NetworkXError``.
        By default NetworkX Graph or DiGraph are used depending on `directed`.

    See Also
    --------
    fast_gnp_random_graph

    Notes
    -----
    This algorithm [2]_ runs in $O(n^2)$ time.  For sparse graphs (that is, for
    small values of $p$), :func:`fast_gnp_random_graph` is a faster algorithm.

    :func:`binomial_graph` and :func:`erdos_renyi_graph` are
    aliases for :func:`gnp_random_graph`.

    >>> nx.binomial_graph is nx.gnp_random_graph
    True
    >>> nx.erdos_renyi_graph is nx.gnp_random_graph
    True

    References
    ----------
    .. [1] P. Erdős and A. Rényi, On Random Graphs, Publ. Math. 6, 290 (1959).
    .. [2] E. N. Gilbert, Random Graphs, Ann. Math. Stat., 30, 1141 (1959).
    Fr%   r   r"   r   r   )r+   r,   r-   r   r   r	   	itertoolspermutationscombinationsranger0   r2   )	r3   r4   r)   r&   r#   r(   r5   edgetooles	            r:   r   r   y   s    \ %bjj"((G%xE7L 	Aval;;
q|4AAv)1y%%y7M7MHeAh" ;;=1AJJN Hr;   c                2   t        |dd      }| | dz
  z  dz  }||k\  rt        | |      S t        | |      }| dk(  r|S d}d}d}d}		 |j                  ||z
        ||	z
  k  r|j	                  ||       |	dz  }	|	|k(  r|S |dz  }|dz  }|| k(  r
|dz  }|dz   }R)ao  Returns a $G_{n,m}$ random graph.

    In the $G_{n,m}$ model, a graph is chosen uniformly at random from the set
    of all graphs with $n$ nodes and $m$ edges.

    This algorithm should be faster than :func:`gnm_random_graph` for dense
    graphs.

    Parameters
    ----------
    n : int
        The number of nodes.
    m : int
        The number of edges.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    See Also
    --------
    gnm_random_graph

    Notes
    -----
    Algorithm by Keith M. Briggs Mar 31, 2006.
    Inspired by Knuth's Algorithm S (Selection sampling technique),
    in section 3.4.2 of [1]_.

    References
    ----------
    .. [1] Donald E. Knuth, The Art of Computer Programming,
        Volume 2/Seminumerical algorithms, Third Edition, Addison-Wesley, 1997.
    Fr&   r'   r   r   r   )r   r   r	   	randranger2   )
r3   mr)   r#   mmaxr5   ur7   tks
             r:   r   r      s    N &lUuULA;!DDya..A|$AAv	A	A	A	A
>>$(#a!e+JJq!FAAv	Q	Q6FAAA r;   c                   |rt         j                  nt         j                  }t        ||d|      }| dk(  rt        j                  | |      S |r| | dz
  z  n
| | dz
  z  dz  }||k\  rt        | |      S t        j                  | |      }t        |      }d}	|	|k  rW|j                  |      }
|j                  |      }|
|k(  s|j                  |
|      r?|j                  |
|       |	dz   }	|	|k  rW|S )a  Returns a $G_{n,m}$ random graph.

    In the $G_{n,m}$ model, a graph is chosen uniformly at random from the set
    of all graphs with $n$ nodes and $m$ edges.

    This algorithm should be faster than :func:`dense_gnm_random_graph` for
    sparse graphs.

    Parameters
    ----------
    n : int
        The number of nodes.
    m : int
        The number of edges.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    directed : bool, optional (default=False)
        If True return a directed graph
    create_using : Graph constructor, optional (default=nx.Graph or nx.DiGraph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph types are not supported and raise a ``NetworkXError``.
        By default NetworkX Graph or DiGraph are used depending on `directed`.

    See also
    --------
    dense_gnm_random_graph

    Fr%   r   r"   g       @r   )
r+   r,   r-   r   r	   r   listchoicehas_edger2   )r3   rF   r)   r&   r#   r(   	max_edgesr5   nlist
edge_countrH   r7   s               r:   r   r      s    @ %bjj"((G%xE7L 	Av~~al;;'QUQ!a%[3->II~al;;
q|4AGEJ
q.KKKK6QZZ1%JJq!#aJ q. Hr;      c                   t        |dd      }|| kD  rt        j                  d      || k(  rt        j                  | |      S t	        | |      }t        |j                               }|}t        d|dz  dz         D ]>  }||d |d| z   }	t        t        |            D ]  }
|j                  ||
   |	|
           @ t        |j                               }|D ]  \  }}|j                         |k  s|j                  |      }||k(  s|j                  ||      rB|j                  |      }|j                  |      | dz
  k\  rk||k(  r/|j                  ||      rB|j                  ||        |S )u  Returns a Newman–Watts–Strogatz small-world graph.

    Parameters
    ----------
    n : int
        The number of nodes.
    k : int
        Each node is joined with its `k` nearest neighbors in a ring
        topology.
    p : float
        The probability of adding a new edge for each edge.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Notes
    -----
    First create a ring over $n$ nodes [1]_.  Then each node in the ring is
    connected with its $k$ nearest neighbors (or $k - 1$ neighbors if $k$
    is odd).  Then shortcuts are created by adding new edges as follows: for
    each edge $(u, v)$ in the underlying "$n$-ring with $k$ nearest
    neighbors" with probability $p$ add a new edge $(u, w)$ with
    randomly-chosen existing node $w$.  In contrast with
    :func:`watts_strogatz_graph`, no edges are removed.

    See Also
    --------
    watts_strogatz_graph

    References
    ----------
    .. [1] M. E. J. Newman and D. J. Watts,
       Renormalization group analysis of the small-world network model,
       Physics Letters A, 263, 341, 1999.
       https://doi.org/10.1016/S0375-9601(99)00757-4
    FrD   z"k>=n, choose smaller k or larger nr   r   Nr   )r   r+   NetworkXErrorr   r	   rL   nodesr@   lenr2   edgesr0   rM   rN   degree)r3   rJ   r4   r)   r#   r5   rP   fromvjtovirB   rH   r7   r8   s                  r:   r   r   8  sr   T &lUuUL1uCDD 	Av  L11A|$AOEE1a1fqj! )ABi%!*$s5z" 	)AJJuQxQ(	)) 	QWWYA 
!1;;=1E"A q&AJJq!,KK&88A;!a%' q&AJJq!,
 

1a 
! Hr;   c                   t        |dd      }|| kD  rt        j                  d      || k(  rt        j                  | |      }|S t        j                  | |      }t        t        |             }t        d|dz  dz         D ](  }||d |d| z   }|j                  t        ||             * t        d|dz  dz         D ]  }||d |d| z   }t        ||      D ]  \  }	}
|j                         |k  s|j                  |      }||	k(  s|j                  |	|      rB|j                  |      }|j                  |	      | dz
  k\  rk||	k(  r/|j                  |	|      rB|j                  |	|
       |j                  |	|         |S )	u:  Returns a Watts–Strogatz small-world graph.

    Parameters
    ----------
    n : int
        The number of nodes
    k : int
        Each node is joined with its `k` nearest neighbors in a ring
        topology.
    p : float
        The probability of rewiring each edge
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    See Also
    --------
    newman_watts_strogatz_graph
    connected_watts_strogatz_graph

    Notes
    -----
    First create a ring over $n$ nodes [1]_.  Then each node in the ring is joined
    to its $k$ nearest neighbors (or $k - 1$ neighbors if $k$ is odd).
    Then shortcuts are created by replacing some edges as follows: for each
    edge $(u, v)$ in the underlying "$n$-ring with $k$ nearest neighbors"
    with probability $p$ replace it with a new edge $(u, w)$ with uniformly
    random choice of existing node $w$.

    In contrast with :func:`newman_watts_strogatz_graph`, the random rewiring
    does not increase the number of edges. The rewired graph is not guaranteed
    to be connected as in :func:`connected_watts_strogatz_graph`.

    References
    ----------
    .. [1] Duncan J. Watts and Steven H. Strogatz,
       Collective dynamics of small-world networks,
       Nature, 393, pp. 440--442, 1998.
    FrD   z!k>n, choose smaller k or larger nr"   r   r   Nr   )r   r+   rT   r   r	   rL   r@   add_edges_fromzipr0   rM   rN   rX   remove_edger2   )r3   rJ   r4   r)   r#   r5   rU   rZ   targetsrH   r7   r8   s               r:   r   r     s   Z &lUuUL1uBCC 	Ava.
q|4AqNE1a1fqj! .)eAaj(	UG,-. 1a1fqj! %)eAaj(w' 
	%DAq{{}q KK&1f

1a 0E*Axx{a!e+ 1f

1a 0
 MM!Q'JJq!$
	%% Hr;      c                    t        |      D ]+  }t        | ||||      }t        j                  |      s)|c S  t        j                  d      )u  Returns a connected Watts–Strogatz small-world graph.

    Attempts to generate a connected graph by repeated generation of
    Watts–Strogatz small-world graphs.  An exception is raised if the maximum
    number of tries is exceeded.

    Parameters
    ----------
    n : int
        The number of nodes
    k : int
        Each node is joined with its `k` nearest neighbors in a ring
        topology.
    p : float
        The probability of rewiring each edge
    tries : int
        Number of attempts to generate a connected graph.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Notes
    -----
    First create a ring over $n$ nodes [1]_.  Then each node in the ring is joined
    to its $k$ nearest neighbors (or $k - 1$ neighbors if $k$ is odd).
    Then shortcuts are created by replacing some edges as follows: for each
    edge $(u, v)$ in the underlying "$n$-ring with $k$ nearest neighbors"
    with probability $p$ replace it with a new edge $(u, w)$ with uniformly
    random choice of existing node $w$.
    The entire process is repeated until a connected graph results.

    See Also
    --------
    newman_watts_strogatz_graph
    watts_strogatz_graph

    References
    ----------
    .. [1] Duncan J. Watts and Steven H. Strogatz,
       Collective dynamics of small-world networks,
       Nature, 393, pp. 440--442, 1998.
    r"   z Maximum number of tries exceeded)r@   r   r+   is_connectedrT   )r3   rJ   r4   triesr)   r#   r\   r5   s           r:   r   r     sO    ` 5\  Aq$\J??1H	
 

=
>>r;   c                H    t        |dd      } z  dz  dk7  rt        j                  d      d cxk  rk  sn t        j                  d      t        j                  |      } dk(  r|S d  fd	} |       }|
 |       }|
|j	                  |       |S )
a)  Returns a random $d$-regular graph on $n$ nodes.

    A regular graph is a graph where each node has the same number of neighbors.

    The resulting graph has no self-loops or parallel edges.

    Parameters
    ----------
    d : int
      The degree of each node.
    n : integer
      The number of nodes. The value of $n \times d$ must be even.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Notes
    -----
    The nodes are numbered from $0$ to $n - 1$.

    Kim and Vu's paper [2]_ shows that this algorithm samples in an
    asymptotically uniform way from the space of random graphs when
    $d = O(n^{1 / 3 - \epsilon})$.

    Raises
    ------

    NetworkXError
        If $n \times d$ is odd or $d$ is greater than or equal to $n$.

    References
    ----------
    .. [1] A. Steger and N. Wormald,
       Generating random regular graphs quickly,
       Probability and Computing 8 (1999), 377-396, 1999.
       https://doi.org/10.1017/S0963548399003867

    .. [2] Jeong Han Kim and Van H. Vu,
       Generating random regular graphs,
       Proceedings of the thirty-fifth ACM symposium on Theory of computing,
       San Diego, CA, USA, pp 213--222, 2003.
       http://portal.acm.org/citation.cfm?id=780542.780576
    FrD   r   r   zn * d must be evenz+the 0 <= d < n inequality must be satisfiedr"   c                 X    |sy|D ]"  }|D ]  }||k(  r ||kD  r||}}||f| vs  y $ y)NTF )rW   potential_edgess1s2s       r:   	_suitablez'random_regular_graph.<locals>._suitableH  sX     ! 	 B% 
  87B85(
 	  r;   c                     t               } t        t                    
z  }|rt        d       }j	                  |       t        |      }t        ||      D ]G  \  }}||kD  r||}}||k7  r||f| vr| j                  ||f       .||xx   dz  cc<   ||xx   dz  cc<   I  	| |      sy |j                         D cg c]  \  }}t        |      D ]  }|  }}}}|r| S c c}}}w )Nc                       y)Nr   rh   rh   r;   r:   <lambda>z=random_regular_graph.<locals>._try_creation.<locals>.<lambda>b  s    r;   r   )	setrL   r@   r   shuffleiterr_   additems)rW   stubsri   stubiterrj   rk   node	potential_rl   dr3   r)   s            r:   _try_creationz+random_regular_graph.<locals>._try_creation[  s    U1X"))4OLLE{Hh1 -B7B8"b!6IIr2h'#B'1,'#B'1,'- UO4 (7'<'<'> #D)y)  E ! * s   C&)r   r+   rT   r	   r^   )rz   r3   r)   r#   r5   r{   rW   rl   s   ```    @r:   r   r     s    b &lUuUL	A{a344:A:LMM
q|4AAv&@ OE
- -UHr;   c                     t               }t        |      |k  r1|j                  |       }|j                  |       t        |      |k  r1|S )zReturn m unique elements from seq.

    This differs from random.sample which can return repeated
    elements if seq holds repeated elements.

    Note: rng is a random.Random or numpy.random.RandomState instance.
    )rp   rV   rM   rs   )seqrF   rngra   xs        r:   _random_subsetr     sD     eG
g,
JJsOA g,
 Nr;   c                j   t        |dd      }|dk  s|| k\  rt        j                  d| d|        |t        ||      }nHt	        |      |k  st	        |      | kD  rt        j                  d| d|  d      |j                         }|j                         D  cg c]  \  } }t        |      D ]  }|   }}} }t	        |      }	|	 k  r]t        |||      }
|j                  t        |	g|z  |
             |j                  |
       |j                  |	g|z         |	dz  }	|	| k  r]|S c c}}} w )	ue  Returns a random graph using Barabási–Albert preferential attachment

    A graph of $n$ nodes is grown by attaching new nodes each with $m$
    edges that are preferentially attached to existing nodes with high degree.

    Parameters
    ----------
    n : int
        Number of nodes
    m : int
        Number of edges to attach from a new node to existing nodes
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    initial_graph : Graph or None (default)
        Initial network for Barabási–Albert algorithm.
        It should be a connected graph for most use cases.
        A copy of `initial_graph` is used.
        If None, starts from a star graph on (m+1) nodes.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Returns
    -------
    G : Graph

    Raises
    ------
    NetworkXError
        If `m` does not satisfy ``1 <= m < n``, or
        the initial graph number of nodes m0 does not satisfy ``m <= m0 <= n``.

    References
    ----------
    .. [1] A. L. Barabási and R. Albert "Emergence of scaling in
       random networks", Science 286, pp 509-512, 1999.
    FrD   r   u;   Barabási–Albert network must have m >= 1 and m < n, m = , n = u1   Barabási–Albert initial graph needs between m=z and n= nodes)r   r+   rT   r   rV   copyrX   r@   r   r^   r_   extend)r3   rF   r)   initial_graphr#   r5   rz   ry   repeated_nodessourcera   s              r:   r   r     sV   R &lUuUL1uQI!FSTRUV
 	
 q,'}!S%7!%;""CA3gaSPVW    %&HHJAADAqaA1aAaANAVF
1* !D9	fX\734g&vhl+! 1* H Bs   D.c                   t        |dd      }|dk  s|| k\  rt        j                  d| d|        |dk  s|| k\  rt        j                  d| d|        |dk  s|dkD  rt        j                  d|       |dk(  rt        | |||	      S |dk(  rt        | |||	      S |t	        t        ||      |      }n\t        |      t        ||      k  st        |      | kD  r&t        j                  d
t        ||       d|  d      |j                         }t        |      }|j                         D  	
cg c]  \  } }	t        |	      D ]  }
|   }}	} }
t        |      }| k  ru|j                         |k  r|}n|}t        |||      }|j                  t        |g|z  |             |j                  |       |j                  |g|z         |dz  }|| k  ru|S c c}
}	} w )u  Returns a random graph using dual Barabási–Albert preferential attachment

    A graph of $n$ nodes is grown by attaching new nodes each with either $m_1$
    edges (with probability $p$) or $m_2$ edges (with probability $1-p$) that
    are preferentially attached to existing nodes with high degree.

    Parameters
    ----------
    n : int
        Number of nodes
    m1 : int
        Number of edges to link each new node to existing nodes with probability $p$
    m2 : int
        Number of edges to link each new node to existing nodes with probability $1-p$
    p : float
        The probability of attaching $m_1$ edges (as opposed to $m_2$ edges)
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    initial_graph : Graph or None (default)
        Initial network for Barabási–Albert algorithm.
        A copy of `initial_graph` is used.
        It should be connected for most use cases.
        If None, starts from an star graph on max(m1, m2) + 1 nodes.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Returns
    -------
    G : Graph

    Raises
    ------
    NetworkXError
        If `m1` and `m2` do not satisfy ``1 <= m1,m2 < n``, or
        `p` does not satisfy ``0 <= p <= 1``, or
        the initial graph number of nodes m0 does not satisfy m1, m2 <= m0 <= n.

    References
    ----------
    .. [1] N. Moshiri "The dual-Barabasi-Albert model", arXiv:1810.10538.
    FrD   r   u;   Dual Barabási–Albert must have m1 >= 1 and m1 < n, m1 = r   u;   Dual Barabási–Albert must have m2 >= 1 and m2 < n, m2 = r   u;   Dual Barabási–Albert network must have 0 <= p <= 1, p = r"   uA   Barabási–Albert initial graph must have between max(m1, m2) = z	 and n = r   )r   r+   rT   r   r   maxrV   r   rL   rX   r@   r0   r   r^   r_   r   )r3   m1m2r4   r)   r   r#   r5   ra   rz   ry   r   r   rF   s                 r:   r   r     s   ` &lUuUL	AvqI"VTUSVW
 	
 
AvqI"VTUSVW
 	
 	1uAI!M
 	

 	Av$QD|LL	
a$QD|LLs2r{L1}B+s=/AA/E""!!$RYqcA    1gG$%HHJAADAqaA1aAaANAVF
1*;;=1AA !D9	fX\734g&vhl+!! 1*" H) Bs   7Gc                   t        |dd      }|dk  s|| k\  rd| d|  }t        j                  |      ||z   dk\  rd| d| }t        j                  |      t        ||      }g }|j	                  t        |             |}	|	| k  r[|j                         }
t        |      dz
  }t        |      |z  dz  }|
|k  r)|j                         ||z
  k  r|j                         D cg c]  \  }}||k  s| }}}t        |      D ]  }|j                  |      }t        ||         }|j                  |       |j                  |D cg c]	  }||vs| c}      }|j                  ||       |j                  |       |j                  |       |j                  |      |k(  r|j                  |       |j                  |      |k(  s||v s|j                  |        n||
cxk  r	||z   k  rn n||j                         cxk  r|k  ron nk|j                         D cg c]  \  }}d	|cxk  r|k  sn n| }}}t        |      D ]*  }|j                  |      }t        ||         }|j                  |      }|j                  |       |j                  |D cg c]	  }||vs| c}      }|j                  ||       |j                  ||       |j                  |       |j                  |       |j                  |      d	k(  r||v r|j                  |       ||v r(|j                  |      |k(  s|j                  |       |j                  |      dk(  s|j                  |       - nZt!        |||      }|j#                  t%        |	g|z  |             |j	                  |       |j	                  |	g|dz   z         |	dz  }	|	| k  r[|S c c}}w c c}w c c}}w c c}w )
uu  Returns an extended Barabási–Albert model graph.

    An extended Barabási–Albert model graph is a random graph constructed
    using preferential attachment. The extended model allows new edges,
    rewired edges or new nodes. Based on the probabilities $p$ and $q$
    with $p + q < 1$, the growing behavior of the graph is determined as:

    1) With $p$ probability, $m$ new edges are added to the graph,
    starting from randomly chosen existing nodes and attached preferentially at the
    other end.

    2) With $q$ probability, $m$ existing edges are rewired
    by randomly choosing an edge and rewiring one end to a preferentially chosen node.

    3) With $(1 - p - q)$ probability, $m$ new nodes are added to the graph
    with edges attached preferentially.

    When $p = q = 0$, the model behaves just like the Barabási–Alber model.

    Parameters
    ----------
    n : int
        Number of nodes
    m : int
        Number of edges with which a new node attaches to existing nodes
    p : float
        Probability value for adding an edge between existing nodes. p + q < 1
    q : float
        Probability value of rewiring of existing edges. p + q < 1
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Returns
    -------
    G : Graph

    Raises
    ------
    NetworkXError
        If `m` does not satisfy ``1 <= m < n`` or ``1 >= p + q``

    References
    ----------
    .. [1] Albert, R., & Barabási, A. L. (2000)
       Topology of evolving networks: local events and universality
       Physical review letters, 85(24), 5234.
    FrD   r   z7Extended Barabasi-Albert network needs m>=1 and m<n, m=z, n=z5Extended Barabasi-Albert network needs p + q <= 1, p=z, q=r   r   )r   r+   rT   r	   r   r@   r0   rV   sizerX   rM   rL   appendr2   remover`   r   r^   r_   )r3   rF   r4   qr)   r#   msgr5   attachment_preferencenew_nodea_probabilityclique_degreeclique_sizenddegeligible_nodesr\   src_nodeprohibited_nodes	dest_noderw   	nbr_nodesra   s                          r:   r   r   G  s   l &lUuUL1uQGs$qcRs##1uzEaSQCPs## 	A|$A   q* H
Q, A
1v-2 1[1_!<01
RWRcM>QbRNR1X 5;;~6 $((#4  ''1 KK"7VB2EU;URV	 

8Y/ &,,X6%,,Y7 88H%6"))(388I&-7I<W")))4/54 -)1q5)a1668.Ik.I 12
VWRa#>U>UbVNV1X !9{{>2 !4M	  ;;y1   & KK"7OB2Y;NRO	 dH-

4+ &,,X6%,,Y7 88H%*x>/I"))(3.xx	*m;&--i8xx	*a/&--i8C!9L %%:AtDGS(a9: "((1!(((q1u)=>MHo Q,p H] S W( W Ps0   *O(8O(	O.
O.
-O3O3*	O9
4O9
c                L   t        |dd      }|dk  s| |k  rt        j                  d| d|        |dkD  s|dk  rt        j                  d|       t        ||      }t	        |      }|}|| k  r*t        |||      }|j                         }	|j                  ||	       |j                  |	       d}
|
|k  r|j                         |k  rq|j                  |	      D cg c]  }|j                  ||      s||k7  r| }}|r:|j                  |      }|j                  ||       |j                  |       |
dz   }
|j                         }	|j                  ||	       |j                  |	       |
dz   }
|
|k  r|j                  |g|z         |dz  }|| k  r*|S c c}w )u  Holme and Kim algorithm for growing graphs with powerlaw
    degree distribution and approximate average clustering.

    Parameters
    ----------
    n : int
        the number of nodes
    m : int
        the number of random edges to add for each new node
    p : float,
        Probability of adding a triangle after adding a random edge
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Notes
    -----
    The average clustering has a hard time getting above a certain
    cutoff that depends on `m`.  This cutoff is often quite low.  The
    transitivity (fraction of triangles to possible triangles) seems to
    decrease with network size.

    It is essentially the Barabási–Albert (BA) growth model with an
    extra step that each random edge is followed by a chance of
    making an edge to one of its neighbors too (and thus a triangle).

    This algorithm improves on BA in the sense that it enables a
    higher average clustering to be attained if desired.

    It seems possible to have a disconnected graph with this algorithm
    since the initial `m` nodes may not be all linked to a new node
    on the first iteration like the BA model.

    Raises
    ------
    NetworkXError
        If `m` does not satisfy ``1 <= m <= n`` or `p` does not
        satisfy ``0 <= p <= 1``.

    References
    ----------
    .. [1] P. Holme and B. J. Kim,
       "Growing scale-free networks with tunable clustering",
       Phys. Rev. E, 65, 026107, 2002.
    FrD   r   z'NetworkXError must have m>1 and m<n, m=z,n=r   z$NetworkXError p must be in [0,1], p=)r   r+   rT   r	   rL   r   popr2   r   r0   	neighborsrN   rM   r   )r3   rF   r4   r)   r#   r5   r   r   possible_targetstargetcountnbrneighborhoods                r:   r   r     s   f &lUuUL1uA!H3qcRSS1uA!EaSIJJA|$A!WNF
1*).!TB!%%'	

66"f%ai{{}q   !{{62 ::fc2sf}    
  ++l3CJJvs+"))#.!AIE%))+FJJvv&!!&)AIE# ai& 	vhl+!7 1*8 H' s   " F!c                $   t        |dd      }t        |      t        |      }}t        d ||fD              rt        j                  d      t        d|j                         z  | z  dz         }t        ||      }|dz
  }t        |      D ]  } |j                         |k  s|dz  }|j                  | |       |}|j                         |k  r+|dz  }|j                  ||       |j                         |k  r+|j                         |k  rk |S )a  Returns a random lobster graph.

    A lobster is a tree that reduces to a caterpillar when pruning all
    leaf nodes. A caterpillar is a tree that reduces to a path graph
    when pruning all leaf nodes; setting `p2` to zero produces a caterpillar.

    This implementation iterates on the probabilities `p1` and `p2` to add
    edges at levels 1 and 2, respectively. Graphs are therefore constructed
    iteratively with uniform randomness at each level rather than being selected
    uniformly at random from the set of all possible lobsters.

    Parameters
    ----------
    n : int
        The expected number of nodes in the backbone
    p1 : float
        Probability of adding an edge to the backbone
    p2 : float
        Probability of adding an edge one level beyond backbone
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Grap)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Raises
    ------
    NetworkXError
        If `p1` or `p2` parameters are >= 1 because the while loops would never finish.
    FrD   c              3   &   K   | ]	  }|d k\    yw)r   Nrh   ).0r4   s     r:   	<genexpr>z!random_lobster.<locals>.<genexpr>n  s     
$a16
$s   z6Probability values for `p1` and `p2` must both be < 1.r   g      ?r   )
r   absanyr+   rT   r1   r0   r
   r@   r2   )	r3   p1p2r)   r#   llenLcurrent_nodecat_nodes	            r:   r   r   J  s	   D &lUuULWc"gB

$B8
$$WXX q4;;= 1$s*+D4&A!8L4[ 3kkmb ALJJq,'#H++-"$!

8\2 ++-"$	 kkmb 3 Hr;   c          	         t        |dd      }t        d|      }g }g }d}| D ]  \  }}}	t        ||	z        }
|j                  ||
z
         t	        j
                  t        ||
||j                        |      }|j                  |       ||z  }t        j                  j                  ||      } t        t        |      dz
        D ]  }t        ||         }t        ||dz            }||   }d}||k  s/|j                  |      }|j                  |      }||k(  s|j                  ||      r@|j                  ||       |dz   }||k  rW |S )a;  Returns a random shell graph for the constructor given.

    Parameters
    ----------
    constructor : list of three-tuples
        Represents the parameters for a shell, starting at the center
        shell.  Each element of the list must be of the form `(n, m,
        d)`, where `n` is the number of nodes in the shell, `m` is
        the number of edges in the shell, and `d` is the ratio of
        inter-shell (next) edges to intra-shell edges. If `d` is zero,
        there will be no intra-shell edges, and if `d` is one there
        will be all possible intra-shell edges.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. Graph instances are not supported.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Examples
    --------
    >>> constructor = [(10, 20, 0.8), (20, 40, 0.8)]
    >>> G = nx.random_shell_graph(constructor)

    FrD   r   )r)   r#   )first_labelr   )r   r	   r1   r   r+   convert_node_labels_to_integersr   	__class__	operatorsunionr@   rV   rL   rM   rN   r2   )constructorr)   r#   r5   glistintra_edgesnnodesr3   rF   rz   inter_edgesgginlist1nlist2total_edgesrQ   rH   r7   s                      r:   r   r     s`   8 &lUuULA|$AEKF 	%1a!a%j1{?+..Q$Q[[Q
 	Q!LLq!$	% CJN# ,eBieBFm$!"o
;&F#AF#AAvAq)

1a '!^
 ;&, Hr;   c                X    t        |dd      }t        | |||      }t        ||      }|S )a#  Returns a tree with a power law degree distribution.

    Parameters
    ----------
    n : int
        The number of nodes.
    gamma : float
        Exponent of the power law.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    tries : int
        Number of attempts to adjust the sequence to make it a tree.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Raises
    ------
    NetworkXError
        If no valid sequence is found within the maximum number of
        attempts.

    Notes
    -----
    A trial power law degree sequence is chosen and then elements are
    swapped with new elements from a powerlaw distribution until the
    sequence makes a tree (by checking, for example, that the number of
    edges is one smaller than the number of nodes).

    FrD   )gammar)   re   )r   r   r   )r3   r   r)   re   r#   r}   r5   s          r:   r   r     s4    D &lUuUL
'T
OCS,/AHr;   )r    c                    t         j                  j                  | ||      }|D cg c]!  }t        | t	        t        |      d            # }}t         j                  j                  |||      }|D cg c]!  }t        | t	        t        |      d            # }}|D ]B  }d| z  t        |      z
  dk(  r|c S |j                  d| dz
        }	|j                         ||	<   D t        j                  d| d      c c}w c c}w )aK  Returns a degree sequence for a tree with a power law distribution.

    Parameters
    ----------
    n : int,
        The number of nodes.
    gamma : float
        Exponent of the power law.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    tries : int
        Number of attempts to adjust the sequence to make it a tree.

    Raises
    ------
    NetworkXError
        If no valid sequence is found within the maximum number of
        attempts.

    Notes
    -----
    A trial power law degree sequence is chosen and then elements are
    swapped with new elements from a power law distribution until
    the sequence makes a tree (by checking, for example, that the number of
    edges is one smaller than the number of nodes).

    )exponentr)   r   r   r   zExceeded max (z%) attempts for a valid tree sequence.)
r+   utilspowerlaw_sequenceminr   roundsumrandintr   rT   )
r3   r   r)   re   zszseqswapr   indexs
             r:   r   r     s   @ 	""1u4"@A./0C3uQx#$0D0 	""55t"DA./0C3uQx#$0D0 	! q53t9!KQA&hhjU	! 


DE % 1
 1s   &C=5&Dc                  	 t        |dd      }|
ddl		fd}t        j                  |      }|j	                  t        |              d\  }}|| k  rt        j                  d|j                         z
         } || z  || z  d      |k  r|dz   |dz   }}n>t        j                  |  ||| z  || z  |      z        }|j                  |dz
  |dz
         || k  r|S )	u  Returns an random graph based on the specified kernel.

    The algorithm chooses each of the $[n(n-1)]/2$ possible edges with
    probability specified by a kernel $\kappa(x,y)$ [1]_.  The kernel
    $\kappa(x,y)$ must be a symmetric (in $x,y$), non-negative,
    bounded function.

    Parameters
    ----------
    n : int
        The number of nodes
    kernel_integral : function
        Function that returns the definite integral of the kernel $\kappa(x,y)$,
        $F(y,a,b) := \int_a^b \kappa(x,y)dx$
    kernel_root: function (optional)
        Function that returns the root $b$ of the equation $F(y,a,b) = r$.
        If None, the root is found using :func:`scipy.optimize.brentq`
        (this requires SciPy).
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
    create_using : Graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        Multigraph and directed types are not supported and raise a ``NetworkXError``.

    Notes
    -----
    The kernel is specified through its definite integral which must be
    provided as one of the arguments. If the integral and root of the
    kernel integral can be found in $O(1)$ time then this algorithm runs in
    time $O(n+m)$ where m is the expected number of edges [2]_.

    The nodes are set to integers from $0$ to $n-1$.

    Examples
    --------
    Generate an Erdős–Rényi random graph $G(n,c/n)$, with kernel
    $\kappa(x,y)=c$ where $c$ is the mean expected degree.

    >>> def integral(u, w, z):
    ...     return c * (z - w)
    >>> def root(u, w, r):
    ...     return r / c + w
    >>> c = 1
    >>> graph = nx.random_kernel_graph(1000, integral, root)

    See Also
    --------
    gnp_random_graph
    expected_degree_graph

    References
    ----------
    .. [1] Bollobás, Béla,  Janson, S. and Riordan, O.
       "The phase transition in inhomogeneous random graphs",
       *Random Structures Algorithms*, 31, 3--122, 2007.

    .. [2] Hagberg A, Lemons N (2015),
       "Fast Generation of Sparse Random Kernel Graphs".
       PLoS ONE 10(9): e0135177, 2015. doi:10.1371/journal.pone.0135177
    FrD   Nr   c                 T      fd}j                   j                  |d      S )Nc                      |       z
  S Nrh   )bakernel_integralrys    r:   my_functionz=random_kernel_graph.<locals>.kernel_root.<locals>.my_functioni  s    &q!Q/!33r;   r   )optimizebrentq)r   r   r   r   r   sps   ``` r:   kernel_rootz(random_kernel_graph.<locals>.kernel_rooth  s#    4 ;;%%k1a88r;   r"   )r   r   r   )r   scipyr+   r	   add_nodes_fromr@   r.   r/   r0   ceilr2   )
r3   r   r   r)   r#   graphr\   rZ   r   r   s
    `       @r:   r   r   "  s    D &lUuUL	9 NN5E	q"FQ
a%XXa$++-'((1q5!a%+q0q5!a%qA		!k!a%Q::;ANN1q5!a%( a% Lr;   )NFr   )d   N)NN)rR   Nr   )(__doc__r=   r.   collectionsr   networkxr+   networkx.utilsr   
utils.miscr   classicr   r	   r
   r   
degree_seqr   __all___dispatchabler   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rh   r;   r:   <module>r      s  
   #  * + H H ,. T2L4 L 3 L^ T2;d ; 3 ;~ "$  T2<D < 3 <~ T24d 4 3 4n T2FD F 3 FR T2KT K 3 K\ T23?RV 3? 3 3?l T2s$ s 3 sl T2Gt G 3 GT T2+/dAEd 3 dN T2a$ a 3 aH T2Xt X 3 Xv T22 2 3 2j T2:t : 3 :z T2$4 $ 3 $N 4  4n T2/3TEIT 3 Tr;   