U
    9%e`                     @   sp   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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   s2   | |kst t|| d D ]}|| | fV  qd S )Nr   )AssertionErrorrange)nZmin_size_of_first_partp1 r   b/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/networkx/algorithms/community/lukes.py_split_n_from   s    r   c              	      s  t | st dnXt | rTdd |  D }t|dksBt|d }t| }ntt	| j
}t | |}dks~dkrt| dkrt tt tdkrt tt tn| t  }|D ]}t|tstd dqt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 ]N}
i |j
|
 t< j
|
  }|
hg|j
|
 t |< |
hg|j
|
 t d< qxfdd|j
D D ]8}i |j
| t< j
|  }|hg|j
| t |< q||}j
|  }d}d}i }t ||}|D ]}t||d D ]}t||D ]\}}||j
| t  ksj||j
| t  krqj|j
| t | }|j
| t | }|	|||||\}}|| ks|| d |k r
||f||< ||krj|}|}qjq\|  D ] \}\}}||j
| t |< q,|!  qH||j
| t d< |"| ||kr|j
| t d S qdS )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 LUKES[1].

    Parameters
    ----------
    G : 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
    ----------
    .. 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>N   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   _leavesu   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   | ]}| k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   kr|d  kr|qS )r   r   r   r   eclusterr   r   r      s       zAlukes_partitioning.<locals>._value_of_cluster.<locals>.<listcomp>c                 3   s   | ]}j |   V  qd S r   )edgesr!   edge_weightsafe_Gr   r   r      s     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)   )	partitionr.   r   r   _value_of_partition   s    z/lukes_partitioning.<locals>._value_of_partitionc                    s   t  fdd| D S )Nc                 3   s   | ]}j |   V  qd S r   )r   )r   r   node_weightr(   r   r   r      s     zAlukes_partitioning.<locals>._weight_of_cluster.<locals>.<genexpr>r/   r#   r2   r   r   _weight_of_cluster   s    z.lukes_partitioning.<locals>._weight_of_clusterc                    s*    fdd| D }t |dks"t|d S )Nc                    s   g | ]} |kr|qS r   r   r,   noder   r   r      s      z6lukes_partitioning.<locals>._pivot.<locals>.<listcomp>r   r   )lenr	   )r0   r6   ccxr   r5   r   _pivot   s    z"lukes_partitioning.<locals>._pivotc           
         s   | |||   }t||krtttfdd| }tt fdd|}|g| | }||fS | | }	|	|	fS d S )Nc                    s   |  kS r   r   r   )r8   r   r   <lambda>       zClukes_partitioning.<locals>._concatenate_or_merge.<locals>.<lambda>c                    s   |  kS 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)r9   r1   r4   )r=   r8   r   _concatenate_or_merge   s    


z1lukes_partitioning.<locals>._concatenate_or_mergec                    s   g | ]}| kr|qS r   r   r   )leavesr   r   r      s      )#r   Zis_treeZNotATreeZis_directedZ	in_degreer7   r	   r   r   r?   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   PKEYr   r
   r   keysitemsclearZremove_nodes_from)Gmax_sizer3   r'   rootZt_GZ
all_n_attrr   r    rB   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   r9   r*   r1   r4   r'   rC   r3   r(   r   r      s    .







 


)NN)__doc__copyr   	functoolsr   randomr   Znetworkxr   Znetworkx.utilsr   __all__rE   rD   rG   rF   rM   rL   r   r   r   r   r   r   <module>   s   