Ë
    D^(hc4  ã                   ó´  — d Z ddlZddlZddlmZ ddlmZmZ g d¢Z	 G d„ dej                  «      Z ed«       ed	«      ej                  d
„ «       «       «       Zej                  ej                  fd„«       Zej                  d„ «       Zej                  d„ «       Zd„ Zd„ Zd„ Zdej                  fd„Z ed«       ej                  d¬«      d„ «       «       Zy)zÇ
Algorithms for chordal graphs.

A graph is chordal if every cycle of length at least 4 has a chord
(an edge joining two nodes not adjacent in the cycle).
https://en.wikipedia.org/wiki/Chordal_graph
é    N)Úconnected_components)Úarbitrary_elementÚnot_implemented_for)Ú
is_chordalÚfind_induced_nodesÚchordal_graph_cliquesÚchordal_graph_treewidthÚNetworkXTreewidthBoundExceededÚcomplete_to_chordal_graphc                   ó   — e Zd ZdZy)r
   zVException raised when a treewidth bound has been provided and it has
    been exceededN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úY/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/networkx/algorithms/chordal.pyr
   r
      s   „ òr   r
   ÚdirectedÚ
multigraphc                 ób   — t        | j                  «      dk  ryt        t        | «      «      dk(  S )u  Checks whether G is a chordal graph.

    A graph is chordal if every cycle of length at least 4 has a chord
    (an edge joining two nodes not adjacent in the cycle).

    Parameters
    ----------
    G : graph
      A NetworkX graph.

    Returns
    -------
    chordal : bool
      True if G is a chordal graph and False otherwise.

    Raises
    ------
    NetworkXNotImplemented
        The algorithm does not support DiGraph, MultiGraph and MultiDiGraph.

    Examples
    --------
    >>> e = [
    ...     (1, 2),
    ...     (1, 3),
    ...     (2, 3),
    ...     (2, 4),
    ...     (3, 4),
    ...     (3, 5),
    ...     (3, 6),
    ...     (4, 5),
    ...     (4, 6),
    ...     (5, 6),
    ... ]
    >>> G = nx.Graph(e)
    >>> nx.is_chordal(G)
    True

    Notes
    -----
    The routine tries to go through every node following maximum cardinality
    search. It returns False when it finds that the separator for any node
    is not a clique.  Based on the algorithms in [1]_.

    Self loops are ignored.

    References
    ----------
    .. [1] R. E. Tarjan and M. Yannakakis, Simple linear-time algorithms
       to test chordality of graphs, test acyclicity of hypergraphs, and
       selectively reduce acyclic hypergraphs, SIAM J. Comput., 13 (1984),
       pp. 566â€“579.
    é   Tr   )ÚlenÚnodesÚ_find_chordality_breaker)ÚGs    r   r   r      s.   € ôr ˆ1�7‰7ƒ|�qÒØÜÔ'¨Ó*Ó+¨qÑ0Ð0r   c                 óî  — t        | «      st        j                  d«      ‚t        j                  | «      }|j	                  ||«       t        «       }t        |||«      }|rF|\  }}}	|j                  |«       |D ]  }
|
|k7  sŒ	|j	                  ||
«       Œ t        |||«      }|rŒF|rL|j                  |«       | |   D ]3  }t        |t        | |   «      z  «      dk(  sŒ!|j                  |«        |S  |S )aÑ  Returns the set of induced nodes in the path from s to t.

    Parameters
    ----------
    G : graph
      A chordal NetworkX graph
    s : node
        Source node to look for induced nodes
    t : node
        Destination node to look for induced nodes
    treewidth_bound: float
        Maximum treewidth acceptable for the graph H. The search
        for induced nodes will end as soon as the treewidth_bound is exceeded.

    Returns
    -------
    induced_nodes : Set of nodes
        The set of induced nodes in the path from s to t in G

    Raises
    ------
    NetworkXError
        The algorithm does not support DiGraph, MultiGraph and MultiDiGraph.
        If the input graph is an instance of one of these classes, a
        :exc:`NetworkXError` is raised.
        The algorithm can only be applied to chordal graphs. If the input
        graph is found to be non-chordal, a :exc:`NetworkXError` is raised.

    Examples
    --------
    >>> G = nx.Graph()
    >>> G = nx.generators.classic.path_graph(10)
    >>> induced_nodes = nx.find_induced_nodes(G, 1, 9, 2)
    >>> sorted(induced_nodes)
    [1, 2, 3, 4, 5, 6, 7, 8, 9]

    Notes
    -----
    G must be a chordal graph and (s,t) an edge that is not in G.

    If a treewidth_bound is provided, the search for induced nodes will end
    as soon as the treewidth_bound is exceeded.

    The algorithm is inspired by Algorithm 4 in [1]_.
    A formal definition of induced node can also be found on that reference.

    Self Loops are ignored

    References
    ----------
    .. [1] Learning Bounded Treewidth Bayesian Networks.
       Gal Elidan, Stephen Gould; JMLR, 9(Dec):2699--2731, 2008.
       http://jmlr.csail.mit.edu/papers/volume9/elidan08a/elidan08a.pdf
    úInput graph is not chordal.é   )
