
    Gd                         d Z ddlZddlmZ g dZej        d             Zej         ed          d                         Z ed           ed          dd
                        Z	dS )z5Functions for computing and verifying regular graphs.    N)not_implemented_for)
is_regularis_k_regulark_factorc                    t           j                            |           }|                                 s5|                     |          t          fd| j        D                       S |                     |          t          fd| j        D                       }|                     |          t          fd| j        D                       }|o|S )a  Determines whether the graph ``G`` is a regular graph.

    A regular graph is a graph where each vertex has the same degree. A
    regular digraph is a graph where the indegree and outdegree of each
    vertex are equal.

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

    Returns
    -------
    bool
        Whether the given graph or digraph is regular.

    Examples
    --------
    >>> G = nx.DiGraph([(1, 2), (2, 3), (3, 4), (4, 1)])
    >>> nx.is_regular(G)
    True

    c              3   *   K   | ]\  }}|k    V  d S N ).0_dd1s      ;lib/python3.11/site-packages/networkx/algorithms/regular.py	<genexpr>zis_regular.<locals>.<genexpr>#   s+      00tq!27000000    c              3   *   K   | ]\  }}|k    V  d S r	   r
   )r   r   r   d_ins      r   r   zis_regular.<locals>.<genexpr>&   s+      ;;tq!;;;;;;r   c              3   *   K   | ]\  }}|k    V  d S r	   r
   )r   r   r   d_outs      r   r   zis_regular.<locals>.<genexpr>(   s+      >>A%1*>>>>>>r   )nxutilsarbitrary_elementis_directeddegreeall	in_degree
out_degree)Gn1
in_regularout_regularr   r   r   s       @@@r   r   r      s    0 
	#	#A	&	&B==?? *XXb\\0000qx000000{{2;;;;q{;;;;;
