
    h                         S r SSKJr  SSKJr  SSKJr  SSKrSSK	J
r
  S/rSrS	rSrS
rSrSrS r\R&                  " SSS9SS j5       rg)z=Lukes Algorithm for exact optimal weighted tree partitioning.    )deepcopy)	lru_cache)choiceN)not_implemented_forlukes_partitioningweightg      ?   
partitionsi   c              #   T   #    X:  d   e[        XS-   5       H  nX U-
  4v   M     g 7f)Nr	   )range)nmin_size_of_first_partp1s      U/var/www/html/env/lib/python3.13/site-packages/networkx/algorithms/community/lukes.py_split_n_fromr      s3      &&&*E2b&j 3s   &(node_weightedge_weight)
node_attrs
edge_attrsc           
      6	  ^^^!^"^#^$^%^& [         R                  " U 5      (       d  [         R                  " S5      e[         R                  " U 5      (       aN  U R	                  5        VVs/ s H  u  pEUS:X  d  M  UPM     nnn[        U5      S:X  d   eUS   n[        U 5      nO4[        [        U R                  5      5      n[         R                  " X5      nTb  Tc^  [        U 5      m&Tc&  [         R                  " T&[        [        5        [        mTc&  [         R                  " T&[        [         5        [         mOU m&[         R"                  " T&T5      R%                  5       nU H'  n	['        U	[(        5      (       a  M  [+        ST S35      e   [-        S5      S 5       m![-        S5      U!4S	 j5       n
[/        [0        5      UU&4S
 j5       m#U#4S jm$[/        [0        5      UU&4S j5       m%S m"U"U$U%4S jn[3        T!" U5      5      nU Ha  n0 UR                  U   [4        '   T&R                  U   T   nU1/UR                  U   [4           U'   U1/UR                  U   [4           S'   Mc     UR                   V	s/ s H  oU;  d  M
  U	PM     sn	 HF  n0 UR                  U   [4        '   T&R                  U   T   nU1/UR                  U   [4           U'   MH     [         R6                  " U5         U
" U5      nT&R                  U   T   nSnSn0 n[         R8                  " UU5      nU GH  n[;        UUS-   5       H  n[=        UU5       H  u  nnUUR                  U   [4           ;  d  UUR                  U   [4           ;  a  M<  UR                  U   [4           U   nUR                  U   [4           U   nU" UUUUU5      u  nnUU;  d  UU   S   U:  a  UU4UU'   UU::  d  M  UnUnM     M     UR?                  5        H"  u  nu  nn UUR                  U   [4           U'   M$     URA                  5         GM     UUR                  U   [4           S'   URC                  U5        UU:X  a  UR                  U   [4           S   $ GM  s  snnf s  sn	f )u  Optimal partitioning of a weighted tree using the Lukes algorithm.

This algorithm partitions a connected, acyclic graph featuring integer
node weights and float edge weights. The resulting clusters are such
that the total weight of the nodes in each cluster does not exceed
max_size and that the weight of the edges that are cut by the partition
is minimum. The algorithm is based on [1]_.

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

max_size : int
    Maximum weight a partition can have in terms of sum of
    node_weight for all nodes in the partition

edge_weight : key
    Edge data key to use as weight. If None, the weights are all
    set to one.

node_weight : key
    Node data key to use as weight. If None, the weights are all
    set to one. The data must be int.

Returns
-------
partition : list
    A list of sets of nodes representing the clusters of the
    partition.

Raises
------
NotATree
    If G is not a tree.
TypeError
    If any of the values of node_weight is not int.

References
----------
.. [1] Lukes, J. A. (1974).
   "Efficient Algorithm for the Partitioning of Trees."
   IBM Journal of Research and Development, 18(3), 217–224.

z&lukes_partitioning works only on treesr   r	   Nz9lukes_partitioning needs integer values for node_weight ()
undirectedc              3   t   #    U R                    H$  n[        R                  " X5      (       a  M   Uv   M&     g 7fN)nodesnxdescendants)grxs     r   _leaves#lukes_partitioning.<locals>._leavesv   s)      A>>"(( s   )8	8c                    >^ [        T" U 5      5      m[        U R                  5      T-
   H5  n[        U4S j[        R                  " X5       5       5      (       d  M3  Us  $    g )Nc              3   ,   >#    U  H	  oT;   v   M     g 7fr    ).0r   tleavess     r   	<genexpr>Glukes_partitioning.<locals>._a_parent_of_leaves_only.<locals>.<genexpr>   s     ?)>A<)>s   )setr   allr   r   )r   r   r&   r    s     @r   _a_parent_of_leaves_only4lukes_partitioning.<locals>._a_parent_of_leaves_only}   sG    gbk"RXX(A?)>??? )    c                    > TR                    Vs/ s H  oS   U ;   d  M  US   U ;   d  M  UPM     nn[        UU4S jU 5       5      $ s  snf )Nr   r	   c              3   H   >#    U  H  nTR                   U   T   v   M     g 7fr   )edges)r%   er   safe_Gs     r   r'   @lukes_partitioning.<locals>._value_of_cluster.<locals>.<genexpr>   s     EA6<<?;/   ")r0   sum)clusterr1   valid_edgesr   r2   s      r   _value_of_cluster-lukes_partitioning.<locals>._value_of_cluster   sF    "(,,V,QA$'/qadgoq,VEEEE Ws   A	A	A	c                 .   > [        U4S jU  5       5      $ )Nc              3   F   >#    U  H  nT" [        U5      5      v   M     g 7fr   )	frozenset)r%   cr8   s     r   r'   Blukes_partitioning.<locals>._value_of_partition.<locals>.<genexpr>   s     FIq$Yq\22Is   !r5   )	partitionr8   s    r   _value_of_partition/lukes_partitioning.<locals>._value_of_partition   s    FIFFFr-   c                 0   > [        UU4S jU  5       5      $ )Nc              3   H   >#    U  H  nTR                   U   T   v   M     g 7fr   )r   )r%   r   r   r2   s     r   r'   Alukes_partitioning.<locals>._weight_of_cluster.<locals>.<genexpr>   s     AA6<<?;/r4   r?   )r6   r   r2   s    r   _weight_of_cluster.lukes_partitioning.<locals>._weight_of_cluster   s    AAAAr-   c                 j    U  Vs/ s H  o!U;   d  M
  UPM     nn[        U5      S:X  d   eUS   $ s  snf )Nr	   r   )len)r@   noder=   ccxs       r   _pivot"lukes_partitioning.<locals>._pivot   s8    #1)Qqyq)13x1}}1v 2s   	00c                   >^
^ T" X5      mT" X5      m
TR                  T
5      nT" [        U5      5      U::  aE  [        [        U4S jU 5      5      n[        [        U
4S jU5      5      nU/U-   U-   nUT" U5      4$ X-   n	U	T" U	5      4$ )Nc                    > U T:g  $ r   r$   )r   rK   s    r   <lambda>Clukes_partitioning.<locals>._concatenate_or_merge.<locals>.<lambda>   	    Sr-   c                    > U T:g  $ r   r$   )r   ccis    r   rP   rQ      rR   r-   )unionr<   listfilter)partition_1partition_2r   i
ref_weight	merged_xicp1cp2option_2option_1rT   rK   rL   rA   rF   s             @@r   _concatenate_or_merge1lukes_partitioning.<locals>._concatenate_or_merge   s    [$[$IIcN	 i	23zAv0+>?Cv0+>?C!{S(3.H0:::"0H0:::r-   )"r   is_treeNotATreeis_directed	in_degreerI   r   r   rV   r   dfs_treeset_edge_attributesD_EDGE_VALUED_EDGE_Wset_node_attributesD_NODE_VALUED_NODE_Wget_node_attributesvalues
isinstanceint	TypeErrorr   r   CLUSTER_EVAL_CACHE_SIZEr)   PKEY_clear_cacher   r   r   itemsclearremove_nodes_from)'Gmax_sizer   r   r   droott_G
all_n_attrr   r+   ra   leaveslvslotinnerx_nodeweight_of_x
best_valuebest_partition	bp_bufferx_descendantsi_nodejabpart1part2partvaluewbest_part_for_vlvlr    rL   r8   rA   rF   r2   s'     ``                             @@@@@@r   r   r      sa   ^ ::a==kkBCC>>!"#++-:-$!16A-D:t9>!>7D1+C$qww-(D++a&C k1!""6<B"K""6<B"K ''<CCEJ!S!!++6-q:   & '
 & ' &'F (FG &'B (B
;$ F 		"d||B,&(TF		"dD!#%$		"dA	  !YY:Y6/!Y:!#		%||E";/).y		%t$ ; OOC )#.ll6*;7
	sF3#F;15)![9DAq6!24!88CIIf$5d$;; !IIf-d3A6EIIf-d3A6E"7uffVW"XKD%	)Yq\!_u-D'+U{	! "U*%*
)-' : 64 .7__->))$b-=		&!$'* .?OO; $B &4		&$"m,T> 99T?4(++] M ;~ ;s   (R8R=	R
R)NN)__doc__copyr   	functoolsr   randomr   networkxr   networkx.utilsr   __all__rj   ri   rm   rl   rt   rs   r   _dispatchabler   r$   r-   r   <module>r      sg    C     .
   ]}EF, FF,r-   