o
    ]Zh                     @   s~   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d ZejddddddZdS )z=Lukes Algorithm for exact optimal weighted tree partitioning.    )deepcopy)	lru_cache)choiceN)not_implemented_forlukes_partitioningweightg      ?   Z
partitionsi   c                 c   s4    | |ksJ t || d D ]	}|| | fV  qd S )Nr   )range)nZmin_size_of_first_partp1 r   R/var/www/auris/lib/python3.10/site-packages/networkx/algorithms/community/lukes.py_split_n_from   s
   r   node_weightedge_weight)Z
node_attrsZ
edge_attrsc              	      s  t | s
t dt | r)dd |  D }t|dks J |d }t| }ntt| j	}t 
| |}du s>du r]t| du rOt tt tdu r\t tt tn| t  }|D ]}t|tsxtd dqitd	d
d  td	 fdd}ttfddfddttfdddd fdd}	t |D ]&}
i |j	|
 t< j	|
  }|
hg|j	|
 t |< |
hg|j	|
 t d< qfdd|j	D D ]}i |j	| t< j	|  }|hg|j	| t |< qt | 	 ||}j	|  }d}d}i }t ||}|D ]}t||d D ]]}t||D ]T\}}||j	| t vsO||j	| t vrQq7|j	| t | }|j	| t | }|	|||||\}}||vs{|| d |k r||f||< ||kr|}|}q7q0| D ]\}\}}||j	| t |< q|   q'||j	| t d< |!| ||kr|j	| t d S q)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 treesc                 S   s   g | ]
\}}|d kr|qS )r   r   ).0r
   dr   r   r   
<listcomp>O   s    z&lukes_partitioning.<locals>.<listcomp>r   r   Nz9lukes_partitioning needs integer values for node_weight ()Z
undirectedc                 s   s$    | j D ]}t| |s|V  qd S N)nodesnxdescendants)grxr   r   r   _leavesv   s   
z#lukes_partitioning.<locals>._leavesc                    sJ   t |  t | j  D ]}t fddt| |D r"|  S qd S )Nc                 3   s    | ]}| v V  qd S r   r   r   r   Ztleavesr   r   	<genexpr>   s    zGlukes_partitioning.<locals>._a_parent_of_leaves_only.<locals>.<genexpr>)setr   allr   r   )r   r
   )r   r   r   _a_parent_of_leaves_only}   s   z4lukes_partitioning.<locals>._a_parent_of_leaves_onlyc                    s,    fddj D }tfdd|D S )Nc                    s(   g | ]}|d   v r|d  v r|qS )r   r   r   r   eclusterr   r   r      s   ( zAlukes_partitioning.<locals>._value_of_cluster.<locals>.<listcomp>c                 3       | ]
}j |   V  qd S r   )edgesr"   r   safe_Gr   r   r          z@lukes_partitioning.<locals>._value_of_cluster.<locals>.<genexpr>)r'   sum)r%   Zvalid_edgesr(   r$   r   _value_of_cluster   s   z-lukes_partitioning.<locals>._value_of_clusterc                    s   t  fdd| D S )Nc                 3   s    | ]	} t |V  qd S r   )	frozensetr   cr,   r   r   r      s    zBlukes_partitioning.<locals>._value_of_partition.<locals>.<genexpr>r+   )	partitionr0   r   r   _value_of_partition   s   z/lukes_partitioning.<locals>._value_of_partitionc                    s   t  fdd| D S )Nc                 3   r&   r   )r   )r   r
   r   r)   r   r   r      r*   zAlukes_partitioning.<locals>._weight_of_cluster.<locals>.<genexpr>r1   r$   r4   r   r   _weight_of_cluster   s   z.lukes_partitioning.<locals>._weight_of_clusterc                    s*    fdd| D }t |dksJ |d S )Nc                    s   g | ]} |v r|qS r   r   r.   noder   r   r          z6lukes_partitioning.<locals>._pivot.<locals>.<listcomp>r   r   )len)r2   r7   ccxr   r6   r   _pivot   s   z"lukes_partitioning.<locals>._pivotc           
         s   | |||   }t||kr:ttfdd| }tt fdd|}|g| | }||fS | | }	|	|	fS )Nc                       |  kS r   r   r   )r:   r   r   <lambda>       zClukes_partitioning.<locals>._concatenate_or_merge.<locals>.<lambda>c                    r<   r   r   r=   )ccir   r   r>      r?   )unionr-   listfilter)
Zpartition_1Zpartition_2r   iZ
ref_weightZ	merged_xiZcp1Zcp2Zoption_2Zoption_1)r;   r3   r5   )r@   r:   r   _concatenate_or_merge   s   


z1lukes_partitioning.<locals>._concatenate_or_mergec                    s   g | ]}| vr|qS r   r   r   )leavesr   r   r      r8   )"r   Zis_treeZNotATreeZis_directedZ	in_degreer9   r   r   rB   r   Zdfs_treeZset_edge_attributesD_EDGE_VALUED_EDGE_WZset_node_attributesD_NODE_VALUED_NODE_WZget_node_attributesvalues
isinstanceint	TypeErrorr   r   CLUSTER_EVAL_CACHE_SIZEr   PKEY_clear_cacher   r	   r   itemsclearZremove_nodes_from)Gmax_sizer   r   rootZt_GZ
all_n_attrr   r!   rE   lvZslotinnerZx_nodeZweight_of_xZ
best_valueZbest_partitionZ	bp_bufferZx_descendantsZi_nodejabZpart1Zpart2partvaluewZbest_part_for_vlZvlr   )	r   r;   r,   r3   r5   r   rF   r   r)   r   r      s   
/








)NN)__doc__copyr   	functoolsr   randomr   Znetworkxr   Znetworkx.utilsr   __all__rH   rG   rJ   rI   rP   rO   r   Z_dispatchabler   r   r   r   r   <module>   s     