U
    ?h                     @   sd   d Z ddlmZ ddlZddlmZ ddlmZm	Z	m
Z
 dgZdd Ze
d	e	d
dddZdS )uB   Functions for computing the Kernighan–Lin bipartition algorithm.    )countN)is_partition)
BinaryHeapnot_implemented_forpy_random_statekernighan_lin_bisectionc                 #   s   t  t  f \}} tt D ]:\}}}tfdd|D } | ||rT|n|  q" fdd}d}	d}
|r|r| \}}||| | \}}||| |
|| 7 }
|	d7 }	|
|	||ffV  qvdS )z
    This is a modified form of Kernighan-Lin, which moves single nodes at a
    time, alternating between sides to keep the bisection balanced.  We keep
    two min-heaps of swap costs to make optimal-next-move selection fast.
    c                 3   s$   | ]\}} | r|n| V  qd S )N ).0vw)sider   ]/var/www/html/venv/lib/python3.8/site-packages/networkx/algorithms/community/kernighan_lin.py	<genexpr>   s     z'_kernighan_lin_sweep.<locals>.<genexpr>c                    s\   | D ]N\}} |  }| |}|d k	r|d| |kr@| n| 7 }|||d qd S )N   T)getinsert)Zcosts_xxyr   Zcosts_yZcost_ycostsedgesr   r   r   _update_costs   s    
z+_kernighan_lin_sweep.<locals>._update_costsr      N)r   zipr   sumr   pop)r   r   Zcosts0Zcosts1uZside_uZedges_uZcost_ur   iZtotcostr
   Zcost_vr   r   r   _kernighan_lin_sweep   s    

r      Zdirected
   weightc              
      s  t  }t }|| dd t|D |dkrVdg|d  dg|d d   }nxz|\}}	W n2 ttfk
r }
 ztd|
W 5 d}
~
X Y nX t ||	fstddg| }|D ]}d|| < q 	 r fd	d
|D }n fdd
|D }t
|D ]`}tt||}t|\}}}|dkr< qn|d| D ] \}}\}}d||< d||< qHqdd t||D }dd t||D }	||	fS )u  Partition a graph into two blocks using the Kernighan–Lin
    algorithm.

    This algorithm partitions a network into two sets by iteratively
    swapping pairs of nodes to reduce the edge cut between the two sets.  The
    pairs are chosen according to a modified form of Kernighan-Lin, which
    moves node individually, alternating between sides to keep the bisection
    balanced.

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

    partition : tuple
        Pair of iterables containing an initial partition. If not
        specified, a random balanced partition is used.

    max_iter : int
        Maximum number of times to attempt swaps to find an
        improvemement before giving up.

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

    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.
        Only used if partition is None

    Returns
    -------
    partition : tuple
        A pair of sets of nodes representing the bipartition.

    Raises
    ------
    NetworkXError
        If partition is not a valid partition of the nodes of the graph.

    References
    ----------
    .. [1] Kernighan, B. W.; Lin, Shen (1970).
       "An efficient heuristic procedure for partitioning graphs."
       *Bell Systems Technical Journal* 49: 291--307.
       Oxford University Press 2011.

    c                 S   s   i | ]\}}||qS r   r   )r	   r   r
   r   r   r   
<dictcomp>a   s      z+kernighan_lin_bisection.<locals>.<dictcomp>Nr   r   r   zpartition must be two setszpartition invalidc                    s(   g | ] }fd d |   D qS )c                    s2   g | ]*\}} | t fd d| D fqS )c                 3   s   | ]}|  d V  qdS )r   Nr   )r	   e)r!   r   r   r   s   s     z@kernighan_lin_bisection.<locals>.<listcomp>.<listcomp>.<genexpr>)r   values)r	   r   dindexr!   r   r   
<listcomp>r   s   6kernighan_lin_bisection.<locals>.<listcomp>.<listcomp>itemsr	   r
   Gr(   r!   r   r   r)   q   s   
z+kernighan_lin_bisection.<locals>.<listcomp>c                    s(   g | ] }fd d |   D qS )c                    s$   g | ]\}} | | d fqS r   r#   )r	   r   r$   r'   r   r   r)   z   s     r*   r+   r-   r.   r   r   r)   y   s    c                 S   s   h | ]\}}|d kr|qS )r   r   r	   r   sr   r   r   	<setcomp>   s      z*kernighan_lin_bisection.<locals>.<setcomp>c                 S   s   h | ]\}}|d kr|qS r0   r   r1   r   r   r   r3      s      )lenlistshuffle	enumerate	TypeError
ValueErrornxZNetworkXErrorr   Zis_multigraphranger   minr   )r/   	partitionZmax_iterr!   seednlabelsr   ABerrar   r   r   Zmin_costZmin_i_r   r
   r   r.   r   r   +   sB    3
"


)Nr    r!   N)__doc__	itertoolsr   Znetworkxr:   Z-networkx.algorithms.community.community_utilsr   Znetworkx.utilsr   r   r   __all__r   r   r   r   r   r   <module>   s   