U
    td,                     @   sz   d Z ddlmZ ddlmZ G dd deZG dd deZdd	 ZdddZdddZ	dddZ
dddZdddZd
S )z.Classes representing cuts and flows on graphs.    )	GraphBase)VertexClusteringc                       sb   e Zd ZdZd fdd	Zdd Zdd Zed	d
 Zedd Z	edd Z
edd Z  ZS )Cuta  A cut of a given graph.

    This is a simple class used to represent cuts returned by
    L{Graph.mincut()}, L{Graph.all_st_cuts()} and other functions
    that calculate cuts.

    A cut is a special vertex clustering with only two clusters.
    Besides the usual L{VertexClustering} methods, it also has the
    following attributes:

      - C{value} - the value (capacity) of the cut. It is equal to
        the number of edges if there are no capacities on the
        edges.

      - C{partition} - vertex IDs in the parts created
        after removing edges in the cut

      - C{cut} - edge IDs in the cut

      - C{es} - an edge selector restricted to the edges
        in the cut.

    You can use indexing on this object to obtain lists of vertex IDs
    for both sides of the partition.

    This class is usually not instantiated directly, everything
    is taken care of by the functions that return cuts.

    Examples:

      >>> from igraph import Graph
      >>> g = Graph.Ring(20)
      >>> mc = g.mincut()
      >>> print(mc.value)
      2.0
      >>> print(min(len(x) for x in mc))
      1
      >>> mc.es["color"] = "red"
    Nc                    st   |dks|dkrt ddg|  }|D ]}d||< q*t || |dkrVt|}t|| _t|| _|| _	dS )zInitializes the cut.

        This should not be called directly, everything is taken care of by
        the functions that return cuts.
        Nzpartition and cut must be given   r   )

ValueErrorvcountsuper__init__lenfloat_valuesorted
_partition_cut)selfgraphvaluecut	partitionZ
partition2Z
membershipZvid	__class__ C/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/igraph/cut.pyr	   4   s    


zCut.__init__c                 C   s   d| j j| j| j| j| jf S )Nz%s(%r, %r, %r, %r))r   __name___graphr   r   r   r   r   r   r   __repr__L   s    zCut.__repr__c                 C   s.   dt | jt | j| j t | j | jf S )Nz3Graph cut (%d edges, %d vs %d vertices, value=%.4f)r
   r   r   r   r   r   r   r   r   r   __str__U   s    zCut.__str__c                 C   s   | j j| jS )z.Returns an edge selector restricted to the cut)r   esselectr   r   r   r   r   r   ]   s    zCut.esc                 C   s   t | S )z7Returns the vertex IDs partitioned according to the cut)listr   r   r   r   r   b   s    zCut.partitionc                 C   s   | j S )zReturns the edge IDs in the cut)r   r   r   r   r   r   g   s    zCut.cutc                 C   s   | j S )z-Returns the sum of edge capacities in the cut)r   r   r   r   r   r   l   s    z	Cut.value)NNNN)r   
__module____qualname____doc__r	   r   r   propertyr   r   r   r   __classcell__r   r   r   r   r      s   (	


r   c                       s<   e Zd ZdZ fddZdd Zdd Zedd	 Z  Z	S )
Flowa  A flow of a given graph.

    This is a simple class used to represent flows returned by
    L{Graph.maxflow}. It has the following attributes:

      - C{graph} - the graph on which this flow is defined

      - C{value} - the value (capacity) of the flow

      - C{flow} - the flow values on each edge. For directed graphs,
        this is simply a list where element M{i} corresponds to the
        flow on edge M{i}. For undirected graphs, the direction of
        the flow is not constrained (since the edges are undirected),
        hence positive flow always means a flow from the smaller vertex
        ID to the larger, while negative flow means a flow from the
        larger vertex ID to the smaller.

      - C{cut} - edge IDs in the minimal cut corresponding to
        the flow.

      - C{partition} - vertex IDs in the parts created
        after removing edges in the cut

      - C{es} - an edge selector restricted to the edges
        in the cut.

    This class is usually not instantiated directly, everything
    is taken care of by L{Graph.maxflow}.

    Examples:

      >>> from igraph import Graph
      >>> g = Graph.Ring(20)
      >>> mf = g.maxflow(0, 10)
      >>> print(mf.value)
      2.0
      >>> mf.es["color"] = "red"
    c                    s   t  |||| || _dS )zInitializes the flow.

        This should not be called directly, everything is
        taken care of by L{Graph.maxflow}.
        N)r   r	   _flow)r   r   r   flowr   r   r   r   r   r	      s    zFlow.__init__c                 C   s"   d| j j| j| j| j| j| jf S )Nz%s(%r, %r, %r, %r, %r))r   r   r   r   r(   r   r   r   r   r   r   r      s    zFlow.__repr__c                 C   s.   dt | jt | j| j t | j | jf S )Nz4Graph flow (%d edges, %d vs %d vertices, value=%.4f)r   r   r   r   r   r      s    zFlow.__str__c                 C   s   | j S )a  Returns the flow values for each edge.

        For directed graphs, this is simply a list where element M{i}
        corresponds to the flow on edge M{i}. For undirected graphs, the
        direction of the flow is not constrained (since the edges are
        undirected), hence positive flow always means a flow from the smaller
        vertex ID to the larger, while negative flow means a flow from the
        larger vertex ID to the smaller.
        )r(   r   r   r   r   r)      s    z	Flow.flow)