r   ÚnxÚNetworkXErrorÚGraphÚadd_edgeÚsetr   ÚupdateÚaddr   )r   ÚsÚtÚtreewidth_boundÚHÚinduced_nodesÚtripletÚuÚvÚwÚns              r   r   r   \   s  € ôp �aŒ=Ü×ÑÐ<Ó=Ð=ä
�‰�‹€AØ‡J�Jˆq�!ÔÜ“E€MÜ& q¨!¨_Ó=€GÙ
Ø‰	ˆˆAˆqØ×Ñ˜WÔ%Øò 	!ˆAØ�A‹vØ—
‘
˜1˜aÕ ð	!ô +¨1¨a°ÓAˆò ñ à×Ñ˜!ÔØ�1‘ò 	ˆAÜ�=¤3 q¨¡t£9Ñ,Ó-°Ó2Ø×!Ñ! !Ô$ØØÐð		ð Ðr   c              #   óÜ  ‡ K  — ˆ fd„t        ‰ «      D «       D �]O  }|j                  «       dk(  rIt        j                  |«      dkD  rt        j                  d«      ‚t        |j                  «       «      –— Œ`t        |j                  «       «      }t        |«      }|j                  |«       |h}|h}|r¦t        |||«      }|j                  |«       |j                  |«       t        |j                  |«      «      |z  }|j                  |«      }t        |«      r&|j                  |«       ||k\  st        |«      –— |}nt        j                  d«      ‚|rŒ¦t        |«      –— �ŒR y­w)aU  Returns all maximal cliques of a chordal graph.

    The algorithm breaks the graph in connected components and performs a
    maximum cardinality search in each component to get the cliques.

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

    Yields
    ------
    frozenset of nodes
        Maximal cliques, each of which is a frozenset of
        nodes in `G`. The order of cliques is arbitrary.

    Raises
    ------
    NetworkXError
        The algorithm does not support DiGraph, MultiGraph and MultiDiGraph.
        The algorithm can only be applied to chordal graphs. If the input
        graph is found to be non-chordal, a :exc:`NetworkXError` is raised.

    Examples
    --------
    >>> e = [
    ...     (1, 2),
    ...     (1, 3),
    ...     (2, 3),
    ...     (2, 4),
    ...     (3, 4),
    ...     (3, 5),
    ...     (3, 6),
    ...     (4, 5),
    ...     (4, 6),
    ...     (5, 6),
    ...     (7, 8),
    ... ]
    >>> G = nx.Graph(e)
    >>> G.add_node(9)
    >>> cliques = [c for c in chordal_graph_cliques(G)]
    >>> cliques[0]
    frozenset({1, 2, 3})
    c              3   ó\   •K  — | ]#  }‰j                  |«      j                  «       –— Œ% y ­w©N)ÚsubgraphÚcopy)Ú.0Úcr   s     €r   ú	<genexpr>z(chordal_graph_cliques.<locals>.<genexpr>Ú   s"   øè ø€ ÒD qˆa�j‰j˜‹m× Ñ ×"ÑDùs   ƒ),é   r   r   N)r   Únumber_of_nodesr   Únumber_of_selfloopsr    Ú	frozensetr   r#   r   ÚremoveÚ_max_cardinality_noder%   Ú	neighborsr3   Ú_is_complete_graph)r   ÚCÚ
