U
    ?hó  ã                   @   sN   d Z ddlmZmZ ddlZddddgZdd	d„Zd
d„ Zdd„ Z	dd„ Z
dS )zOperations on many graphs.
é    )ÚchainÚrepeatNÚ	union_allÚcompose_allÚdisjoint_union_allÚintersection_all© c                    sü   d}t ƒ }dd„ ‰ t|tdƒƒ}‡ fdd„t| |ƒD ƒ} t| ƒD ]¦\}}t |jƒ}|dkrd| ¡ }n2| ¡ | ¡ kr€t 	d¡‚n| 
|¡s–t 	dd	¡‚||O }|j |j¡ | |jd
d¡ | | ¡ rØ|jd
d
dn
|jd
d¡ q@|dkrøtdƒ‚|S )a  Returns the union of all graphs.

    The graphs must be disjoint, otherwise an exception is raised.

    Parameters
    ----------
    graphs : iterable
       Iterable of NetworkX graphs

    rename : iterable , optional
       Node names of graphs can be changed by specifying the tuple
       rename=('G-','H-') (for example).  Node "u" in G is then renamed
       "G-u" and "v" in H is renamed "H-v". Infinite generators (like itertools.count)
       are also supported.

    Returns
    -------
    U : a graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    To force a disjoint union with node relabeling, use
    disjoint_union_all(G,H) or convert_node_labels_to integers().

    Graph, edge, and node attributes are propagated to the union graph.
    If a graph attribute is present in multiple graphs, then the value
    from the last graph in the list with that attribute is used.

    See Also
    --------
    union
    disjoint_union_all
    Nc                    s$   ˆ d kr| S ‡ fdd„}t  | |¡S )Nc                    s   ˆ › | › S ©Nr   )Úx©Úprefixr   úS/var/www/html/venv/lib/python3.8/site-packages/networkx/algorithms/operators/all.pyÚlabel9   s    z,union_all.<locals>.add_prefix.<locals>.label)ÚnxZrelabel_nodes)Úgraphr   r   r   r   r   Ú
add_prefix5   s    zunion_all.<locals>.add_prefixc                 3   s   | ]\}}ˆ ||ƒV  qd S r	   r   )Ú.0ÚGÚname©r   r   r   Ú	<genexpr>?   s     zunion_all.<locals>.<genexpr>r   ú)All graphs must be graphs or multigraphs.z-The node sets of the graphs are not disjoint.z[Use appropriate rename=(G1prefix,G2prefix,...,GNprefix)or use disjoint_union(G1,G2,...,GN).T©Údata©Úkeysr   z'cannot apply union_all to an empty list)Úsetr   r   ÚzipÚ	enumerateÚnodesÚ	__class__Úis_multigraphr   ÚNetworkXErrorÚ
isdisjointr   ÚupdateÚadd_nodes_fromÚadd_edges_fromÚedgesÚ
ValueError)ÚgraphsÚrenameÚRZ
seen_nodesÚir   ÚG_nodes_setr   r   r   r   
   s2    '	


þ ÿc                 C   s   dd„ }t || ƒƒ}|S )aç  Returns the disjoint union of all graphs.

    This operation forces distinct integer node labels starting with 0
    for the first graph in the list and numbering consecutively.

    Parameters
    ----------
    graphs : iterable
       Iterable of NetworkX graphs

    Returns
    -------
    U : A graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    It is recommended that the graphs be either all directed or all undirected.

    Graph, edge, and node attributes are propagated to the union graph.
    If a graph attribute is present in multiple graphs, then the value
    from the last graph in the list with that attribute is used.
    c                 s   s.   d}| D ] }t j||dV  |t|ƒ7 }qd S )Nr   )Úfirst_label)r   Zconvert_node_labels_to_integersÚlen)r)   r.   r   r   r   r   Úyield_relabeledz   s    z+disjoint_union_all.<locals>.yield_relabeled)r   )r)   r0   r+   r   r   r   r   ]   s    c                 C   sž   d}t | ƒD ]|\}}|dkr&| ¡ }n| ¡ | ¡ kr@t d¡‚|j |j¡ | |jdd¡ | 	| ¡ rz|j
dddn
|j
dd¡ q|dkrštdƒ‚|S )aì  Returns the composition of all graphs.

    Composition is the simple union of the node sets and edge sets.
    The node sets of the supplied graphs need not be disjoint.

    Parameters
    ----------
    graphs : iterable
       Iterable of NetworkX graphs

    Returns
    -------
    C : A graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    It is recommended that the supplied graphs be either all directed or all
    undirected.

    Graph, edge, and node attributes are propagated to the union graph.
    If a graph attribute is present in multiple graphs, then the value
    from the last graph in the list with that attribute is used.
    Nr   r   Tr   r   z)cannot apply compose_all to an empty list)r   r    r!   r   r"   r   r$   r%   r   r&   r'   r(   )r)   r+   r,   r   r   r   r   r   …   s    

 ÿc                 C   s¼   d}t | ƒD ]†\}}t|jƒ}t| ¡ r4|jddn| ¡ ƒ}|dkrX| ¡ }|}|}n,| ¡ | ¡ krtt d¡‚n||M }||M }|j 	|j¡ q|dkr¤t
dƒ‚| |¡ | |¡ |S )aÉ  Returns a new graph that contains only the nodes and the edges that exist in
    all graphs.

    Parameters
    ----------
    graphs : iterable
       Iterable of NetworkX graphs

    Returns
    -------
    R : A new graph with the same type as the first graph in list

    Raises
    ------
    ValueError
       If `graphs` is an empty list.

    Notes
    -----
    Attributes from the graph, nodes, and edges are not copied to the new
    graph.
    NT)r   r   r   z.cannot apply intersection_all to an empty list)r   r   r   r!   r'   r    r   r"   r   r$   r(   r%   r&   )r)   r+   r,   r   r-   ZG_edges_setZnode_intersectionZedge_intersectionr   r   r   r   ¸   s$    
 

)r   )Ú__doc__Ú	itertoolsr   r   Znetworkxr   Ú__all__r   r   r   r   r   r   r   r   Ú<module>   s   
S(3