3
Md}                 @   sn   d Z ddlmZ ddlZdddddd	gZG d
d dZG dd dZG dd dZdd Z	dd Z
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| j  d S )N)r	   _rewind)selfedges r   P/var/www/html/virt/lib/python3.6/site-packages/networkx/algorithms/flow/utils.py__init__   s    zCurrentEdge.__init__c             C   s   | j S )N)r   )r   r   r   r   get   s    zCurrentEdge.getc             C   s4   yt | j| _W n tk
r.   | j   Y nX d S )N)nextr
   r   StopIterationr   )r   r   r   r   move_to_next!   s
    zCurrentEdge.move_to_nextc             C   s    t | jj | _t| j| _d S )N)iterr	   itemsr
   r   r   )r   r   r   r   r   (   s    zCurrentEdge._rewindN)r	   r
   r   )	__name__
__module____qualname____doc__	__slots__r   r   r   r   r   r   r   r   r      s   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 )N)setr   r   )r   r   r   r   r   3   s    zLevel.__init__N)r   r   )r   r   r   r   r   r   r   r   r   r   r   -   s   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 )N)r#   )r   Zworkr   r   r   add_workA   s    zGlobalRelabelThreshold.add_workc             C   s   | j | jkS )N)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
   c                s*  | j  rtjdtj }|j|  td fdd| jddD }dt fdd	|D  pfd
| j rx|D ]Z\}}}t	|j
 }|j||s|j|||d |j||dd qv||| | d< qvW nFxD|D ]<\}}}t	|j
 }|j|||d |j|||d qW |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|j  d kr|||fqS )r   )r   ).0uvattr)capacityr    r   r   
<listcomp>m   s   z*build_residual_network.<locals>.<listcomp>T)data   c             3   s0   | ](\}}} |kr|  kr|  V  qd S )Nr   )r*   r+   r,   r-   )r.   r    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_listr+   r,   r-   rr   )r.   r    r   r   K   s2    


c       	      C   s   t |g}|h}| jd }xd|r~|j }xR| | j D ]B\}}|d |kr6||kr6||krdtjd|j| |j| q6W qW dS )z/Detect an infinite-capacity s-t path in R.
    r    r.   z-Infinite capacity path, flow unbounded above.N)r   r7   popleftr   r4   ZNetworkXUnboundedaddappend)	r9   stqseenr    r+   r,   r-   r   r   r   r      s    


c             C   sL   i }xB| D ]:}dd | | D ||< || j dd || j D  q
W |S )z5Build a flow dictionary from a residual network.
    c             S   s   i | ]
}d |qS )r   r   )r*   r,   r   r   r   
<dictcomp>   s    z#build_flow_dict.<locals>.<dictcomp>c             s   s*   | ]"\}}|d  dkr||d  fV  qdS )Zflowr   Nr   )r*   r,   r-   r   r   r   r2      s    z"build_flow_dict.<locals>.<genexpr>)updater   )r8   r9   Z	flow_dictr+   r   r   r   r      s    
)r   collectionsr   Znetworkxr4   __all__r   r   r   r   r   r   r   r   r   r   <module>   s   Q