r   r"   r#   r$   r	   r   r   r%   r)   r&   r   r   r   r   r'   r   s   '	
r'   c                    s     fddt t || D S )a      Returns all the cuts between the source and target vertices in a
    directed graph.

    This function lists all edge-cuts between a source and a target vertex.
    Every cut is listed exactly once.

    @param source: the source vertex ID
    @param target: the target vertex ID
    @return: a list of L{Cut} objects.

    @newfield ref: Reference
    @ref: JS Provan and DR Shier: A paradigm for listing (s,t)-cuts in
      graphs. Algorithmica 15, 351--372, 1996.
    c                    s   g | ]\}}t  ||d qS )r   r   r   .0r   partr   r   r   
<listcomp>   s   z _all_st_cuts.<locals>.<listcomp>)zipr   Zall_st_cuts)r   sourcetargetr   r/   r   _all_st_cuts   s    
r4   Nc                    s0   t  |||\}} fddt||D S )aG      Returns all the mincuts between the source and target vertices in a
    directed graph.

    This function lists all minimum edge-cuts between a source and a target
    vertex.

    @param source: the source vertex ID
    @param target: the target vertex ID
    @param capacity: the edge capacities (weights). If C{None}, all
      edges have equal weight. May also be an attribute name.
    @return: a list of L{Cut} objects.

    @newfield ref: Reference
    @ref: JS Provan and DR Shier: A paradigm for listing (s,t)-cuts in
      graphs. Algorithmica 15, 351--372, 1996.
    c                    s    g | ]\}}t  ||d qS r*   r+   r,   r   r   r   r   r0      s    z#_all_st_mincuts.<locals>.<listcomp>)r   Zall_st_mincutsr1   )r   r2   r3   capacitycutspartsr   r5   r   _all_st_mincuts   s    r9   r)   c                 C   s   t | |\} }|| j|< | S )a  Calculates the Gomory-Hu tree of an undirected graph with optional
    edge capacities.

    The Gomory-Hu tree is a concise representation of the value of all the
    maximum flows (or minimum cuts) in a graph. The vertices of the tree
    correspond exactly to the vertices of the original graph in the same order.
    Edges of the Gomory-Hu tree are annotated by flow values.  The value of
    the maximum flow (or minimum cut) between an arbitrary (u,v) vertex
    pair in the original graph is then given by the minimum flow value (i.e.
    edge annotation) along the shortest path between u and v in the
    Gomory-Hu tree.

    @param capacity: the edge capacities (weights). If C{None}, all
      edges have equal weight. May also be an attribute name.
    @param flow: the name of the edge attribute in the returned graph
      in which the flow values will be stored.
    @return: the Gomory-Hu tree as a L{Graph} object.
    )r   Zgomory_hu_treer   )r   r6   r)   Zflow_valuesr   r   r   _gomory_hu_tree   s    
r:   c                 C   s   t | ft| ||| S )a~  Returns a maximum flow between the given source and target vertices
    in a graph.

    A maximum flow from I{source} to I{target} is an assignment of
    non-negative real numbers to the edges of the graph, satisfying
    two properties:

        1. For each edge, the flow (i.e. the assigned number) is not
           more than the capacity of the edge (see the I{capacity}
           argument)

        2. For every vertex except the source and the target, the
           incoming flow is the same as the outgoing flow.

    The value of the flow is the incoming flow of the target or the
    outgoing flow of the source (which are equal). The maximum flow
    is the maximum possible such value.

    @param capacity: the edge capacities (weights). If C{None}, all
      edges have equal weight. May also be an attribute name.
    @return: a L{Flow} object describing the maximum flow
    )r'   r   Zmaxflowr   r2   r3   r6   r   r   r   _maxflow	  s    r<   c                 C   s   t | ft| ||| S )a  Calculates the minimum cut between the given source and target vertices
    or within the whole graph.

    The minimum cut is the minimum set of edges that needs to be removed to
    separate the source and the target (if they are given) or to disconnect the
    graph (if neither the source nor the target are given). The minimum is
    calculated using the weights (capacities) of the edges, so the cut with
    the minimum total capacity is calculated.

    For undirected graphs and no source and target, the method uses the
    Stoer-Wagner algorithm. For a given source and target, the method uses the
    push-relabel algorithm; see the references below.

    @param source: the source vertex ID. If C{None}, the target must also be
      C{None} and the calculation will be done for the entire graph (i.e.
      all possible vertex pairs).
    @param target: the target vertex ID. If C{None}, the source must also be
      C{None} and the calculation will be done for the entire graph (i.e.
      all possible vertex pairs).
    @param capacity: the edge capacities (weights). If C{None}, all
      edges have equal weight. May also be an attribute name.
    @return: a L{Cut} object describing the minimum cut
    )r   r   Zmincutr;   r   r   r   _mincut#  s    r=   c                 C   s   t | ft| ||| S )a  Calculates the minimum cut between the source and target vertices in a
    graph.

    @param source: the source vertex ID
    @param target: the target vertex ID
    @param capacity: the capacity of the edges. It must be a list or a valid
      attribute name or C{None}. In the latter case, every edge will have the
      same capacity.
    @return: the value of the minimum cut, the IDs of vertices in the
      first and second partition, and the IDs of edges in the cut,
      packed in a 4-tuple
    )r   r   Z	st_mincutr;   r   r   r   
_st_mincut>  s    r>   )N)Nr)   )N)NNN)N)r$   Zigraph._igraphr   Zigraph.clusteringr   r   r'   r4   r9   r:   r<   r=   r>   r   r   r   r   <module>   s   gQ