R  >>>>>>>>>)k)r   directedc                 D    t          fd| j        D                       S )a  Determines whether the graph ``G`` is a k-regular graph.

    A k-regular graph is a graph where each vertex has degree k.

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

    Returns
    -------
    bool
        Whether the given graph is k-regular.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (2, 3), (3, 4), (4, 1)])
    >>> nx.is_k_regular(G, k=3)
    False

    c              3   *   K   | ]\  }}|k    V  d S r	   r
   )r   nr   ks      r   r   zis_k_regular.<locals>.<genexpr>C   s+      ++$!QqAv++++++r   )r   r   )r   r&   s    `r   r   r   ,   s*    . ++++!(++++++r   
multigraphweightc                    ddl m}m}  G fdd          } G d d          }t          fd| j        D                       rt          j        d          |                                 g }t          j                  D ]T\  }}	|	d	z  k     r ||	|          }
n ||	|          }
|
	                                 |
                    |
           U |d
|          } ||          st          j        d                                          D ]:}||vr4|d         |d         f|vr"                    |d         |d                    ;|D ]}
|
                                 S )u  Compute a k-factor of G

    A k-factor of a graph is a spanning k-regular subgraph.
    A spanning k-regular subgraph of G is a subgraph that contains
    each vertex of G and a subset of the edges of G such that each
    vertex has degree k.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    matching_weight: string, optional (default='weight')
       Edge data key corresponding to the edge weight.
       Used for finding the max-weighted perfect matching.
       If key not found, uses 1 as weight.

    Returns
    -------
    G2 : NetworkX graph
        A k-factor of G

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (2, 3), (3, 4), (4, 1)])
    >>> G2 = nx.k_factor(G, k=1)
    >>> G2.edges()
    EdgeView([(1, 2), (3, 4)])

    References
    ----------
    .. [1] "An algorithm for computing simple k-factors.",
       Meijer, Henk, Yurai Núñez-Rodríguez, and David Rappaport,
       Information processing letters, 2009.
    r   )is_perfect_matchingmax_weight_matchingc                   &    e Zd Zd Zd Z fdZdS )k_factor.<locals>.LargeKGadgetc                     | _         || _        || _        | _        fdt	                    D             | _        fdt	          |z
            D             | _        d S )Nc                     g | ]}|fS r
   r
   r   xnodes     r   
<listcomp>z;k_factor.<locals>.LargeKGadget.__init__.<locals>.<listcomp>v       "D"D"DD!9"D"D"Dr   c                     g | ]	}|z   f
S r
   r
   r   r1   r   r2   s     r   r3   z;k_factor.<locals>.LargeKGadget.__init__.<locals>.<listcomp>w   s"    !P!P!P4V"4!P!P!Pr   )originalgr&   r   rangeouter_verticescore_verticesselfr&   r   r2   r8   s     `` r   __init__z'k_factor.<locals>.LargeKGadget.__init__p   ss     DMDFDF DK"D"D"D"DeFmm"D"D"DD!P!P!P!P!PeFQJ>O>O!P!P!PDr   c                    | j         | j                 }t          |                                          }t          |                                          }t          | j        ||          D ]\  }}} | j         j        ||fi | | j        D ]'}| j        D ]}| j                             ||           (| j         	                    | j                   d S r	   )
r8   r7   listkeysvalueszipr:   add_edger;   remove_node)r=   adj_view	neighbors
edge_attrsouterneighborcores          r   replace_nodez+k_factor.<locals>.LargeKGadget.replace_nodey   s    vdm,HX]]__--Ihoo//00J/2#Y
0 0 ? ?+x  x>>:>>>>* 1 1!0 1 1EFOOD%00001Ft}-----r   c                 r   | j                             | j                   | j        D ]Z}| j         |         }t	          |                                          D ])\  }}|| j        vr | j         j        | j        |fi |  n*[                    | j                                       | j                   d S r	   )	r8   add_noder7   r:   r@   itemsr;   rD   remove_nodes_from)r=   rI   rF   rJ   rH   r8   s        r   restore_nodez+k_factor.<locals>.LargeKGadget.restore_node   s    FOODM***,  6%=,01A1A,B,B  (Hjt'999'xNN:NNN :  3444 233333r   N__name__
__module____qualname__r>   rL   rQ   )r8   s   r   LargeKGadgetr-   o   sO        	Q 	Q 	Q	. 	. 	.		4 		4 		4 		4 		4 		4 		4r   rV   c                        e Zd Zd Zd Zd ZdS )k_factor.<locals>.SmallKGadgetc                    | _         || _        | _        || _        fdt	                    D             | _        fdt	                    D             | _        fdt	          |          D             | _        d S )Nc                     g | ]}|fS r
   r
   r0   s     r   r3   z;k_factor.<locals>.SmallKGadget.__init__.<locals>.<listcomp>   r4   r   c                     g | ]	}|z   f
S r
   r
   r6   s     r   r3   z;k_factor.<locals>.SmallKGadget.__init__.<locals>.<listcomp>   s"    "M"M"M!D!f*#5"M"M"Mr   c                 $    g | ]}|d z  z   fS )   r
   r6   s     r   r3   z;k_factor.<locals>.SmallKGadget.__init__.<locals>.<listcomp>   s&    !K!K!KQ4QZ"8!K!K!Kr   )r7   r&   r   r8   r9   r:   inner_verticesr;   r<   s     `` r   r>   z'k_factor.<locals>.SmallKGadget.__init__   s     DMDF DKDF"D"D"D"DeFmm"D"D"DD"M"M"M"M"MuV}}"M"M"MD!K!K!K!K!K%((!K!K!KDr   c                    | j         | j                 }t          | j        | j        t          |                                                    D ]8\  }}\  }}| j                             ||            | j         j        ||fi | 9| j        D ]'}| j        D ]}| j                             ||           (| j         	                    | j                   d S r	   )
r8   r7   rC   r:   r^   r@   rO   rD   r;   rE   )r=   rF   rI   innerrJ   rH   rK   s          r   rL   z+k_factor.<locals>.SmallKGadget.replace_node   s    vdm,H8;#T%8$x~~?O?O:P:P9 9 ? ?4u4x u---x>>:>>>>* 1 1!0 1 1EFOOD%00001Ft}-----r   c                    | j                             | j                   | j        D ]M}| j         |         }|                                D ])\  }}|| j        vr | j         j        | j        |fi |  n*N| j                             | j                   | j                             | j                   | j                             | j                   d S r	   )	r8   rN   r7   r:   rO   r;   rD   rP   r^   )r=   rI   rF   rJ   rH   s        r   rQ   z+k_factor.<locals>.SmallKGadget.restore_node   s    FOODM***,  6%=,4NN,<,<  (Hjt'999'xNN:NNN : F$$T%8999F$$T%8999F$$T%788888r   NrR   r
   r   r   SmallKGadgetrX      sD        	L 	L 	L
	. 
	. 
	.
	9 
	9 
	9 
	9 
	9r   rb   c              3   *   K   | ]\  }}|k     V  d S r	   r
   )r   r   r   r&   s      r   r   zk_factor.<locals>.<genexpr>   s+      
&
&TQ1q5
&
&
&
&
&
&r   z/Graph contains a vertex with degree less than kg       @T)maxcardinalityr(   z7Cannot find k-factor because no perfect matching exists   )networkx.algorithms.matchingr*   r+   anyr   r   NetworkXUnfeasiblecopyr@   rL   appendedgesremove_edgerQ   )r   r&   matching_weightr*   r+   rV   rb   gadgetsr2   r   gadgetmatchingedger8   s    `           @r   r   r   F   s   N VUUUUUUU 4  4  4  4  4  4  4  4  4  4D!9 !9 !9 !9 !9 !9 !9 !9H 
&
&
&
&QX
&
&
&&& W#$UVVV	A GQX  fv|!\!VT155FF!\!VT155Fv #"1T/RRRH q(++ 
#E
 
 	
 		 , ,xT!Wd1g$6h$F$FMM$q'47+++  Hr   )r(   )
__doc__networkxr   networkx.utilsr   __all__	_dispatchr   r   r   r
   r   r   <module>rw      s    ; ;     . . . . . .
4
4
4  *  *  *F Z  , , !  ,0 Z  \""K K K #" ! K K Kr   