ó
 ,µ[c           @  s  d  Z  d d l m Z d d l Z d d l Z d d l Td d l Z d Z d d d d	 g Z	 d
 „  Z
 e e e e e e e e e d „	 Z e e e e e e e e e d „	 Z e e e e e e e e e d „	 Z e e e e e e e e e e d „
 Z d „  Z d S(   sP   Functions measuring similarity using graph edit distance.

The graph edit distance is the number of edge/node changes needed
to make two graphs isomorphic.

The default algorithm/implementation is sub-optimal for some graphs.
The problem of finding the exact Graph Edit Distance (GED) is NP-hard
so it is often slow. If the simple interface `graph_edit_distance`
takes too long for your graph, try `optimize_graph_edit_distance`
and/or `optimize_edit_paths`.

At the same time, I encourage capable people to investigate
alternative GED algorithms, in order to improve the choices available.
iÿÿÿÿ(   t   print_functionN(   t   *s%   Andrey Paramonov <paramon@acdlabs.ru>t   graph_edit_distancet   optimal_edit_pathst   optimize_graph_edit_distancet   optimize_edit_pathsc          O  s   t  |  | Ž  d  S(   N(   t   print(   t   argst   kwargs(    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   debug_print(   s    c         C  sQ   d } xD t |  | | | | | | | | |	 |
 t ƒ D] \ } } } | } q4 W| S(   sÙ  Returns GED (graph edit distance) between graphs G1 and G2.

    Graph edit distance is a graph similarity measure analogous to
    Levenshtein distance for strings.  It is defined as minimum cost
    of edit path (sequence of node and edge edit operations)
    transforming graph G1 to graph isomorphic to G2.

    Parameters
    ----------
    G1, G2: graphs
        The two graphs G1 and G2 must be of the same type.

    node_match : callable
        A function that returns True if node n1 in G1 and n2 in G2
        should be considered equal during matching.

        The function will be called like

           node_match(G1.nodes[n1], G2.nodes[n2]).

        That is, the function will receive the node attribute
        dictionaries for n1 and n2 as inputs.

        Ignored if node_subst_cost is specified.  If neither
        node_match nor node_subst_cost are specified then node
        attributes are not considered.

    edge_match : callable
        A function that returns True if the edge attribute dictionaries
        for the pair of nodes (u1, v1) in G1 and (u2, v2) in G2 should
        be considered equal during matching.

        The function will be called like

           edge_match(G1[u1][v1], G2[u2][v2]).

        That is, the function will receive the edge attribute
        dictionaries of the edges under consideration.

        Ignored if edge_subst_cost is specified.  If neither
        edge_match nor edge_subst_cost are specified then edge
        attributes are not considered.

    node_subst_cost, node_del_cost, node_ins_cost : callable
        Functions that return the costs of node substitution, node
        deletion, and node insertion, respectively.

        The functions will be called like

           node_subst_cost(G1.nodes[n1], G2.nodes[n2]),
           node_del_cost(G1.nodes[n1]),
           node_ins_cost(G2.nodes[n2]).

        That is, the functions will receive the node attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function node_subst_cost overrides node_match if specified.
        If neither node_match nor node_subst_cost are specified then
        default node substitution cost of 0 is used (node attributes
        are not considered during matching).

        If node_del_cost is not specified then default node deletion
        cost of 1 is used.  If node_ins_cost is not specified then
        default node insertion cost of 1 is used.

    edge_subst_cost, edge_del_cost, edge_ins_cost : callable
        Functions that return the costs of edge substitution, edge
        deletion, and edge insertion, respectively.

        The functions will be called like

           edge_subst_cost(G1[u1][v1], G2[u2][v2]),
           edge_del_cost(G1[u1][v1]),
           edge_ins_cost(G2[u2][v2]).

        That is, the functions will receive the edge attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function edge_subst_cost overrides edge_match if specified.
        If neither edge_match nor edge_subst_cost are specified then
        default edge substitution cost of 0 is used (edge attributes
        are not considered during matching).

        If edge_del_cost is not specified then default edge deletion
        cost of 1 is used.  If edge_ins_cost is not specified then
        default edge insertion cost of 1 is used.

    upper_bound : numeric
        Maximum edit distance to consider.  Return None if no edit
        distance under or equal to upper_bound exists.

    Examples
    --------
    >>> G1 = nx.cycle_graph(6)
    >>> G2 = nx.wheel_graph(7)
    >>> nx.graph_edit_distance(G1, G2)
    7.0

    See Also
    --------
    optimal_edit_paths, optimize_graph_edit_distance,

    is_isomorphic (test for graph edit distance of 0)

    References
    ----------
    .. [1] Zeina Abu-Aisheh, Romain Raveaux, Jean-Yves Ramel, Patrick
       Martineau. An Exact Graph Edit Distance Algorithm for Solving
       Pattern Recognition Problems. 4th International Conference on
       Pattern Recognition Applications and Methods 2015, Jan 2015,
       Lisbon, Portugal. 2015,
       <10.5220/0005209202710278>. <hal-01168816>
       https://hal.archives-ouvertes.fr/hal-01168816

    N(   t   NoneR   t   True(   t   G1t   G2t
   node_matcht
   edge_matcht   node_subst_costt   node_del_costt   node_ins_costt   edge_subst_costt   edge_del_costt   edge_ins_costt   upper_boundt   bestcostt   vertex_patht	   edge_patht   cost(    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR   ,   s    {		
c         C  s—   t  ƒ  } d } x{ t |  | | | | | | | | |	 |
 t ƒ D]L \ } } } | d k	 rp | | k  rp t  ƒ  } n  | j | | f ƒ | } q= W| | f S(   sR  Returns all minimum-cost edit paths transforming G1 to G2.

    Graph edit path is a sequence of node and edge edit operations
    transforming graph G1 to graph isomorphic to G2.  Edit operations
    include substitutions, deletions, and insertions.

    Parameters
    ----------
    G1, G2: graphs
        The two graphs G1 and G2 must be of the same type.

    node_match : callable
        A function that returns True if node n1 in G1 and n2 in G2
        should be considered equal during matching.

        The function will be called like

           node_match(G1.nodes[n1], G2.nodes[n2]).

        That is, the function will receive the node attribute
        dictionaries for n1 and n2 as inputs.

        Ignored if node_subst_cost is specified.  If neither
        node_match nor node_subst_cost are specified then node
        attributes are not considered.

    edge_match : callable
        A function that returns True if the edge attribute dictionaries
        for the pair of nodes (u1, v1) in G1 and (u2, v2) in G2 should
        be considered equal during matching.

        The function will be called like

           edge_match(G1[u1][v1], G2[u2][v2]).

        That is, the function will receive the edge attribute
        dictionaries of the edges under consideration.

        Ignored if edge_subst_cost is specified.  If neither
        edge_match nor edge_subst_cost are specified then edge
        attributes are not considered.

    node_subst_cost, node_del_cost, node_ins_cost : callable
        Functions that return the costs of node substitution, node
        deletion, and node insertion, respectively.

        The functions will be called like

           node_subst_cost(G1.nodes[n1], G2.nodes[n2]),
           node_del_cost(G1.nodes[n1]),
           node_ins_cost(G2.nodes[n2]).

        That is, the functions will receive the node attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function node_subst_cost overrides node_match if specified.
        If neither node_match nor node_subst_cost are specified then
        default node substitution cost of 0 is used (node attributes
        are not considered during matching).

        If node_del_cost is not specified then default node deletion
        cost of 1 is used.  If node_ins_cost is not specified then
        default node insertion cost of 1 is used.

    edge_subst_cost, edge_del_cost, edge_ins_cost : callable
        Functions that return the costs of edge substitution, edge
        deletion, and edge insertion, respectively.

        The functions will be called like

           edge_subst_cost(G1[u1][v1], G2[u2][v2]),
           edge_del_cost(G1[u1][v1]),
           edge_ins_cost(G2[u2][v2]).

        That is, the functions will receive the edge attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function edge_subst_cost overrides edge_match if specified.
        If neither edge_match nor edge_subst_cost are specified then
        default edge substitution cost of 0 is used (edge attributes
        are not considered during matching).

        If edge_del_cost is not specified then default edge deletion
        cost of 1 is used.  If edge_ins_cost is not specified then
        default edge insertion cost of 1 is used.

    upper_bound : numeric
        Maximum edit distance to consider.

    Returns
    -------
    edit_paths : list of tuples (node_edit_path, edge_edit_path)
        node_edit_path : list of tuples (u, v)
        edge_edit_path : list of tuples ((u1, v1), (u2, v2))

    cost : numeric
        Optimal edit path cost (graph edit distance).

    Examples
    --------
    >>> G1 = nx.cycle_graph(6)
    >>> G2 = nx.wheel_graph(7)
    >>> paths, cost = nx.optimal_edit_paths(G1, G2)
    >>> len(paths)
    84
    >>> cost
    7.0

    See Also
    --------
    graph_edit_distance, optimize_edit_paths

    References
    ----------
    .. [1] Zeina Abu-Aisheh, Romain Raveaux, Jean-Yves Ramel, Patrick
       Martineau. An Exact Graph Edit Distance Algorithm for Solving
       Pattern Recognition Problems. 4th International Conference on
       Pattern Recognition Applications and Methods 2015, Jan 2015,
       Lisbon, Portugal. 2015,
       <10.5220/0005209202710278>. <hal-01168816>
       https://hal.archives-ouvertes.fr/hal-01168816

    N(   t   listR
   R   t   Falset   append(   R   R   R   R   R   R   R   R   R   R   R   t   pathsR   R   R   R   (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR   ²   s    ƒ			
c         c  sJ   xC t  |  | | | | | | | | |	 |
 t ƒ D] \ } } } | Vq. Wd S(   sý  Returns consecutive approximations of GED (graph edit distance)
    between graphs G1 and G2.

    Graph edit distance is a graph similarity measure analogous to
    Levenshtein distance for strings.  It is defined as minimum cost
    of edit path (sequence of node and edge edit operations)
    transforming graph G1 to graph isomorphic to G2.

    Parameters
    ----------
    G1, G2: graphs
        The two graphs G1 and G2 must be of the same type.

    node_match : callable
        A function that returns True if node n1 in G1 and n2 in G2
        should be considered equal during matching.

        The function will be called like

           node_match(G1.nodes[n1], G2.nodes[n2]).

        That is, the function will receive the node attribute
        dictionaries for n1 and n2 as inputs.

        Ignored if node_subst_cost is specified.  If neither
        node_match nor node_subst_cost are specified then node
        attributes are not considered.

    edge_match : callable
        A function that returns True if the edge attribute dictionaries
        for the pair of nodes (u1, v1) in G1 and (u2, v2) in G2 should
        be considered equal during matching.

        The function will be called like

           edge_match(G1[u1][v1], G2[u2][v2]).

        That is, the function will receive the edge attribute
        dictionaries of the edges under consideration.

        Ignored if edge_subst_cost is specified.  If neither
        edge_match nor edge_subst_cost are specified then edge
        attributes are not considered.

    node_subst_cost, node_del_cost, node_ins_cost : callable
        Functions that return the costs of node substitution, node
        deletion, and node insertion, respectively.

        The functions will be called like

           node_subst_cost(G1.nodes[n1], G2.nodes[n2]),
           node_del_cost(G1.nodes[n1]),
           node_ins_cost(G2.nodes[n2]).

        That is, the functions will receive the node attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function node_subst_cost overrides node_match if specified.
        If neither node_match nor node_subst_cost are specified then
        default node substitution cost of 0 is used (node attributes
        are not considered during matching).

        If node_del_cost is not specified then default node deletion
        cost of 1 is used.  If node_ins_cost is not specified then
        default node insertion cost of 1 is used.

    edge_subst_cost, edge_del_cost, edge_ins_cost : callable
        Functions that return the costs of edge substitution, edge
        deletion, and edge insertion, respectively.

        The functions will be called like

           edge_subst_cost(G1[u1][v1], G2[u2][v2]),
           edge_del_cost(G1[u1][v1]),
           edge_ins_cost(G2[u2][v2]).

        That is, the functions will receive the edge attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function edge_subst_cost overrides edge_match if specified.
        If neither edge_match nor edge_subst_cost are specified then
        default edge substitution cost of 0 is used (edge attributes
        are not considered during matching).

        If edge_del_cost is not specified then default edge deletion
        cost of 1 is used.  If edge_ins_cost is not specified then
        default edge insertion cost of 1 is used.

    upper_bound : numeric
        Maximum edit distance to consider.

    Returns
    -------
    Generator of consecutive approximations of graph edit distance.

    Examples
    --------
    >>> G1 = nx.cycle_graph(6)
    >>> G2 = nx.wheel_graph(7)
    >>> for v in nx.optimize_graph_edit_distance(G1, G2):
    ...     minv = v
    >>> minv
    7.0

    See Also
    --------
    graph_edit_distance, optimize_edit_paths

    References
    ----------
    .. [1] Zeina Abu-Aisheh, Romain Raveaux, Jean-Yves Ramel, Patrick
       Martineau. An Exact Graph Edit Distance Algorithm for Solving
       Pattern Recognition Problems. 4th International Conference on
       Pattern Recognition Applications and Methods 2015, Jan 2015,
       Lisbon, Portugal. 2015,
       <10.5220/0005209202710278>. <hal-01168816>
       https://hal.archives-ouvertes.fr/hal-01168816
    N(   R   R   (   R   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR   D  s    ~		c      
   #  sU  d d l  ‰ d d l m ‰	 d d d „  ƒ  Y‰ ‡ ‡	 f d †  ‰
 d „  ‰ d „  ‰ d	 „  ‰ g  ‡ ‡ ‡ ‡ ‡ ‡
 ‡ f d
 † ‰ ‡
 ‡ f d †  ‰ ‡ ‡
 ‡ ‡ ‡ ‡ ‡ f d †  ‰ ‡ ‡ ‡ ‡ f d †  ‰ t ˆ j ƒ } t ˆ j ƒ } t | ƒ } t | ƒ } ˆ j | | | | f ƒ } | rˆ j g  | D]0 } | D]# } | ˆ j | ˆ j | ƒ ^ q;q1ƒ j | | ƒ | d | … d | … f <n{ | r
