
    wgp                         d dl mZ d dlZd dlmZmZ ddgZ ed       ej                  dd	      dd
              Z	d Z
d Zd Zee
dZ ed       ej                  dd      dd              Zy)    )chainN)not_implemented_forpairwisemetric_closuresteiner_treedirectedweightT)
edge_attrsreturns_graphc           	         t        j                         }t        |       }t        j                  | |      }t	        |      \  }\  }}|t        |      z
  rd}t        j
                  |      |j                  |       |D ]  }	|j                  ||	||	   ||	           |D ];  \  }\  }}|j                  |       |D ]  }	|j                  ||	||	   ||	           = |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vs
             r/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/algorithms/approximation/steinertree.pyr   r   	   s    $ 	
AVF **1V<N~.A$HJs##
MM! =	

1a(1+DG
<=  . AHda 	AAJJq!hqkQJ@	AA
 H    c                     t        j                   |      }i }i } j                         D ]&  }||   d   ||<   t        ||         dz
  ||||   f<   ( t        j                         } j                  d      D ]  \  }}}	||   ||   }}
|||
f   |	j                  d      z   |||f   z   }|j                  |
|      s|j                  |
||       Zt        |||
   |   d         }|j                  |
||        t        j                  |d      }t        j                         }|D ]C  \  }}}t        j                   ||      }t        |      D ]  \  }}|j                  ||        E t        t        j                  |d            } j                         r fd|D        } j                  |      j!                         }t#        ||       |j                         S )	Nr      T)datar   r	   Fc           
   3   `   K   | ]#  \  t              fd       f % yw)c                            |       S N kr   r   r   r	   s    r   <lambda>z2_mehlhorn_steiner_tree.<locals>.<genexpr>.<lambda>Q       ad1gaj.@ r    keyNmin.0r   r   r   r	   s    @@r   	<genexpr>z)_mehlhorn_steiner_tree.<locals>.<genexpr>P   s1      
GKq!Q3qtAw$@AB
   ).)r   multi_source_dijkstra_pathnodeslenr   edgesgethas_edger   r/   minimum_spanning_edgesshortest_pathr   listis_multigraphedge_subgraphcopy_remove_nonterminal_leaves)r   terminal_nodesr	   pathsd_1sr   	G_1_primer   r#   susvweight_here
new_weightG_2G_3dr   n1n2G_3_mstG_4s   ` `                   r   _mehlhorn_steiner_treerQ   2   s   ))!^<E
C
AWWY +Qx{!U1X*Q!I+
 
Igg4g( :
1d1qtB1b'lTXXfa%8832w<G!!"b)r2k:[)B-*;H*EFJr2j9: 
#
#ID
9C
((*C !1a1a0tn 	!FBLLR 	!!
 2,,Su=>G
OV
 //'
"
'
'
)CsN399;r    c                     t               }|j                  |      }t        j                  |dd      }t	        j
                  d |D              } j                         r fd|D        } j                  |      }t        j                  |dd      } j                  |      j                         }	t        |	|       |	j                         S )	Nr   r   T)r	   r#   c              3   @   K   | ]  \  }}}t        |d            yw)r   N)r   )r1   r   r   rL   s       r   r2   z$_kou_steiner_tree.<locals>.<genexpr>a   s     'U1a6(;'Us   c           
   3   `   K   | ]#  \  t              fd       f % yw)c                            |       S r&   r'   r(   s    r   r*   z-_kou_steiner_tree.<locals>.<genexpr>.<lambda>d   r+   r    r,   Nr.   r0   s    @@r   r2   z$_kou_steiner_tree.<locals>.<genexpr>c   s4      
