
    wg                         d Z ddlmZ ddlmZ ddlmZ ddlZddl	m
Z
 dgZdZd	ZdZd
ZdZdZd Z ej&                  dd      dd       Zy)z=Lukes Algorithm for exact optimal weighted tree partitioning.    )deepcopy)	lru_cache)choiceN)not_implemented_forlukes_partitioningweightg      ?   
partitionsi   c              #   T   K   | |k\  sJ t        || dz         D ]  }|| |z
  f  y w)Nr	   )range)nmin_size_of_first_partp1s      h/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/algorithms/community/lukes.py_split_n_fromr      s@      &&&&*AE2 !b&js   &(node_weightedge_weight)
node_attrs
edge_attrsc           
        !"#$%& t        j                  |       st        j                  d      t        j                  |       rI| j	                         D cg c]  \  }}|dk(  s| }}}t        |      dk(  sJ |d   }t        |       }n4t        t        | j                              }t        j                  | |      }Zt        |       &%t        j                  &t        t               t        (t        j                  &t        t                t         n| &t        j"                  &      j%                         }|D ]!  }	t'        |	t(              rt+        d d       t-        d      d        !t-        d      !fd	       }
t/        t0              &fd
       ##fd$t/        t0              &fd       %d ""$%fd}t3         !|            }|D ]`  }i |j                  |   t4        <   &j                  |      }|hg|j                  |   t4           |<   |hg|j                  |   t4           d<   b |j                  D 	cg c]	  }	|	|vs|	 c}	D ]E  }i |j                  |   t4        <   &j                  |      }|hg|j                  |   t4           |<   G t        j6                  |       	  |
|      }&j                  |      }d}d}i }t        j8                  ||      }|D ]  }t;        ||dz         D ]  }t=        ||      D ]  \  }}||j                  |   t4           vs||j                  |   t4           vr7|j                  |   t4           |   }|j                  |   t4           |   } ||||||      \  }}||vs||   d   |k  r||f||<   ||k  s|}|}  |j?                         D ]!  \  }\  }} ||j                  |   t4           |<   # |jA                           ||j                  |   t4           d<   |jC                  |       ||k(  r|j                  |   t4           d   S c c}}w c c}	w )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   d   K   | j                   D ]  }t        j                  | |      r|  y wN)nodesnxdescendants)grxs     r   _leavesz#lukes_partitioning.<locals>._leavesv   s.       	A>>"a(	s   &00c                     t         |             t        | j                        z
  D ].  }t        fdt        j                  | |      D              s,|c S  y )Nc              3   &   K   | ]  }|v  
 y wr    ).0r   tleavess     r   	<genexpr>zGlukes_partitioning.<locals>._a_parent_of_leaves_only.<locals>.<genexpr>   s     ?A1<?s   )setr   allr   r   )r   r   r%   r    s     @r   _a_parent_of_leaves_onlyz4lukes_partitioning.<locals>._a_parent_of_leaves_only}   sK    gbk"RXX( 	A?A)>??	    c                     j                   D cg c]  }|d   | v s|d   | v s| }}t        fd|D              S c c}w )Nr   r	   c              3   B   K   | ]  }j                   |        y wr   )edges)r$   er   safe_Gs     r   r&   z@lukes_partitioning.<locals>._value_of_cluster.<locals>.<genexpr>   s     EA6<<?;/E   )r-   sum)clusterr.   valid_edgesr   r/   s      r   _value_of_clusterz-lukes_partitioning.<locals>._value_of_cluster   sE    "(,,VQ!A$'/adgoqVVEEEE Ws   A A A c                 ,    t        fd| D              S )Nc              3   @   K   | ]  } t        |              y wr   )	frozenset)r$   cr4   s     r   r&   zBlukes_partitioning.<locals>._value_of_partition.<locals>.<genexpr>   s     Fq$Yq\2Fs   r1   )	partitionr4   s    r   _value_of_partitionz/lukes_partitioning.<locals>._value_of_partition   s    FIFFFr*   c                 .    t        fd| D              S )Nc              3   B   K   | ]  }j                   |        y wr   )r   )r$   r   r   r/   s     r   r&   zAlukes_partitioning.<locals>._weight_of_cluster.<locals>.<genexpr>   s     AA6<<?;/Ar0   r9   )r2   r   r/   s    r   _weight_of_clusterz.lukes_partitioning.<locals>._weight_of_cluster   s    AAAAr*   c                 ^    | D cg c]	  }||v s| }}t        |      dk(  sJ |d   S c c}w )Nr	   r   )len)r:   noder8   ccxs       r   _pivotz"lukes_partitioning.<locals>._pivot   s9    #1Qtqyq113x1}}1v 2s   	**c                   
  | |       ||      
j                  
      } t        |            |k  rCt        t        fd|             }t        t        
fd|            }|g|z   |z   }| |      fS | |z   }	|	 |	      fS )Nc                     | k7  S r   r#   )r   rB   s    r   <lambda>zClukes_partitioning.<locals>._concatenate_or_merge.<locals>.<lambda>       S r*   c                     | k7  S r   r#   )r   ccis    r   rF   zClukes_partitioning.<locals>._concatenate_or_merge.<locals>.<lambda>   rG   r*   )unionr7   listfilter)partition_1partition_2r   i
ref_weight	merged_xicp1cp2option_2option_1rI   rB   rC   r;   r>   s             @@r   _concatenate_or_mergez1lukes_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_degreer@   r   r   rK   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)   rV   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    rC   r4   r;   r>   r/   s'     ``                             @@@@@@r   r   r      s|   ^ ::a=kkBCC>>!"#++-:$!Q1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:!6/!: 1!#		%||E";/).y		%t$1 OOC )#.ll6*;7
	sF3# 	F;15 .)![9 .DAq6!24!88CIIf$5d$;; !IIf-d3A6EIIf-d3A6E"7uffVW"XKD%	)Yq\!_u-D'+U{	! "U*%*
)-'..4 .7__-> >))$b-=		&!$'*>OO;	B &4		&$"m,T> 99T?4(++] M ;~ ;s   Q)Q	Q Q)NN)__doc__copyr   	functoolsr   randomr   networkxr   networkx.utilsr   __all__r^   r]   ra   r`   rh   rg   r   _dispatchabler   r#   r*   r   <module>r      si    C     .
   ]}EF, FF,r*   