ˆ j g  | D]: } | D]- } d t	 | ˆ j | ˆ j | ƒ ƒ ^ q¬q¢ƒ j | | ƒ | d | … d | … f <n  | r9g  | D] } | ˆ j | ƒ ^ q} n d g t | ƒ } | r{g  | D] } | ˆ j | ƒ ^ qY} n d g t | ƒ } | d | … d | … f j
 ƒ  t
 | ƒ t
 | ƒ d ‰ ˆ j g  t | ƒ D]5 } t | ƒ D]" } | | k r| | n ˆ ^ qëqÛƒ j | | ƒ | d | … | | | … f <ˆ j g  t | ƒ D]5 } t | ƒ D]" } | | k r~| | n ˆ ^ qbqRƒ j | | ƒ | | | | … d | … f <ˆ
 | | | ƒ ‰ t ˆ j ƒ } t ˆ j ƒ } t | ƒ } t | ƒ } ˆ j | | | | f ƒ } | rŒˆ j g  | D]0 } | D]# } | ˆ j | ˆ j | ƒ ^ q8q.ƒ j | | ƒ | d | … d | … f <n{ | rˆ j g  | D]: } | D]- } d t	 | ˆ j | ˆ j | ƒ ƒ ^ q©qŸƒ j | | ƒ | d | … d | … f <n  | r6g  | D] } | ˆ j | ƒ ^ q} n d g t | ƒ } |	 rxg  | D] } |	 ˆ j | ƒ ^ qV} n d g t | ƒ } | d | … d | … f j
 ƒ  t
 | ƒ t
 | ƒ d ‰ ˆ j g  t | ƒ D]5 } t | ƒ D]" } | | k r| | n ˆ ^ qèqØƒ j | | ƒ | d | … | | | … f <ˆ j g  t | ƒ D]5 } t | ƒ D]" } | | k r{| | n ˆ ^ q_qOƒ j | | ƒ | | | | … d | … f <ˆ
 | | | ƒ ‰  d d ‡  ‡ f d †  ƒ  Y} | ƒ  ‰ ‡ ‡ ‡ f d †  ‰ xO ˆ g  | | ˆ g  | | ˆ  d ƒ	 D]) \ } } } t | ƒ t | ƒ | f Vq$Wd S(   s›  GED (graph edit distance) calculation: advanced interface.

    Graph edit path is a sequence of node and edge edit operations
    transforming graph G1 to graph isomorphic to G2.  Edit operations
    include substitutions, deletions, and insertions.

    Graph edit distance is defined as minimum cost of edit path.

    Parameters
    ----------
    G1, G2: graphs
        The two graphs G1 and G2 must be of the same type.

    node_match : callable
        A function that returns True if node n1 in G1 and n2 in G2
        should be considered equal during matching.

        The function will be called like

           node_match(G1.nodes[n1], G2.nodes[n2]).

        That is, the function will receive the node attribute
        dictionaries for n1 and n2 as inputs.

        Ignored if node_subst_cost is specified.  If neither
        node_match nor node_subst_cost are specified then node
        attributes are not considered.

    edge_match : callable
        A function that returns True if the edge attribute dictionaries
        for the pair of nodes (u1, v1) in G1 and (u2, v2) in G2 should
        be considered equal during matching.

        The function will be called like

           edge_match(G1[u1][v1], G2[u2][v2]).

        That is, the function will receive the edge attribute
        dictionaries of the edges under consideration.

        Ignored if edge_subst_cost is specified.  If neither
        edge_match nor edge_subst_cost are specified then edge
        attributes are not considered.

    node_subst_cost, node_del_cost, node_ins_cost : callable
        Functions that return the costs of node substitution, node
        deletion, and node insertion, respectively.

        The functions will be called like

           node_subst_cost(G1.nodes[n1], G2.nodes[n2]),
           node_del_cost(G1.nodes[n1]),
           node_ins_cost(G2.nodes[n2]).

        That is, the functions will receive the node attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function node_subst_cost overrides node_match if specified.
        If neither node_match nor node_subst_cost are specified then
        default node substitution cost of 0 is used (node attributes
        are not considered during matching).

        If node_del_cost is not specified then default node deletion
        cost of 1 is used.  If node_ins_cost is not specified then
        default node insertion cost of 1 is used.

    edge_subst_cost, edge_del_cost, edge_ins_cost : callable
        Functions that return the costs of edge substitution, edge
        deletion, and edge insertion, respectively.

        The functions will be called like

           edge_subst_cost(G1[u1][v1], G2[u2][v2]),
           edge_del_cost(G1[u1][v1]),
           edge_ins_cost(G2[u2][v2]).

        That is, the functions will receive the edge attribute
        dictionaries as inputs.  The functions are expected to return
        positive numeric values.

        Function edge_subst_cost overrides edge_match if specified.
        If neither edge_match nor edge_subst_cost are specified then
        default edge substitution cost of 0 is used (edge attributes
        are not considered during matching).

        If edge_del_cost is not specified then default edge deletion
        cost of 1 is used.  If edge_ins_cost is not specified then
        default edge insertion cost of 1 is used.

    upper_bound : numeric
        Maximum edit distance to consider.

    strictly_decreasing : bool
        If True, return consecutive approximations of strictly
        decreasing cost.  Otherwise, return all edit paths of cost
        less than or equal to the previous minimum cost.

    Returns
    -------
    Generator of tuples (node_edit_path, edge_edit_path, cost)
        node_edit_path : list of tuples (u, v)
        edge_edit_path : list of tuples ((u1, v1), (u2, v2))
        cost : numeric

    See Also
    --------
    graph_edit_distance, optimize_graph_edit_distance, optimal_edit_paths

    References
    ----------
    .. [1] Zeina Abu-Aisheh, Romain Raveaux, Jean-Yves Ramel, Patrick
       Martineau. An Exact Graph Edit Distance Algorithm for Solving
       Pattern Recognition Problems. 4th International Conference on
       Pattern Recognition Applications and Methods 2015, Jan 2015,
       Lisbon, Portugal. 2015,
       <10.5220/0005209202710278>. <hal-01168816>
       https://hal.archives-ouvertes.fr/hal-01168816

    iÿÿÿÿN(   t   linear_sum_assignmentt
   CostMatrixc           B  s   e  Z d  „  Z RS(   c         S  s(   | |  _  | |  _ | |  _ | |  _ d  S(   N(   t   Ct   lsa_row_indt   lsa_col_indt   ls(   t   selfR!   R"   R#   R$   (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   __init__N  s    			(   t   __name__t
   __module__R&   (    (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR    M  s   c           sÓ   ˆ |  ƒ \ } } t  t t | ƒ ƒ | | ƒ } t ‡  ‡ f d †  | Dƒ ƒ } t  t t | ƒ ƒ | | ƒ } t ‡  ‡ f d †  | Dƒ ƒ } | | ˆ  | | <| | ˆ | | <ˆ |  | | |  | | f j ƒ  ƒ S(   Nc         3  s6   |  ], \ } } } | ˆ  k  r | ˆ k  r | Vq d  S(   N(    (   t   .0t   kt   it   j(   t   mt   n(    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>c  s    c         3  s6   |  ], \ } } } | ˆ  k r | ˆ k r | Vq d  S(   N(    (   R)   R*   R+   R,   (   R-   R.   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>e  s    (   t   zipt   ranget   lenR   t   sum(   R!   R-   R.   R"   R#   t   indexest	   subst_indt	   dummy_ind(   R    R   (   R-   R.   s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   make_CostMatrixZ  s    c         S  s–   g  t  | | ƒ D]" } | | k p0 | | | k ^ q } g  t  | | ƒ D]" } | | k pi | | | k ^ qJ } |  | d  d  … f d  d  … | f S(   N(   R0   (   R!   R+   R,   R-   R.   R*   t   row_indt   col_ind(    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt	   extract_Cm  s    99c         S  s–   g  t  | | ƒ D]" } | | k o0 | | | k ^ q } g  t  | | ƒ D]" } | | k oi | | | k ^ qJ } |  | d  d  … f d  d  … | f S(   N(   R0   (   R!   R+   R,   R-   R.   R*   R7   R8   (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   reduce_Cs  s    99c         S  sT   |  g  |  D] } | | k ^ q
 } x* t  | ƒ D] } | | | k c d 8<q0 W| S(   Ni   (   t   set(   t   indR+   R*   t   rind(    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt
   reduce_indy  s    #c           s©  t  ˆ
 ƒ ‰  t  ˆ ƒ ‰ g  t ˆ  ƒ D]H ‰ ˆ
 ˆ d  ˆ ˆ f k sg t ‡ ‡
 ‡ f d †  | Dƒ ƒ r% ˆ ^ q% ‰ g  t ˆ ƒ D]H ‰ ˆ ˆ d  ˆ ˆ f k sÂ t ‡ ‡ ‡ f d †  | Dƒ ƒ r€ ˆ ^ q€ ‰ t  ˆ ƒ ‰ t  ˆ ƒ ‰	 ˆ sò ˆ	 r{ˆ | j ˆ ˆ ˆ  ˆ ƒ } xt t ˆ ƒ ˆ ƒ D]\ } ‰ ˆ
 ˆ d  ‰ xè t t ˆ	 ƒ ˆ ƒ D]Ñ \ } ‰ ˆ ˆ d  ‰ t j ˆ ƒ s‹t j ˆ ƒ r¹t ‡ ‡ ‡ ‡ f d †  | Dƒ ƒ räqSqän+ t ‡ ‡ ‡ ‡ f d †  | Dƒ ƒ räqSn  ˆ ˆ ˆ f k rüqSn  ˆ ˆ ˆ f k rqSn  ˆ | | | f <qSWq#Wˆ | ˆ ˆ	 ƒ }	 t ‡  ‡ ‡ ‡ ‡ ‡	 f d †  t |	 j |	 j	 ƒ Dƒ ƒ }
 n$ g  }
 ˆ ˆ j
 d ƒ g  g  d ƒ }	 |
 |	 f S(	   s‹  
        Parameters:
            u, v: matched vertices, u=None or v=None for
               deletion/insertion
            pending_g, pending_h: lists of edges not yet mapped
            Ce: CostMatrix of pending edge mappings
            matched_uv: partial vertex edit path
                list of tuples (u, v) of previously matched vertex
                    mappings u<->v, u=None or v=None for
                    deletion/insertion

        Returns:
            list of (i, j): indices of edge mappings g<->h
            localCe: local CostMatrix of edge mappings
                (basically submatrix of Ce at cross of rows i, cols j)
        i   c         3  s;   |  ]1 \ } } ˆ ˆ  d   | ˆ f ˆ | f f k Vq d S(   i   N(    (   R)   t   pt   q(   R+   t	   pending_gt   u(    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>–  s   c         3  s;   |  ]1 \ } } ˆ ˆ  d   | ˆ f ˆ | f f k Vq d S(   i   N(    (   R)   R?   R@   (   R,   t	   pending_ht   v(    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>™  s   c         3  s]   |  ]S \ } } ˆ  | ˆ f k r3 ˆ | ˆ f k pT ˆ  ˆ | f k oT ˆ ˆ | f k Vq d  S(   N(    (   R)   R?   R@   (   t   gt   hRB   RD   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>©  s   c         3  sQ   |  ]G \ } } ˆ  | ˆ f ˆ | f f k oH ˆ | ˆ f ˆ | f f k Vq d  S(   N(    (   R)   R?   R@   (   RE   RF   RB   RD   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>®  s   c         3  su   |  ]k \ } } | ˆ k  s' | ˆ k  r | ˆ k  r= ˆ | n ˆ  ˆ | | ˆ k  r^ ˆ | n ˆ ˆ | f Vq d  S(   N(    (   R)   R*   t   l(   t   Mt   Nt   g_indt   h_indR-   R.   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>¸  s   	i    (   i    i    (   R1   R0   t   anyR!   R/   t   nxt   is_directedR   R"   R#   t   empty(   RB   RD   RA   RC   t   Cet
   matched_uvR!   R*   RG   t   localCet   ij(   R    R   R   R9   t   infR6   t   np(   RH   RI   RE   RJ   RF   RK   R+   R,   R-   R.   RA   RC   RB   RD   s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   match_edges€  sD    --""	c           s‹   t  | ƒ rƒ t | Œ  \ } } ˆ  t ‡  f d †  | Dƒ ƒ } ˆ t ‡ f d †  | Dƒ ƒ } ˆ ˆ |  j | | ˆ  ˆ ƒ | | ƒ S|  Sd  S(   Nc         3  s!   |  ] } | ˆ  k  r d  Vq d S(   i   N(    (   R)   t   t(   R-   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>Æ  s    c         3  s!   |  ] } | ˆ  k  r d  Vq d S(   i   N(    (   R)   RW   (   R.   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>Ç  s    (   R1   R/   R2   R!   (   RP   RS   R-   R.   R+   R,   t   m_it   n_j(   R6   R:   (   R-   R.   s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt	   reduce_CeÃ  s      %c      	   3  sî  t  | ƒ ‰ t  | ƒ ‰ t ‡ ‡ f d †  t | j | j ƒ Dƒ ƒ \ } }	 ˆ | ˆ k  re | | n d |	 ˆ k  r~ | |	 n d | | | |  ƒ \ }
 } ˆ	 | |
 t  | ƒ t  | ƒ ƒ } ˆ | | j | j | j ƒ rÞ nž ˆ ˆ | j | f |	 f ˆ ˆ ƒ ˆ
 | j | ˆ |	 f ƒ ˆ
 | j |	 ˆ | f ƒ | j | j | |	 f ƒ } | |	 f | |
 | | j | |	 f | j f Vt ƒ  } | |	 ‰  ‰ ˆ ˆ k rÇ‡  ‡ ‡ f d †  t	 ˆ ˆ ƒ Dƒ } n& ‡  ‡ ‡ f d †  t	 ˆ ˆ ƒ Dƒ } xÕ| D]Í\ } }	 ˆ | | j | |	 f | j ƒ r*qôn  ˆ ˆ | j | f |	 f ˆ ˆ ƒ | ˆ k  raˆ d n ˆ |	 ˆ k  rzˆ d n ˆ ƒ } ˆ | | j | |	 f | j | j ƒ r´qôn  ˆ | ˆ k  rÍ| | n d |	 ˆ k  ræ| |	 n d | | | |  ƒ \ }
 } ˆ | | j | |	 f | j | j ƒ r2qôn  ˆ	 | |
 t  | ƒ t  | ƒ ƒ } ˆ | | j | |	 f | j | j | j ƒ r‹qôn  | j
 | |	 f | |
 | | j | |	 f | j f ƒ qôWx" t | d d „  ƒD] } | VqÛWd S(   sê  
        Parameters:
            matched_uv: partial vertex edit path
                list of tuples (u, v) of vertex mappings u<->v,
                u=None or v=None for deletion/insertion
            pending_u, pending_v: lists of vertices not yet mapped
            Cv: CostMatrix of pending vertex mappings
            pending_g, pending_h: lists of edges not yet mapped
            Ce: CostMatrix of pending edge mappings
            matched_cost: cost of partial edit path

        Returns:
            sequence of
                (i, j): indices of vertex mapping u<->v
                Cv_ij: reduced CostMatrix of pending vertex mappings
                    (basically Cv with row i, col j removed)
                list of (x, y): indices of edge mappings g<->h
                Ce_xy: reduced CostMatrix of pending edge mappings
                    (basically Ce with rows x, cols y removed)
                cost: total cost of edit operation
            NOTE: most promising ops first
        c         3  s9   |  ]/ \ } } | ˆ  k  s' | ˆ k  r | | f Vq d  S(   N(    (   R)   R*   RG   (   R-   R.   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>é  s    	c         3  sC   |  ]9 } | ˆ  k r | ˆ k  s1 | ˆ ˆ k r | ˆ f Vq d  S(   N(    (   R)   RW   (   t   fixed_it   fixed_jR-   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>þ  s    c         3  sC   |  ]9 } | ˆ k r | ˆ k  s1 | ˆ ˆ  k r ˆ  | f Vq d  S(   N(    (   R)   RW   (   R[   R\   R.   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>  s    i   t   keyc         S  s   |  d |  d j  |  d j  S(   Ni   i   i   (   R$   (   RW   (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   <lambda>  s    N(   R1   t   minR/   R"   R#   R
   R$   R!   R   R0   R   t   sorted(   RQ   t	   pending_ut	   pending_vt   CvRA   RC   RP   t   matched_costR+   R,   t   xyRR   t   Ce_xyt   Cv_ijt   othert
   candidatesRW   (   R    R6   RV   t   pruneR:   RZ   R>   (   R[   R\   R-   R.   s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   get_edit_opsÌ  sN    4!!!.	)&$!++!%:c	         3  sD  ˆ | | j  | j  ƒ r d St t | ƒ t | ƒ ƒ s_ t ˆ j | ƒ ˆ _ |  | | f Vnáˆ |  | | | ˆ  ˆ | | ƒ }	 x½|	 D]µ\ }
 } } } } |
 \ } } ˆ | | | j  | j  ƒ rÌ q‡ n  | t | ƒ k  rí | j | ƒ n d } | t | ƒ k  r| j | ƒ n d } |  j | | f ƒ xk | D]c \ } } t ˆ  ƒ } t ˆ ƒ } | j | | k  rtˆ  | n d | | k  rˆ | n d f ƒ q4Wt t	 d „  | Dƒ ƒ ƒ } t t	 d „  | Dƒ ƒ ƒ } t ‡  f d †  t
 | ƒ Dƒ ƒ } t ‡ f d †  t
 | ƒ Dƒ ƒ } x5 ˆ |  | | | | ˆ  ˆ | | | ƒ	 D] } | Vq@W| d k	 rn| j | | ƒ n  | d k	 r| j | | ƒ n  |  j ƒ  xB t | t
 | ƒ ƒ D]+ \ } } | d k	 r­ˆ  j | | ƒ q­q­WxB t | t
 | ƒ ƒ D]+ \ } } | d k	 ròˆ j | | ƒ qòqòWx | D] } | j ƒ  q(Wq‡ Wd S(   s›  
        Parameters:
            matched_uv: partial vertex edit path
                list of tuples (u, v) of vertex mappings u<->v,
                u=None or v=None for deletion/insertion
            pending_u, pending_v: lists of vertices not yet mapped
            Cv: CostMatrix of pending vertex mappings
            matched_gh: partial edge edit path
                list of tuples (g, h) of edge mappings g<->h,
                g=None or h=None for deletion/insertion
            pending_g, pending_h: lists of edges not yet mapped
            Ce: CostMatrix of pending edge mappings
            matched_cost: cost of partial edit path

        Returns:
            sequence of (vertex_path, edge_path, cost)
                vertex_path: complete vertex edit path
                    list of tuples (u, v) of vertex mappings u<->v,
                    u=None or v=None for deletion/insertion
                edge_path: complete edge edit path
                    list of tuples (g, h) of edge mappings g<->h,
                    g=None or h=None for deletion/insertion
                cost: total cost of edit path
            NOTE: path costs are non-increasing
        Nc         s  s   |  ] \ } } | Vq d  S(   N(    (   R)   t   xt   y(    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>c  s    c         s  s   |  ] \ } } | Vq d  S(   N(    (   R)   Rl   Rm   (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>d  s    c         3  s6   |  ], } | t  ˆ  ƒ k  r* ˆ  j | ƒ n d  Vq d  S(   N(   R1   t   popR
   (   R)   Rl   (   RA   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>e  s   c         3  s6   |  ], } | t  ˆ  ƒ k  r* ˆ  j | ƒ n d  Vq d  S(   N(   R1   Rn   R
   (   R)   Rm   (   RC   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pys	   <genexpr>g  s   (   R$   t   maxR1   R_   t   valueRn   R
   R   R   R`   t   reversedt   insertR/   (   RQ   Ra   Rb   Rc   t
   matched_ghRA   RC   RP   Rd   t   edit_opsRS   Rg   Re   Rf   t	   edit_costR+   R,   RB   RD   Rl   Rm   t   len_gt   len_ht   sortedxt   sortedyt   Gt   HRW   RE   RF   (   Rk   t   get_edit_pathst   maxcostRj   (   RA   RC   s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR|     sX    *''$		
""i    i   t   MaxCostc             s   e  Z ‡  ‡ f d  †  Z RS(   c           s'   ˆ j  j ƒ  ˆ  j  j ƒ  d |  _ d  S(   Ni   (   R!   R2   Rp   (   R%   (   RP   Rc   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR&   Õ  s    (   R'   R(   R&   (    (   RP   Rc   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR~   Ô  s   c           sO   ˆ d  k	 r |  ˆ k r t Sn  |  ˆ  j k r2 t Sˆ rK |  ˆ  j k rK t Sd  S(   N(   R
   R   Rp   (   R   (   R}   t   strictly_decreasingR   (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyRj   Û  s    (    (    (   t   numpyt   scipy.optimizeR   R   t   nodesR1   t   zerost   arrayt   reshapet   intR2   R0   t   edges(   R   R   R   R   R   R   R   R   R   R   R   R   Ra   Rb   R-   R.   R!   RB   RD   t	   del_costst	   ins_costsR+   R,   RA   RC   RE   RF   R~   R   R   R   (    (   RP   R    Rc   R   R   R9   Rk   R|   RT   R   R6   RV   R}   RU   Rj   R:   RZ   R>   R   R   s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyR   Ê  s    €			$C	!Pg	=%	G%)):	H&	H&	=%	G%)):	H&	H&	"c         C  s`   d d l  m } y d d l } Wn | d ƒ ‚ n Xy d d l } Wn | d ƒ ‚ n Xd S(   s   Fixture for nose tests.iÿÿÿÿ(   t   SkipTestNs   NumPy not availables   SciPy not available(   t   noseRŠ   R€   t   scipy(   t   moduleRŠ   R€   RŒ   (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   setup_moduleò  s    (   t   __doc__t
   __future__R    t   matht   networkxRM   t   operatort   syst
   __author__t   __all__R	   R
   R   R   R   R   R   RŽ   (    (    (    s=   lib/python2.7/site-packages/networkx/algorithms/similarity.pyt   <module>   sL   
		ÿ ÿ %