unnumberedr-   ÚnumberedÚclique_wanna_beÚnew_clique_wanna_beÚsgs   `       r   r   r   ¬   sC  øè ø€ ó\ EÔ,@ÀÓ,CÔDó -ˆØ×ÑÓ !Ò#Ü×%Ñ% aÓ(¨1Ò,Ü×&Ñ&Ð'DÓEÐEÜ˜AŸG™G›IÓ&Ó&ä˜QŸW™W›Y›ˆJÜ! !Ó$ˆAØ×Ñ˜aÔ Ø�sˆHØ ˜cˆOÙÜ)¨!¨Z¸ÓB�Ø×!Ñ! !Ô$Ø—‘˜Q”Ü&)¨!¯+©+°a«.Ó&9¸HÑ&DÐ#Ø—Z‘Z Ó0�Ü% bÔ)Ø'×+Ñ+¨AÔ.Ø.°/ÒAÜ'¨Ó8Ò8Ø&9‘Oä×*Ñ*Ð+HÓIÐIò ô ˜OÓ,Ô,ñ1-ùs   ƒEE,ÅE,c                 ó®   — t        | «      st        j                  d«      ‚d}t        j                  | «      D ]  }t	        |t        |«      «      }Œ |dz
  S )a¼  Returns the treewidth of the chordal graph G.

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

    Returns
    -------
    treewidth : int
        The size of the largest clique in the graph minus one.

    Raises
    ------
    NetworkXError
        The algorithm does not support DiGraph, MultiGraph and MultiDiGraph.
        The algorithm can only be applied to chordal graphs. If the input
        graph is found to be non-chordal, a :exc:`NetworkXError` is raised.

    Examples
    --------
    >>> e = [
    ...     (1, 2),
    ...     (1, 3),
    ...     (2, 3),
    ...     (2, 4),
    ...     (3, 4),
    ...     (3, 5),
    ...     (3, 6),
    ...     (4, 5),
    ...     (4, 6),
    ...     (5, 6),
    ...     (7, 8),
    ... ]
    >>> G = nx.Graph(e)
    >>> G.add_node(9)
    >>> nx.chordal_graph_treewidth(G)
    3

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Tree_decomposition#Treewidth
    r   éÿÿÿÿr8   )r   r   r    r   Úmaxr   )r   Ú
max_cliqueÚcliques      r   r	   r	   õ   sW   € ôZ �aŒ=Ü×ÑÐ<Ó=Ð=à€JÜ×*Ñ*¨1Ó-ò 2ˆÜ˜¤S¨£[Ó1‰
ð2à˜‰>Ðr   c                 óÈ   — t        j                  | «      dkD  rt        j                  d«      ‚| j                  «       }|dk  ry| j	                  «       }||dz
  z  dz  }||k(  S )z&Returns True if G is a complete graph.r   z'Self loop found in _is_complete_graph()r   Tr8   )r   r:   r    r9   Únumber_of_edges)r   r/   ÚeÚ	max_edgess       r   r?   r?   +  si   € ä	×Ñ˜aÓ  1Ò$Ü×ÑÐHÓIÐIØ	×ÑÓ€AØˆ1‚uØØ	×ÑÓ€AØ�a˜!‘e‘ Ñ!€IØ�	‰>Ðr   c                 ó¬   — t        | «      }| D ]D  }|t        t        | |   j                  «       «      |gz   «      z
  }|sŒ2||j                  «       fc S  y)z5Given a non-complete graph G, returns a missing edge.N)r#   ÚlistÚkeysÚpop)r   r   r,   Úmissings       r   Ú_find_missing_edgerT   7  sS   € ä�‹F€EØò &ˆØœ#œd 1 Q¡4§9¡9£;Ó/°1°#Ñ5Ó6Ñ6ˆÚØ�w—{‘{“}Ð%Ò%ñ&r   c                 óx   — d}|D ]-  }t        | |   D �cg c]	  }||v sŒ|‘Œ c}«      }||kD  sŒ*|}|}Œ/ S c c}w )z`Returns a the node in choices that has more connections in G
    to nodes in wanna_connect.
    rG   )r   )r   ÚchoicesÚwanna_connectÚ
max_numberÚxÚyÚnumberÚmax_cardinality_nodes           r   r=   r=   @  sX   € ð €JØò %ˆÜ  1¡Ö<˜A¨¨mÒ);’aÒ<Ó=ˆØ�JÓØˆJØ#$Ñ ð	%ð
  Ðùò	 =s   ”	7
ž7
c                 óò  — t        | «      dk(  rt        j                  d«      ‚t        | «      }|€t	        | «      }|j                  |«       |h}d}|r¤t        | ||«      }|j                  |«       |j                  |«       t        | |   «      |z  }| j                  |«      }t        |«      r2t        |t        |«      «      }||kD  r+t        j                  d|› �«      ‚t        |«      \  }	}
|	||
fS |rŒ¤y)aG  Given a graph G, starts a max cardinality search
    (starting from s if s is given and from an arbitrary node otherwise)
    trying to find a non-chordal cycle.

    If it does find one, it returns (u,v,w) where u,v,w are the three
    nodes that together with s are involved in the cycle.

    It ignores any self loops.
    r   zGraph has no nodes.rG   ztreewidth_bound exceeded: r   )r   r   ÚNetworkXPointlessConceptr#   r   r<   r=   r%   r3   r?   rH   r
   rT   )r   r&   r(   rA   rB   Úcurrent_treewidthr-   rC   rE   r,   r.   s              r   r   r   M  s  € ô ˆ1ƒv�‚{Ü×)Ñ)Ð*?Ó@Ð@Ü�Q“€JØ€yÜ˜aÓ ˆØ×Ñ�aÔØˆs€HØÐÙ
