a
    h                     @   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_partitioningZweightg      ?   Z
partitionsi   c                 c   s2   | |ksJ t || d D ]}|| | fV  qd S )Nr   )range)nZmin_size_of_first_partp1 r   Q/var/www/auris/lib/python3.9/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nXt | rTdd |  D }t|dksBJ |d }t| }ntt| j	}t 
| |}du s~du rt| du rt tt tdu 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 vsj||j	| t vrqj|j	| t | }|j	| t | }|	|||||\}}||v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 [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       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>   r   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      r   zAlukes_partitioning.<locals>._value_of_cluster.<locals>.<listcomp>c                 3   s   | ]}j |   V  qd S r   )edgesr"   r   safe_Gr   r   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      r   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	   r   r(   r   r   r      r   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"J |d S )Nc                    s   g | ]} |v r|qS r   r   r,   noder   r   r      r   z6lukes_partitioning.<locals>._pivot.<locals>.<listcomp>r   r   )len)r0   r5   ccxr   r4   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   )r7   r   r   <lambda>   r   zClukes_partitioning.<locals>._concatenate_or_merge.<locals>.<lambda>c                    s   |  kS r   r   r9   )ccir   r   r:      r   )unionr+   listfilter)
Zpartition_1Zpartition_2r   iZ
ref_weightZ	merged_xiZcp1Zcp2Zoption_2Zoption_1)r8   r1   r3   )r;   r7   r   _concatenate_or_merge   s    


z1lukes_partitioning.<locals>._concatenate_or_mergec                    s   g | ]}| vr|qS r   r   r   )leavesr   r   r      r   )!r   Zis_treeZNotATreeZis_directedZ	in_degreer6   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   itemsclearZremove_nodes_from)Gmax_sizer   r   rootZt_GZ
all_n_attrr   r!   r@   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   r8   r*   r1   r3   r   rA   r   r(   r   r      s    /









)NN)__doc__copyr   	functoolsr   randomr   Znetworkxr   Znetworkx.utilsr   __all__rC   rB   rE   rD   rK   rJ   r   	_dispatchr   r   r   r   r   <module>   s   