o
    &?eq                     @   s   d Z ddlmZ ddlZg dZG dd dZG dd dZG d	d
 d
Zej	de
diddd Zej	ddde
diidddd Zej	ddddddiiddd ZdS )z<
Utility classes and functions for network flow algorithms.
    )dequeN)CurrentEdgeLevelGlobalRelabelThresholdbuild_residual_networkdetect_unboundednessbuild_flow_dictc                   @   s4   e Zd ZdZdZdd Zdd Zdd Zd	d
 ZdS )r   zMechanism for iterating over out-edges incident to a node in a circular
    manner. StopIteration exception is raised when wraparound occurs.
    )_edges_it_currc                 C   s   || _ | j r|   d S d S N)r	   _rewind)selfedges r   _/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/networkx/algorithms/flow/utils.py__init__   s   zCurrentEdge.__init__c                 C   s   | j S r   )r   r   r   r   r   get   s   zCurrentEdge.getc                 C   s,   z	t | j| _W d S  ty   |    w r   )nextr
   r   StopIterationr   r   r   r   r   move_to_next"   s   zCurrentEdge.move_to_nextc                 C   s    t | j | _t| j| _d S r   )iterr	   itemsr
   r   r   r   r   r   r   r   )   s   zCurrentEdge._rewindN)	__name__
__module____qualname____doc__	__slots__r   r   r   r   r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdZdd ZdS )r   z%Active and inactive nodes in a level.)activeinactivec                 C   s   t  | _t  | _d S r   )setr   r    r   r   r   r   r   3   s   zLevel.__init__N)r   r   r   r   r   r   r   r   r   r   r   .   s    r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   zVMeasurement of work before the global relabeling heuristic should be
    applied.
    c                 C   s$   |r|| | nt d| _d| _d S )Ninfr   )float
_threshold_work)r   nmfreqr   r   r   r   =   s   
zGlobalRelabelThreshold.__init__c                 C   s   |  j |7  _ d S r   r%   )r   Zworkr   r   r   add_workA   s   zGlobalRelabelThreshold.add_workc                 C   s   | j | jkS r   )r%   r$   r   r   r   r   
is_reachedD   s   z!GlobalRelabelThreshold.is_reachedc                 C   s
   d| _ d S )Nr   r)   r   r   r   r   
clear_workG   s   
z!GlobalRelabelThreshold.clear_workN)r   r   r   r   r   r*   r+   r,   r   r   r   r   r   8   s    r   capacityr"   )Z
edge_attrsc                    s"  |   r	tdt }||  td fdd| jddD }dt fdd	|D  p3d
|  ri|D ]-\}}}t	|
 }|||s_|j|||d |j||dd q:||| | d< q:n!|D ]\}}}t	|
 }|j|||d |j|||d qk|jd< |S )a  Build a residual network and initialize a zero flow.

    The residual network :samp:`R` from an input graph :samp:`G` has the
    same nodes as :samp:`G`. :samp:`R` is a DiGraph that contains a pair
    of edges :samp:`(u, v)` and :samp:`(v, u)` iff :samp:`(u, v)` is not a
    self-loop, and at least one of :samp:`(u, v)` and :samp:`(v, u)` exists
    in :samp:`G`.

    For each edge :samp:`(u, v)` in :samp:`R`, :samp:`R[u][v]['capacity']`
    is equal to the capacity of :samp:`(u, v)` in :samp:`G` if it exists
    in :samp:`G` or zero otherwise. If the capacity is infinite,
    :samp:`R[u][v]['capacity']` will have a high arbitrary finite value
    that does not affect the solution of the problem. This value is stored in
    :samp:`R.graph['inf']`. For each edge :samp:`(u, v)` in :samp:`R`,
    :samp:`R[u][v]['flow']` represents the flow function of :samp:`(u, v)` and
    satisfies :samp:`R[u][v]['flow'] == -R[v][u]['flow']`.

    The flow value, defined as the total flow into :samp:`t`, the sink, is
    stored in :samp:`R.graph['flow_value']`. If :samp:`cutoff` is not
    specified, reachability to :samp:`t` using only edges :samp:`(u, v)` such
    that :samp:`R[u][v]['flow'] < R[u][v]['capacity']` induces a minimum
    :samp:`s`-:samp:`t` cut.

    z0MultiGraph and MultiDiGraph not supported (yet).r"   c                    s4   g | ]\}}}||kr|  d kr|||fqS r   )r   .0uvattrr-   r"   r   r   
<listcomp>m   s    z*build_residual_network.<locals>.<listcomp>T)data   c                 3   s2    | ]\}}} |v r|  kr|  V  qd S r   r   r/   r4   r   r   	<genexpr>~   s    

z)build_residual_network.<locals>.<genexpr>   )r-   r   r-   )Zis_multigraphnxZNetworkXErrorZDiGraphZadd_nodes_fromr#   r   sumZis_directedminr   Zhas_edgeZadd_edgegraph)Gr-   RZ	edge_listr1   r2   r3   rr   r4   r   r   K   s:   


	
r   r?   T)graphspreserve_edge_attrsZpreserve_graph_attrsc           	      C   s   t |g}|h}| jd }|r?| }| |  D ]!\}}|d |kr:||vr:||kr0td|| || q|sdS dS )z*Detect an infinite-capacity s-t path in R.r"   r-   z-Infinite capacity path, flow unbounded above.N)r   r=   popleftr   r:   ZNetworkXUnboundedaddappend)	r?   stqseenr"   r1   r2   r3   r   r   r   r      s   



r   r9   )r>   r?   flow)rA   rB   c                 C   sH   i }| D ]}dd | | D ||< ||  dd ||  D  q|S )z0Build a flow dictionary from a residual network.c                 S   s   i | ]}|d qS r.   r   )r0   r2   r   r   r   
<dictcomp>   s    z#build_flow_dict.<locals>.<dictcomp>c                 s   s,    | ]\}}|d  dkr||d  fV  qdS )rJ   r   Nr   )r0   r2   r3   r   r   r   r8      s    

z"build_flow_dict.<locals>.<genexpr>)updater   )r>   r?   Z	flow_dictr1   r   r   r   r      s   

r   )r   collectionsr   Znetworkxr:   __all__r   r   r   	_dispatchr#   r   r   r   r   r   r   r   <module>   s"    


Q