1 3qtAw$@AB
r3   r	   F)r   subgraphr   r:   r   from_iterabler=   r>   r?   r@   r7   )
r   rA   r	   r   H	mst_edgesmst_all_edgesG_ST_ST_Hs
   ` `       r   _kou_steiner_treer^   X   s    q(A	

>"A ))!JTJI '''U9'UUM
%
 //-
(C

#
#Cu
EC //#

#
#
%CsN399;r    c           	      p    t        |      } D ch c]#  }t        t         |         |hz
        dk(  s"|% }}||z
  }|rkt        j                   fd|D         }|||z  z  } j                  |       |D ch c]#  }t        t         |         |hz
        dk(  s"|% }}||z
  }|rjy y c c}w c c}w )Nr"   c              3   :   K   | ]  }t        |           y wr&   )r   )r1   nr   s     r   r2   z-_remove_nonterminal_leaves.<locals>.<genexpr>|   s     &MQs1Q4y&Ms   )r   r6   unionremove_nodes_from)r   	terminalsterminal_setra   leavesnonterminal_leavescandidate_leavess   `      r   r@   r@   s   s    y>L8Ac#ad)qc/2a7a8F8,.
 99&M:L&MN.==	./-KS1Y!_1E1J!KK#l2  9 Ls   #B.B.:#B3B3)koumehlhorn)preserve_all_attrsr   c                      |d}	 t         |   } | |      } j                         r fd|D        } j	                  |      }|S # t        $ r}t        | d      |d}~ww xY w)u  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` (also *S*)
    is a tree within `G` that spans those nodes and has minimum size (sum of
    edge weights) among all such trees.

    The approximation algorithm is specified with the `method` keyword
    argument. All three available algorithms produce a tree whose weight is
    within a ``(2 - (2 / l))`` factor of the weight of the optimal Steiner tree,
    where ``l`` is the minimum number of leaf nodes across all possible Steiner
    trees.

    * ``"kou"`` [2]_ (runtime $O(|S| |V|^2)$) computes 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*.

    * ``"mehlhorn"`` [3]_ (runtime $O(|E|+|V|\log|V|)$) modifies Kou et al.'s
      algorithm, beginning by finding the closest terminal node for each
      non-terminal. This data is used to create a complete graph containing only
      the terminal nodes, in which edge is weighted with the shortest path
      distance between them. The algorithm then proceeds in the same way as Kou
      et al..

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

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

    weight : string (default = 'weight')
        Use the edge attribute specified by this string as the edge weight.
        Any edge attribute not present defaults to 1.

    method : string, optional (default = 'mehlhorn')
        The algorithm to use to approximate the Steiner tree.
        Supported options: 'kou', 'mehlhorn'.
        Other inputs produce a ValueError.

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

    Raises
    ------
    NetworkXNotImplemented
        If `G` is directed.

    ValueError
        If the specified `method` is not supported.

    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
    .. [2] Kou, L., G. Markowsky, and L. Berman. 1981.
           ‘A Fast Algorithm for Steiner Trees’.
           Acta Informatica 15 (2): 141–45.
           https://doi.org/10.1007/BF00288961.
    .. [3] Mehlhorn, Kurt. 1988.
           ‘A Faster Approximation Algorithm for the Steiner Problem in Graphs’.
           Information Processing Letters 27 (3): 125–28.
           https://doi.org/10.1016/0020-0190(88)90066-X.
    Nrj   z( is not a valid choice for an algorithm.c           
   3   `   K   | ]#  \  t              fd       f % yw)c                            |       S r&   r'   r(   s    r   r*   z(steiner_tree.<locals>.<genexpr>.<lambda>   r+   r    r,   Nr.   r0   s    @@r   r2   zsteiner_tree.<locals>.<genexpr>   s1      
GKq!Q3qtAw$@AB
r3   )
ALGORITHMSKeyError
ValueErrorr=   r>   )r   rA   r	   methodalgoer7   Ts   ` `     r   r   r      s    Z ~U&! NF+E
OT
 	
AH  UF8#KLMSTTUs   	A
 
	A'A""A'r   )r	   N)	itertoolsr   networkxr   networkx.utilsr   r   __all___dispatchabler   rQ   r^   r@   ro   r   r'   r    r   <module>r{      s      8^
, Z XT:$ ; !$N#L63& &
 Z T>Z ? !Zr    