ó
    …~iÎ/  ã                   ó°  • S r SSKrSSKJr  SSKJr  SSKr/ SQrS r	\R                  R                  S5      \R                  R                  S5      \R                  " S	S
9SS j5       5       5       r\R                  R                  S5      \R                  R                  S5      S 5       5       r\R                  R                  S5      SSS.S j5       rg)zOFunctions for splitting a network into two communities (finding a bipartition).é    N)Údeepcopy)Úcount)Úkernighan_lin_bisectionÚspectral_modularity_bipartitionÚgreedy_node_swap_bipartitionc              #   óP  ^ ^^#   • [         R                  R                  5       [         R                  R                  5       4=u  p#mT R                  5        HW  u  pE[	        U4S jUR                  5        5       5      nTU   (       a  UR                  XF5        ME  UR                  XF* 5        MY     UU U4S jnSnSn	U(       aa  U(       aY  UR                  5       u  pFU" U5        UR                  5       u  p«U" U
5        X–U-   -  n	US-  nX˜XJ44v •  U(       a
  U(       a  MW  gggg7f)zØ
This is a modified form of Kernighan-Lin, which moves single nodes at a
time, alternating between sides to keep the bisection balanced.  We keep
two min-heaps of swap costs to make optimal-next-move selection fast.
c              3   óF   >#   • U  H  u  pTU   (       a  UOU* v •  M     g 7f©N© )Ú.0ÚvÚwtÚsides      €Úg/home/mande/repo/quber/.venv/lib/python3.13/site-packages/networkx/algorithms/community/bipartitions.pyÚ	<genexpr>Ú'_kernighan_lin_sweep.<locals>.<genexpr>   s    øé € ÐFº±°˜4 Ÿ7‘R¨¨Ô+ºùó   ƒ!c                 óÈ   >• T	U    nTU    R                  5        HE  u  p#T	U   nXA:X  a  U* nTU   nX%;   d  M  UR                  U5      SU-  -   nUR                  X&SS9  MG     g )Né   T)Úallow_increase)ÚitemsÚgetÚinsert)
ÚnodeÚ	side_nodeÚnbrr   Úside_nbrÚheap_nbrÚcost_nbrÚ
cost_heapsÚ	edge_infor   s
          €€€r   Ú_update_heap_valuesÚ1_kernighan_lin_sweep.<locals>._update_heap_values   sq   ø€ Ø˜‘Jˆ	Ø  ‘×,Ñ,Ö.‰GˆCØ˜C‘yˆHØÓ$Ø�S�Ø! (Ñ+ˆHØ�Ø#Ÿ<™<¨Ó,¨q°2©vÑ5�à—‘ ¸d�ÓCò /ó    r   é   N)ÚnxÚutilsÚ
BinaryHeapr   Úsumr   Úpop)r!   r   Úheap0Úheap1ÚuÚnbrsÚcost_ur"   ÚiÚtotcostr   Úcost_vr    s   ``          @r   Ú_kernighan_lin_sweepr3      sï   úé € ô !#§¡× 3Ñ 3Ó 5´r·x±x×7JÑ7JÓ7LÐ LÐL�L€E�:à—?‘?Ö$‰ˆÜÔF¸¿¹¼ÓFÓFˆØ��7Ø�L‰L˜Ö#à�L‰L˜˜GÖ$ñ %÷
Dð 	
€AØ€GÞ
–EØ—I‘I“K‰	ˆÙ˜AÔØ—I‘I“K‰	ˆÙ˜AÔØ˜F‘?Ñ"ˆØ	ˆQ‰ˆØ˜1˜&Ð Ò ö —E‘Eˆ%�Eˆ%ùs   …DD&Ä"D&Údirectedé   Úweight)Ú
edge_attrsé
   c                 óV  ^• [        U 5      nUc(  UR                  U5        [        U5      S-  nUSU XVS p‡OA Uu  px[
        R                  R                  XU/5      (       d  [
        R                  " S5      eU V
s0 s H  oªX§;   _M	     nn
[        T5      (       a  TnO"U R                  5       (       a  U4S jnOU4S jnU R                  R                  5        VVVVs0 s H:  u  pÞXÞR                  5        VVs0 s H  u  nnU" XßU5      =nc  M  UU_M     snn_M<     nnnnn[        U5       HI  n[        [        UU5      5      n[        U5      u  nnnUS:¼  a    OUSU  H  u    nu  pßSX½'   SX¿'   M     MK     UR                  5        VVs1 s H  u  nnUS:X  d  M  UiM     nnnUR                  5        VVs1 s H  u  nnUS:X  d  M  UiM     nnnUU4$ ! [        [        4 a  n	[
        R                  " S5      U	eSn	A	ff = fs  sn
f s  snnf s  snnnnf s  snnf s  snnf )	uÀ	  Partition a graph into two blocks using the Kernighanâ€“Lin algorithm.

This algorithm partitions a network into two sets by iteratively
swapping pairs of nodes to reduce the edge cut between the two sets.  The
pairs are chosen according to a modified form of Kernighan-Lin [1]_, which
moves nodes individually, alternating between sides to keep the bisection
balanced.

Kernighan-Lin is an approximate algorithm for maximal modularity bisection.
In [2]_ they suggest that fine-tuned improvements can be made using
greedy node swapping, (see `greedy_node_swap_bipartition`).
The improvements are typically only a few percent of the modularity value.
But they claim that can make a difference between a good and excellent method.
This function does not perform any improvements. But you can do that yourself.

Parameters
----------
G : NetworkX graph
    Graph must be undirected.

partition : tuple
    Pair of iterables containing an initial partition. If not
    specified, a random balanced partition is used.

max_iter : int
    Maximum number of times to attempt swaps to find an
    improvement before giving up.

weight : string or function (default: "weight")
    If this is a string, then edge weights will be accessed via the
    edge attribute with this key (that is, the weight of the edge
    joining `u` to `v` will be ``G.edges[u, v][weight]``). If no
    such edge attribute exists, the weight of the edge is assumed to
    be one.

    If this is a function, the weight of an edge is the value
    returned by the function. The function must accept exactly three
    positional arguments: the two endpoints of an edge and the
    dictionary of edge attributes for that edge. The function must
    return a number or None to indicate a hidden edge.

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

Returns
-------
partition : tuple
    A pair of sets of nodes representing the bipartition.

Raises
------
NetworkXError
    If `partition` is not a valid partition of the nodes of the graph.

References
----------
.. [1] Kernighan, B. W.; Lin, Shen (1970).
   "An efficient heuristic procedure for partitioning graphs."
   *Bell Systems Technical Journal* 49: 291--307.
   Oxford University Press 2011.
.. [2] M. E. J. Newman,
   "Modularity and community structure in networks",
   PNAS, 103 (23), p. 8577-8582,
   https://doi.org/10.1073/pnas.0601602103

Nr   zpartition must be two setszpartition invalidc                 óJ   >• [        U4S jUR                  5        5       5      $ )Nc              3   óF   >#   • U  H  oR                  TS 5      v •  M     g7f)r%   N©r   )r   Úddr6   s     €r   r   Ú<kernighan_lin_bisection.<locals>.<lambda>.<locals>.<genexpr>”   s   øé € Ð(PÂZ¸r¯©°¸×):Ð):ÂZùr   )r)   Úvalues©r-   r   Údr6   s      €r   Ú<lambda>Ú)kernighan_lin_bisection.<locals>.<lambda>”   s   ø€ ¤SÔ(PÀQÇXÁXÄZÓ(PÔ%Pr$   c                 ó(   >• UR                  TS5      $ )Nr%   r<   r@   s      €r   rB   rC   –   s   ø€  Q§U¡U¨6°1Ô%5r$   r   r%   )ÚlistÚshuffleÚlenÚ	TypeErrorÚ
ValueErrorr&   ÚNetworkXErrorÚ	communityÚis_partitionÚcallableÚis_multigraphÚ_adjr   Úranger3   Úmin)ÚGÚ	partitionÚmax_iterr6   ÚseedÚnodesÚmidÚAÚBÚerrr   r   Ú
sum_weightr-   r.   r   rA   r   r!   r0   ÚcostsÚmin_costÚmin_iÚ_ÚsÚpart1Úpart2s      `                       r   r   r   7   s  ø€ ôP �‹G€EàÑØ�‰�UÔÜ�%‹j˜A‰oˆØ�T�cˆ{˜E $˜K‰1ð	JØ‰DˆAô �|‰|×(Ñ(¨°¨F×3Ñ3Ü×"Ò"Ð#6Ó7Ð7á*/Ó0ª% $�4‘9Ò©%€DÐ0ô �×ÑØ‰
Ø	
�‰×	Ñ	ÜP‰
ä5ˆ
ð —v‘v—|‘|”~öâ%‰GˆAð 	
Ÿj™jœlÔVšl‘d�a˜±ZÀÀaÓ5HÐ/H¨r‹EˆAˆrŠE™lÒVÒVÙ%ð ó ô
 �8Ž_ˆÜÔ)¨)°TÓ:Ó;ˆä  ›ZÑˆ�%˜Ø�q‹=Ùà! & 5›M‰LˆAˆq‘&�1ØˆD‰GØˆD‹Gó *ñ ð  Ÿ:™:œ<Ô2š<‘4�1�a¨1°©6�Q™<€EÑ2ØŸ:™:œ<Ô2š<‘4�1�a¨1°©6�Q™<€EÑ2Ø�%ˆ<ÐøôE œ:Ð&ó 	JÜ×"Ò"Ð#?Ó@ÀcÐIûð	Jüò
 1ùó Wùõùó  3ùÛ2sS   ¹G Á=HÃ!H
Ã<HÄHÄH
ÆHÆ#HÆ?H%ÇH%ÇH	Ç-HÈH	ÈH
Ú
multigraphc                 ó„  • SSK n[        R                  R                  U 5      nUR                  R	                  U5      u  p4UR                  U5      S   n[        UR                  USS2U4   5      U 5      n[        5       [        5       p‡U H/  u  pšU	S:  a  UR                  U
5        M  UR                  U
5        M1     Xx4$ )aj  Return a bipartition of the nodes based on the spectrum of the
modularity matrix of the graph.

This method calculates the eigenvector associated with the second
largest eigenvalue of the modularity matrix, where the modularity
matrix *B* is defined by

..math::

    B_{i j} = A_{i j} - \frac{k_i k_j}{2 m},

where *A* is the adjacency matrix, `k_i` is the degree of node *i*,
and *m* is the number of edges in the graph. Nodes whose
corresponding values in the eigenvector are negative are placed in
one block, nodes whose values are nonnegative are placed in another
block.

Parameters
----------
G : NetworkX graph

Returns
-------
C : tuple
    Pair of communities as two sets of nodes of ``G``, partitioned
    according to second largest eigenvalue of the modularity matrix.

Examples
--------
>>> G = nx.karate_club_graph()
>>> MrHi, Officer = nx.community.spectral_modularity_bipartition(G)
>>> MrHi, Officer = sorted([sorted(MrHi), sorted(Officer)])
>>> MrHi
[0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21]
>>> Officer
[8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]

References
----------
.. [1] M. E. J. Newman *Networks: An Introduction*, pages 373--378
   Oxford University Press 2011.
.. [2] M. E. J. Newman,
   "Modularity and community structure in networks",
   PNAS, 103 (23), p. 8577-8582,
   https://doi.org/10.1073/pnas.0601602103

r   Néÿÿÿÿ)
Únumpyr&   ÚlinalgÚmodularity_matrixÚeigÚargsortÚzipÚrealÚsetÚadd)rR   ÚnprY   ÚeigenvaluesÚeigenvectorsÚindexÚv2ÚleftÚrightr-   Úns              r   r   r   ­   s    € ód ä
�	‰	×#Ñ# AÓ&€AØ "§	¡	§¡¨aÓ 0Ñ€KØ�J‰J�{Ó# BÑ'€EÜ	ˆR�W‰W�\¢! U (Ñ+Ó,¨aÓ	0€BÜ“%œ›ˆ%Û‰ˆØˆq‹5Ø�H‰H�QŽKà�I‰I�aŽLñ	 ð
 ˆ;Ðr$   )Ú
init_splitrT   c                óü  ^"• Ucb  [        U 5      S-  n[        U 5      U-
  n[        [        R                  " [	        U 5      U5      5      nU  Vs1 s H  ofU;  d  M
  UiM     nnXW4nOj[
        R                  R                  X5      (       d  [
        R                  " S5      e[        U5      S:X  d  [
        R                  " S5      e[        U5      n[
        R                  R                  X5      n	X‰pºSnU R                  5       n[        U R                  5      m"X¹:¼  GaX  XÂ:  GaR  U
nUn	[        U
5      nUn[        U 5      nU(       Ga  SnSnSnUu  nn[        U"4S jU 5       5      n[        U"4S jU 5       5      nU HŽ  nUU;   a	  UUnnUUnnOUUnnUUnn[        X   R                  5       U-  5      * U-  n[        X   R                  5       U-  5      U-  nT"U   nUSUS-  -  -  UU-
  U-
  -  nUU-   U-   n U U:”  d  M†  U nUnUnUn!M�     UR!                  U5        W!R#                  U5        UU-  nXû:”  a  [        U5      UpºUR!                  U5        U(       a  GM  US	-  nX¹:¼  a  XÂ:  a  GMR  U$ s  snf )
a¹  Split the nodes into two communities based on greedy
modularity maximization.

The algorithm works by selecting a node to change communities which
will maximize the modularity. The swap is made and the community
structure with the highest modularity is kept.

Parameters
----------
G : NetworkX graph

init_split : 2-tuple of sets of nodes
    Pair of sets of nodes in ``G`` providing an initial bipartition
    for the algorithm. If not specified, a random balanced partition
    is used. If this pair of sets is not a partition of the nodes of `G`,
    :exc:`NetworkXException` is raised.

max_iter : int
  Maximum number of iterations of attempting swaps to find an improvement.

Returns
-------
max_split : 2-tuple of sets of nodes
    Pair of sets of nodes of ``G``, partitioned according to a
    node swap greedy modularity maximization algorithm.

Raises
------
NetworkXError
  if init_split is not a valid partition of the
  graph into two communities or if G is a MultiGraph

Examples
--------
>>> G = nx.barbell_graph(3, 0)
>>> left, right = nx.community.greedy_node_swap_bipartition(G)
>>> # Sort the communities so the nodes appear in increasing order.
>>> left, right = sorted([sorted(left), sorted(right)])
>>> sorted(left)
[0, 1, 2]
>>> sorted(right)
[3, 4, 5]

Notes
-----
This function is not implemented for multigraphs.

References
----------
.. [1] M. E. J. Newman "Networks: An Introduction", pages 373--375.
   Oxford University Press 2011.

Nr   z"init_split is not a partition of Gz init_split must be a bipartitionr   re   c              3   ó.   >#   • U  H
  nTU   v •  M     g 7fr
   r   ©r   rv   ÚG_degrees     €r   r   Ú/greedy_node_swap_bipartition.<locals>.<genexpr>D  s   øé € Ð2ªT¨˜ žªTùó   ƒc              3   ó.   >#   • U  H
  nTU   v •  M     g 7fr
   r   rz   s     €r   r   r|   E  s   øé € Ð4ªe¨˜ !žªeùr}   r%   )rG   rm   ÚrandomÚsamplerE   r&   rK   rL   rJ   r   Ú
modularityÚnumber_of_edgesÚdictÚdegreer)   ÚkeysÚremovern   )#rR   rw   rT   Úm1Úm2Ú
some_nodesrv   Úother_nodesÚbest_split_so_farÚbest_modÚ	max_splitÚmax_modÚitsÚmÚ
next_splitÚnext_modrV   Úmax_swapÚmax_nodeÚmax_node_commrt   ru   ÚleftdÚrightdÚin_commÚout_commÚin_degÚout_degÚd_eiiÚd_ejjÚdegÚd_sum_aiÚswap_changeÚnon_max_node_commr{   s#                                     @r   r   r   î   s�  ø€ ðn ÑÜ�‹V�q‰[ˆÜ�‹V�b‰[ˆÜœŸš¤t¨A£w°Ó3Ó4ˆ
Ù"#Ó;¢!˜Q°
Ñ':—q¡!ˆÐ;Ø'Ð5Ñä�|‰|×(Ñ(¨×7Ñ7Ü×"Ò"Ð#GÓHÐHÜ�:‹ !Ó#Ü×"Ò"Ð#EÓFÐFÜ$ ZÓ0Ðä�|‰|×&Ñ& qÓ<€Hà*ˆwØ
€CØ	×ÑÓ€AÜ�A—H‘H‹~€Hà
Ô
 #¤.Ø%ÐØˆÜ˜iÓ(ˆ
ØˆÜ�A“ˆßØˆHØˆHØ ˆMØ$‰KˆD�%ÜÔ2©TÓ2Ó2ˆEÜÔ4©eÓ4Ó4ˆFÛ�Ø˜“9Ø(,¨e˜X�GØ&+¨V˜G�F˜Gà(-¨t˜X�GØ&,¨e˜G�Fä˜Q™TŸY™Y›[¨7Ñ2Ó3Ð3°aÑ7�Ü˜A™DŸI™I›K¨(Ñ2Ó3°aÑ7�Ø˜q‘k�Ø 1 q¨!¡t¡8Ñ,°¸'Ñ1AÀCÑ1GÑH�Ø# e™m¨hÑ6�à Õ)Ø*�HØ �HØ$+�MØ(0Ò%ñ% ð( × Ñ  Ô*Ø×!Ñ! (Ô+Ø˜Ñ ˆHàÓ!Ü%-¨jÓ%9¸8˜7Ø�L‰L˜Ô"÷C ‰eðD 	ˆq‰ˆðQ Ó
 #¦.ðR Ðùòs <s   Á	I9ÁI9)Nr8   r6   N)Ú__doc__r   Úcopyr   Ú	itertoolsr   Únetworkxr&   Ú__all__r3   r'   Únot_implemented_forÚpy_random_stateÚ_dispatchabler   r   r   r   r$   r   Ú<module>rª      sÖ   ðÙ Uã Ý Ý ã ò€ò$!ðN ‡�×Ñ˜jÓ)Ø‡�×Ñ˜!ÓØ×Ò˜XÑ&ópó 'ó ó *ðpðf ‡�×Ñ˜jÓ)Ø‡�×Ñ˜lÓ+ñ<ó ,ó *ð<ð~ ‡�×Ñ˜lÓ+Ø26Àô só ,ñsr$   