o
    ˷e0                     @   sT   d dl mZ d dlZd dlmZmZ ddgZedd
ddZedd
d	dZ	dS )    )chainN)not_implemented_forpairwisemetric_closuresteiner_treedirectedweightc           
      C   s   t  }t| }t j| |d}t|\}\}}|t| r$d}t ||| |D ]}	|j||	||	 ||	 d q+|D ]\}\}}|| |D ]}	|j||	||	 ||	 d qJq=|S )aO  Return the metric closure of a graph.

    The metric closure of a graph *G* is the complete graph in which each edge
    is weighted by the shortest path distance between the nodes in *G* .

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

    Returns
    -------
    NetworkX graph
        Metric closure of the graph `G`.

    r   z:G is not a connected graph. metric_closure is not defined.)distancepath)nxGraphsetall_pairs_dijkstranextNetworkXErrorremoveadd_edge)
Gr   MGnodesall_paths_iterur
   r   msgv r   d/var/www/ideatree/venv/lib/python3.10/site-packages/networkx/algorithms/approximation/steinertree.pyr   	   s    


c                    sd   t  d}||}tj|ddd}tdd |D }  r+ fdd|D } |}|S )a-  Return an approximation to the minimum Steiner tree of a graph.

    The minimum Steiner tree of `G` w.r.t a set of `terminal_nodes`
    is a tree within `G` that spans those nodes and has minimum size
    (sum of edge weights) among all such trees.

    The minimum Steiner tree can be approximated by computing the minimum
    spanning tree of the subgraph of the metric closure of *G* induced by the
    terminal nodes, where the metric closure of *G* is the complete graph in
    which each edge is weighted by the shortest path distance between the
    nodes in *G* .
    This algorithm produces a tree whose weight is within a (2 - (2 / t))
    factor of the weight of the optimal Steiner tree where *t* is number of
    terminal nodes.

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

    terminal_nodes : list
         A list of terminal nodes for which minimum steiner tree is
         to be found.

    Returns
    -------
    NetworkX graph
        Approximation to the minimum steiner tree of `G` induced by
        `terminal_nodes` .

    Notes
    -----
    For multigraphs, the edge between two nodes with minimum weight is the
    edge put into the Steiner tree.


    References
    ----------
    .. [1] Steiner_tree_problem on Wikipedia.
       https://en.wikipedia.org/wiki/Steiner_tree_problem
    r	   r
   T)r   datac                 s   s"    | ]\}}}t |d  V  qdS )r   N)r   ).0r   r   dr   r   r   	<genexpr>a   s     zsteiner_tree.<locals>.<genexpr>c              	   3   s<    | ]\  t     fd ddfV  qdS )c                    s      |   S )Nr   )k)r   r   r   r   r   r   <lambda>e   s    z(steiner_tree.<locals>.<genexpr>.<lambda>)keyN)min)r   r   r   )r   r   r   r    d   s    ,
)r   subgraphr   minimum_spanning_edgesr   from_iterableis_multigraphedge_subgraph)r   terminal_nodesr   r   H	mst_edgesedgesTr   r%   r   r   1   s   +

r	   )
	itertoolsr   networkxr   networkx.utilsr   r   __all__r   r   r   r   r   r   <module>   s    '