
    hO                     P   S r SSKrSSKrSSKJr  SSKrSSKJrJ	r	  / SQr
\R                  " SSS9\" SS/5      SS	 j5       5       r\	" S
5      \R                  " SSSS9SS j5       5       r\R                  " SSSS9SS j5       r\R                  " SSS9SS j5       r\R                  " SSS9SS j5       r\	" S
5      \R                  " SSS9SS j5       5       r\	" S
5      \R                  " SSS9SS j5       5       r\	" S
5      \R                  " SSS9SS j5       5       rS rg)z0
Generators and functions for bipartite graphs.
    N)reduce)nodes_or_numberpy_random_state)configuration_modelhavel_hakimi_graphreverse_havel_hakimi_graphalternating_havel_hakimi_graphpreferential_attachment_graphrandom_graphgnmk_random_graphcomplete_bipartite_graphT)graphsreturns_graph   c                   ^ [         R                  " SU5      nUR                  5       (       a  [         R                  " S5      eU u  pUu  nm[	        U [
        R                  5      (       a4  [	        U[
        R                  5      (       a  T Vs/ s H  oPU-   PM	     snmUR                  USS9  UR                  TSS9  [        U5      [        U5      [        T5      -   :w  a  [         R                  " S5      eUR                  U4S jU 5       5        S[        U5       S[        T5       S	3UR                  S
'   U$ s  snf )a  Returns the complete bipartite graph `K_{n_1,n_2}`.

The graph is composed of two partitions with nodes 0 to (n1 - 1)
in the first and nodes n1 to (n1 + n2 - 1) in the second.
Each node in the first is connected to each node in the second.

Parameters
----------
n1, n2 : integer or iterable container of nodes
    If integers, nodes are from `range(n1)` and `range(n1, n1 + n2)`.
    If a container, the elements are the nodes.
create_using : NetworkX graph instance, (default: nx.Graph)
   Return graph of this type.

Notes
-----
Nodes are the integers 0 to `n1 + n2 - 1` unless either n1 or n2 are
containers of nodes. If only one of n1 or n2 are integers, that
integer is replaced by `range` of that integer.

The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.complete_bipartite_graph
r   Directed Graph not supported	bipartiter   z,Inputs n1 and n2 must contain distinct nodesc              3   >   >#    U  H  nT  H  o!U4v   M
     M     g 7fN ).0uvbottoms      Z/var/www/html/env/lib/python3.13/site-packages/networkx/algorithms/bipartite/generators.py	<genexpr>+complete_bipartite_graph.<locals>.<genexpr>A   s     9S&QV&VSs   zcomplete_bipartite_graph(z, )name)nxempty_graphis_directedNetworkXError
isinstancenumbersIntegraladd_nodes_fromlenadd_edges_fromgraph)n1n2create_usingGtopir   s         @r   r   r      s   : 	q,'A}}=>>GBJB"g&&''Jr7;K;K,L,L"()&Qq&&)SA&Vq)
1vSCK''MNN9S991#c(2c&k]!LAGGFOH *s   D?   bipartite_configuration_model)r    r   r   c                 b  ^^ [         R                  " SU[         R                  S9nUR                  5       (       a  [         R                  " S5      e[        U 5      n[        U5      n[        U 5      n[        U5      nXx:X  d  [         R                  " SU SU 35      e[        XEU5      n[        U 5      S:X  d  [        U 5      S:X  a  U$ [        U5       V	s/ s H
  o/X	   -  PM     n
n	U
 VVs/ s H  o  H  oPM     M     snnm[        XUU-   5       V	s/ s H  o/XU-
     -  PM     n
n	U
 VVs/ s H  o  H  oPM     M     snnmUR                  T5        UR                  T5        UR                  UU4S j[        U5       5       5        SUl        U$ s  sn	f s  snnf s  sn	f s  snnf )a{  Returns a random bipartite graph from two given degree sequences.

Parameters
----------
aseq : list
   Degree sequence for node set A.
bseq : list
   Degree sequence for node set B.
create_using : NetworkX graph instance, optional
   Return graph of this type.
seed : integer, random_state, or None (default)
    Indicator of random number generation state.
    See :ref:`Randomness<randomness>`.

The graph is composed of two partitions. Set A has nodes 0 to
(len(aseq) - 1) and set B has nodes len(aseq) to (len(bseq) - 1).
Nodes from set A are connected to nodes in set B by choosing
randomly from the possible free stubs, one in A and one in B.

Notes
-----
The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
If no graph type is specified use MultiGraph with parallel edges.
If you want a graph with no parallel edges use create_using=Graph()
but then the resulting degree sequences might not be exact.

The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.configuration_model
r   defaultr   /invalid degree sequences, sum(aseq)!=sum(bseq),,c              3   8   >#    U  H  nTU   TU   /v   M     g 7fr   r   )r   r1   astubsbstubss     r   r   &configuration_model.<locals>.<genexpr>   s     A[fQi+[s   r3   )r!   r"   
MultiGraphr#   r$   r)   sum_add_nodes_with_bipartite_labelmaxrangeshuffler*   r    )aseqbseqr.   seedr/   lenalenbsumasumbr   stubssubseqxr:   r;   s                @@r   r   r   F   s}   F 	q,>A}}=>> t9Dt9Dt9Dt9D<=dV1TFK
 	
 	(6A
4yA~Ta %*$K0KqS47]KE0#4eFVaVae4F+0d{+CD+CaS4D>!+CED#4eFVaVae4F 	LLLLAU4[AA,AFH 14D4s   F0F F&3F+bipartite_havel_hakimi_graphc                 f   [         R                  " SU[         R                  S9nUR                  5       (       a  [         R                  " S5      e[        U 5      n[        U5      n[        U 5      n[        U5      nXg:X  d  [         R                  " SU SU 35      e[        X4U5      n[        U 5      S:X  d  [        U 5      S:X  a  U$ [        U5       Vs/ s H	  oU   U/PM     n	n[        XDU-   5       Vs/ s H  oX-
     U/PM     n
nU	R                  5         U	(       a}  U	R                  5       u  pUS:X  a  OdU
R                  5         X* S  HB  nUS   nUR                  X5        US==   S-  ss'   US   S:X  d  M1  U
R                  U5        MD     U	(       a  M}  SUl        U$ s  snf s  snf )	aE  Returns a bipartite graph from two given degree sequences using a
Havel-Hakimi style construction.

The graph is composed of two partitions. Set A has nodes 0 to
(len(aseq) - 1) and set B has nodes len(aseq) to (len(bseq) - 1).
Nodes from the set A are connected to nodes in the set B by
connecting the highest degree nodes in set A to the highest degree
nodes in set B until all stubs are connected.

Parameters
----------
aseq : list
   Degree sequence for node set A.
bseq : list
   Degree sequence for node set B.
create_using : NetworkX graph instance, optional
   Return graph of this type.

Notes
-----
The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
If no graph type is specified use MultiGraph with parallel edges.
If you want a graph with no parallel edges use create_using=Graph()
but then the resulting degree sequences might not be exact.

The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.havel_hakimi_graph
r   r5   r   r7   r8   Nr   rM   r!   r"   r=   r#   r$   r)   r>   r?   r@   rA   sortpopadd_edgeremover    )rC   rD   r.   r/   naseqnbseqrH   rI   r   r:   r;   degreer   targets                 r   r   r      s   B 	q,>A}}=>> IEIEt9Dt9D<=dV1TFK
 	
 	(%8A
4yA~Ta %*%L1LqAwlLF1,1%,GH,GqAI",GFH
KKM
jjlQ;WX&Fq	AJJq1INIayA~f% ' & ,AFH# 2H   F)8F.c                 f   [         R                  " SU[         R                  S9nUR                  5       (       a  [         R                  " S5      e[        U 5      n[        U5      n[        U 5      n[        U5      nXg:X  d  [         R                  " SU SU 35      e[        X4U5      n[        U 5      S:X  d  [        U 5      S:X  a  U$ [        U5       Vs/ s H	  oU   U/PM     n	n[        XDU-   5       Vs/ s H  oX-
     U/PM     n
nU	R                  5         U
R                  5         U	(       am  U	R                  5       u  pUS:X  a  OTU
SU  HB  nUS   nUR                  X5        US==   S-  ss'   US   S:X  d  M1  U
R                  U5        MD     U	(       a  Mm  SUl        U$ s  snf s  snf )aH  Returns a bipartite graph from two given degree sequences using a
Havel-Hakimi style construction.

The graph is composed of two partitions. Set A has nodes 0 to
(len(aseq) - 1) and set B has nodes len(aseq) to (len(bseq) - 1).
Nodes from set A are connected to nodes in the set B by connecting
the highest degree nodes in set A to the lowest degree nodes in
set B until all stubs are connected.

Parameters
----------
aseq : list
   Degree sequence for node set A.
bseq : list
   Degree sequence for node set B.
create_using : NetworkX graph instance, optional
   Return graph of this type.

Notes
-----
The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
If no graph type is specified use MultiGraph with parallel edges.
If you want a graph with no parallel edges use create_using=Graph()
but then the resulting degree sequences might not be exact.

The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.reverse_havel_hakimi_graph
r   r5   r   r7   r8   r   $bipartite_reverse_havel_hakimi_graphrO   )rC   rD   r.   r/   rF   rG   rH   rI   r   r:   r;   rV   r   rW   s                 r   r   r      s   B 	q,>A}}=>> t9Dt9Dt9Dt9D<=dV1TFK
 	
 	(6A
4yA~Ta %*$K0KqAwlKF0+0d{+CD+CaAH~q!+CFD
KKM
KKM
jjlQ;Qv&Fq	AJJq1INIayA~f% ' & 4AFH# 1DrX   c                 h   [         R                  " SU[         R                  S9nUR                  5       (       a  [         R                  " S5      e[        U 5      n[        U5      n[        U 5      n[        U5      nXg:X  d  [         R                  " SU SU 35      e[        X4U5      n[        U 5      S:X  d  [        U 5      S:X  a  U$ [        U5       Vs/ s H	  oU   U/PM     n	n[        XDU-   5       Vs/ s H  oX-
     U/PM     n
nU	(       Ga  U	R                  5         U	R                  5       u  pUS:X  a  OU
R                  5         U
SUS-   nX* US-  -   S n[        X5       VVs/ s H  o  H  nUPM     M     nnn[        U5      [        U5      [        U5      -   :  a  UR                  UR                  5       5        U HB  nUS   nUR                  X5        US==   S-  ss'   US   S:X  d  M1  U
R                  U5        MD     U	(       a  GM  S	Ul        U$ s  snf s  snf s  snnf )
a{  Returns a bipartite graph from two given degree sequences using
an alternating Havel-Hakimi style construction.

The graph is composed of two partitions. Set A has nodes 0 to
(len(aseq) - 1) and set B has nodes len(aseq) to (len(bseq) - 1).
Nodes from the set A are connected to nodes in the set B by
connecting the highest degree nodes in set A to alternatively the
highest and the lowest degree nodes in set B until all stubs are
connected.

Parameters
----------
aseq : list
   Degree sequence for node set A.
bseq : list
   Degree sequence for node set B.
create_using : NetworkX graph instance, optional
   Return graph of this type.

Notes
-----
The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
If no graph type is specified use MultiGraph with parallel edges.
If you want a graph with no parallel edges use create_using=Graph()
but then the resulting degree sequences might not be exact.

The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.alternating_havel_hakimi_graph
r   r5   r   r7   r8      Nr   (bipartite_alternating_havel_hakimi_graph)r!   r"   r=   r#   r$   r)   r>   r?   r@   rA   rP   rQ   zipappendrR   rS   r    )rC   rD   r.   r/   rT   rU   rH   rI   r   r:   r;   rV   r   smalllargezrL   rJ   rW   s                      r   r	   r	   #  s   D 	q,>A}}=>> IEIEt9Dt9D<=dV1TFK
 	
 	(%8A
4yA~Ta$)%L1LqAwlLF1,1%,GH,GqAI",GFH
jjlQ;q6Q;'&A+-01-9-qq!q-9u:E
SZ//LL%Fq	AJJq1INIayA~f%  &$ 8AFH+ 2H :s   H$8H).H.c                    [         R                  " SU[         R                  S9nUR                  5       (       a  [         R                  " S5      eUS:  a  [         R                  " SU S35      e[        U 5      n[        XES5      n[        U5       Vs/ s H
  of/X   -  PM     nnU(       Ga  US   (       a  US   S   nUS   R                  U5        UR                  5       U:  d  [        U5      U:X  a-  [        U5      n	UR                  U	SS9  UR                  X5        Ov[        U[        U5      5       V
s/ s H  o/UR                  U
5      -  PM     nn
[        S U5      nUR                  U5      n	UR                  U	SS9  UR                  X5        US   (       a  M  UR                  US   5        U(       a  GM  S	Ul        U$ s  snf s  sn
f )
a  Create a bipartite graph with a preferential attachment model from
a given single degree sequence.

The graph is composed of two partitions. Set A has nodes 0 to
(len(aseq) - 1) and set B has nodes starting with node len(aseq).
The number of nodes in set B is random.

Parameters
----------
aseq : list
   Degree sequence for node set A.
p :  float
   Probability that a new bottom node is added.
create_using : NetworkX graph instance, optional
   Return graph of this type.
seed : integer, random_state, or None (default)
    Indicator of random number generation state.
    See :ref:`Randomness<randomness>`.

References
----------
.. [1] Guillaume, J.L. and Latapy, M.,
   Bipartite graphs as models of complex networks.
   Physica A: Statistical Mechanics and its Applications,
   2006, 371(2), pp.795-813.
.. [2] Jean-Loup Guillaume and Matthieu Latapy,
   Bipartite structure of all complex networks,
   Inf. Process. Lett. 90, 2004, pg. 215-221
   https://doi.org/10.1016/j.ipl.2004.03.007

Notes
-----
The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.preferential_attachment_graph
r   r5   r   r   zprobability z > 1r   c                 
    X-   $ r   r   )rL   ys     r   <lambda>/preferential_attachment_graph.<locals>.<lambda>  s    ae    'bipartite_preferential_attachment_model)r!   r"   r=   r#   r$   r)   r?   rA   rS   randomadd_noderR   rV   r   choicer    )rC   pr.   rE   r/   rT   r   vvsourcerW   bbbbbstubss                r   r
   r
   q  s   R 	q,>A}}=>>1uaS566IE'!4A!&u	.A#-B	.
eU1XFqELL {{}q CFeOQ

6Q
/

6*16uc!f1EF1EAcAHHQK'1EF !3R8W-

6Q
/

6* ee 			"Q%! "" 7AFH' 
/ Gs   G<Gc                 4   [         R                  " 5       n[        XPU5      nU(       a  [         R                  " U5      nSU  SU SU S3Ul        US::  a  U$ US:  a  [         R
                  " X5      $ [        R                  " SU-
  5      nSnSnXp:  ay  [        R                  " SUR                  5       -
  5      n	US-   [        X-  5      -   nX:  a  Xp:  a  X-
  nUS-   nX:  a  Xp:  a  M  Xp:  a  UR                  XpU-   5        Xp:  a  My  U(       a  SnSnXp:  ay  [        R                  " SUR                  5       -
  5      n	US-   [        X-  5      -   nX:  a  Xp:  a  X-
  nUS-   nX:  a  Xp:  a  M  Xp:  a  UR                  X-   U5        Xp:  a  My  U$ )u  Returns a bipartite random graph.

This is a bipartite version of the binomial (Erdős-Rényi) graph.
The graph is composed of two partitions. Set A has nodes 0 to
(n - 1) and set B has nodes n to (n + m - 1).

Parameters
----------
n : int
    The number of nodes in the first bipartite set.
m : int
    The number of nodes in the second bipartite set.
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 return a directed graph

Notes
-----
The bipartite random graph algorithm chooses each of the n*m (undirected)
or 2*nm (directed) possible edges with probability p.

This algorithm is $O(n+m)$ where $m$ is the expected number of edges.

The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.random_graph

See Also
--------
gnp_random_graph, configuration_model

References
----------
.. [1] Vladimir Batagelj and Ulrik Brandes,
   "Efficient generation of large random networks",
   Phys. Rev. E, 71, 036113, 2005.
zfast_gnp_random_graph(r8   r   r   r   g      ?)r!   Graphr?   DiGraphr    r   mathlogrj   intrR   )
nmrm   rE   directedr/   lpr   wlrs
             r   r   r     s   \ 	
A'a0AJJqM%aS!AaS2AFAvAv**100	#'	B	A
A
%XXcDKKM)*ECL fAAA f 5JJqa%  %  e#-.BABG$A&QUEE &QU u

15!$ e Hrh   c                 D   [         R                  " 5       n[        XPU5      nU(       a  [         R                  " U5      nSU  SU SU S3Ul        U S:X  d  US:X  a  U$ X-  nX&:  a  [         R
                  " XUS9$ UR                  SS9 V Vs/ s H  u  pUS   S	:X  d  M  U PM     nn n[        [        U5      [        U5      -
  5      n	S	n
X:  aI  UR                  U5      nUR                  U	5      nXU   ;   a  M1  UR                  X5        U
S-  n
X:  a  MI  U$ s  snn f )
a  Returns a random bipartite graph G_{n,m,k}.

Produces a bipartite graph chosen randomly out of the set of all graphs
with n top nodes, m bottom nodes, and k edges.
The graph is composed of two sets of nodes.
Set A has nodes 0 to (n - 1) and set B has nodes n to (n + m - 1).

Parameters
----------
n : int
    The number of nodes in the first bipartite set.
m : int
    The number of nodes in the second bipartite set.
k : 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

Examples
--------
from nx.algorithms import bipartite
G = bipartite.gnmk_random_graph(10,20,50)

See Also
--------
gnm_random_graph

Notes
-----
If k > m * n then a complete bipartite graph is returned.

This graph is a bipartite version of the `G_{nm}` random graph model.

The nodes are assigned the attribute 'bipartite' with the value 0 or 1
to indicate which bipartite set the node belongs to.

This function is not imported in the main namespace.
To use it use nx.bipartite.gnmk_random_graph
zbipartite_gnm_random_graph(r8   r   r   )r.   T)datar   r   )r!   ru   r?   rv   r    r   nodeslistsetrl   rR   )rz   r{   krE   r|   r/   	max_edgesdr0   r   
edge_countr   r   s                r   r   r     s   Z 	
A'a0AJJqM*1#Qqc1#Q7AFAvaI~**1a@@d+
C+q~/B1+C
C#a&3s8#$FJ
.KKKK!9JJq!OJ . H Ds   D!Dc                    U R                  [        X-   5      5        [        [        [        U5      S/U-  5      5      nUR	                  [        [        [        XU-   5      S/U-  5      5      5        [
        R                  " XS5        U $ )Nr   r   r   )r(   rA   dictr^   updater!   set_node_attributes)r/   rF   rG   rp   s       r   r?   r?   W  sn    U4;'(StqcDj)*AHHT#eD+.d
;<=1-Hrh   r   )NN)NF)__doc__rw   r&   	functoolsr   networkxr!   networkx.utilsr   r   __all___dispatchabler   r   r   r   r	   r
   r   r   r?   r   rh   r   <module>r      s       ;	 T2!Q)  3)X 6tSWXC Y CL 5dRVWG XGT T2F 3FR T2J 3JZ T2C 3 CL T2R 3 Rj T2B 3 BJrh   