Ü! ! Z°Ó:ˆØ×Ñ˜!ÔØ�‰�QŒÜ˜a ™d›) hÑ.ˆØ�Z‰Z˜Ó(ˆÜ˜bÔ!ä #Ð$5´s¸?Ó7KÓ LÐØ  ?Ò2Ü×7Ñ7Ø0Ð1BÐ0CÐDóð ô (¨Ó+‰FˆQ�Ø�q˜!�9Ðò# ð$ r   T)Úreturns_graphc           	      ó<  ‡— | j                  «       }|D �ci c]  }|d“Œ }}t        j                  |«      r||fS t        «       }|j	                  «       D �ci c]  }|d“Œ c}Št        |j	                  «       «      }t        t        |j	                  «       «      dd«      D ]Ö  }t        |ˆfd„¬«      }|j                  |«       |||<   g }|D ]“  }	| j                  |	|«      r|j                  |	«       Œ'‰|	   }
|D �cg c]  }‰|   |
k  sŒ|‘Œ }}t        j                  |j                  |||	gz   «      |	|«      sŒp|j                  |	«       |j                  ||	f«       Œ• |D ]  }‰|xx   dz  cc<   Œ ŒØ |j                  |«       ||fS c c}w c c}w c c}w )a  Return a copy of G completed to a chordal graph

    Adds edges to a copy of G to create a chordal graph. A graph G=(V,E) is
    called chordal if for each cycle with length bigger than 3, there exist
    two non-adjacent nodes connected by an edge (called a chord).

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

    Returns
    -------
    H : NetworkX graph
        The chordal enhancement of G
    alpha : Dictionary
            The elimination ordering of nodes of G

    Notes
    -----
    There are different approaches to calculate the chordal
    enhancement of a graph. The algorithm used here is called
    MCS-M and gives at least minimal (local) triangulation of graph. Note
    that this triangulation is not necessarily a global minimum.

    https://en.wikipedia.org/wiki/Chordal_graph

    References
    ----------
    .. [1] Berry, Anne & Blair, Jean & Heggernes, Pinar & Peyton, Barry. (2004)
           Maximum Cardinality Search for Computing Minimal Triangulations of
           Graphs.  Algorithmica. 39. 287-298. 10.1007/s00453-004-1084-3.

    Examples
    --------
    >>> from networkx.algorithms.chordal import complete_to_chordal_graph
    >>> G = nx.wheel_graph(10)
    >>> H, alpha = complete_to_chordal_graph(G)
    r   rG   c                 ó   •— ‰|    S r2   r   )ÚnodeÚweights    €r   ú<lambda>z+complete_to_chordal_graph.<locals>.<lambda>§  s   ø€ °6¸$±<€ r   )Úkeyr8   )r4   r   r   r#   r   rP   Úranger   rH   r<   Úhas_edgeÚappendÚhas_pathr3   r%   Úadd_edges_from)r   r)   rc   ÚalphaÚchordsÚunnumbered_nodesÚiÚzÚupdate_nodesrZ   Úy_weightÚlower_nodesrd   s               @r   r   r   t  sž  ø€ ðT 	
�‰‹€AØ!"Ö#˜ˆT�1‰WÐ#€EÐ#Ü	‡}�}�QÔØ�%ˆxˆÜ‹U€FØ"#§'¡'£)Ö,˜$ˆd�A‰gÒ,€FÜ˜AŸG™G›I“ÐÜ”3�q—w‘w“y“> 1 bÓ)ò ˆäÐ Ó&?Ô@ˆØ×Ñ Ô"Øˆˆa‰ØˆØ!ò 	'ˆAØ�z‰z˜!˜QÔØ×#Ñ# AÕ&ð " !™9�à%5öØ!¸À¹ÈÓ9P’Dð�ð ô —;‘;˜qŸz™z¨+¸¸A¸Ñ*>Ó?ÀÀAÕFØ ×'Ñ'¨Ô*Ø—J‘J  1˜vÕ&ð	'ð !ò 	ˆDØ�4‹L˜AÑŒLñ	ð'ð* ×Ñ�VÔØˆeˆ8€Oùò9 $ùò -ùòs   –
FÁ
FÃ>FÄF)r   ÚsysÚnetworkxr   Únetworkx.algorithms.componentsr   Únetworkx.utilsr   r   Ú__all__ÚNetworkXExceptionr
   Ú_dispatchabler   Úmaxsizer   r   r	   r?   rT   r=   r   r   r   r   r   ú<module>r|      s  ðñó ã Ý ?ß Aò€ô R×%9Ñ%9ô ñ
 �ZÓ Ù�\Ó"Ø×Ññ81ó ó #ó !ð81ðv ×ÑØ03·±ò Ló ðLð^ ×ÑñE-ó ðE-ðP ×Ññ2ó ð2òj	ò&ò
 ð #'¸¿¹ó $ñN �ZÓ Ø€×Ñ Ô%ñEó &ó !ñEr   