§
    bŠtjc4  ã                   ó´  — 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dS )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dS )r
   zVException raised when a treewidth bound has been provided and it has
    been exceededN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úY/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/networkx/algorithms/chordal.pyr
   r
      s   € € € € € ðð ð ð r   r
   ÚdirectedÚ
multigraphc                 óv   — t          | j        ¦  «        dk    rdS 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      s9   € õr ˆ1Œ7�|„|�qÒÐØˆtÝÕ'¨Ñ*Ô*Ñ+Ô+¨qÒ0Ð0r   c                 óD  — t          | ¦  «        st          j        d¦  «        ‚t          j        | ¦  «        }|                     ||¦  «         t          ¦   «         }t          |||¦  «        }|rO|\  }}}	|                     |¦  «         |D ]}
|
|k    r|                     ||
¦  «         Œt          |||¦  «        }|°O|r`|                     |¦  «         | |         D ]B}t          |t          | |         ¦  «        z  ¦  «        dk    r|                     |¦  «          nŒC|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   \   sJ  € õp �a‰=Œ=ð >ÝÔÐ<Ñ=Ô=Ð=å
Œ�‰Œ€AØ‡J‚Jˆq�!ÑÔÐÝ‘E”E€MÝ& q¨!¨_Ñ=Ô=€GØ
ð BØ‰	ˆˆAˆqØ×Ò˜WÑ%Ô%Ð%Øð 	!ð 	!ˆAØ�AŠvˆvØ—
’
˜1˜aÑ Ô Ð øÝ*¨1¨a°ÑAÔAˆð ð Bð ð à×Ò˜!ÑÔÐØ�1”ð 	ð 	ˆAÝ�=¥3 q¨¤t¡9¤9Ñ,Ñ-Ô-°Ò2Ð2Ø×!Ò! !Ñ$Ô$Ð$Ø�ð 3ð Ðr   c              #   ój  ‡ K  — ˆ fd„t          ‰ ¦  «        D ¦   «         D �]’}|                     ¦   «         dk    rPt          j        |¦  «        dk    rt          j        d¦  «        ‚t          |                     ¦   «         ¦  «        V — Œkt          |                     ¦   «         ¦  «        }t          |¦  «        }| 	                    |¦  «         |h}|h}|rÉt          |||¦  «        }| 	                    |¦  «         |                     |¦  «         t          |                     |¦  «        ¦  «        |z  }|                     |¦  «        }t          |¦  «        r/|                     |¦  «         ||k    st          |¦  «        V — |}nt          j        d¦  «        ‚|°Ét          |¦  «        V — �Œ”dS )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   óf   •K  — | ]+}‰                      |¦  «                             ¦   «         V — Œ,d S ©N)ÚsubgraphÚcopy)Ú.0Úcr   s     €r   ú	<genexpr>z(chordal_graph_cliques.<locals>.<genexpr>Ú   s9   øè è € ÐDÐD qˆa�jŠj˜‰mŒm× Ò Ñ"Ô"ÐDÐDÐDÐDÐDÐDr   é   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   ¬   sÍ  øè è € ð\ EÐDÐDÐDÕ,@ÀÑ,CÔ,CÐDÑDÔDð -ñ -ˆØ×ÒÑÔ !Ò#Ð#ÝÔ% aÑ(Ô(¨1Ò,Ð,ÝÔ&Ð'DÑEÔEÐEÝ˜AŸGšG™IœIÑ&Ô&Ð&Ð&Ð&Ð&å˜QŸWšW™YœY™œˆJÝ! !Ñ$Ô$ˆAØ×Ò˜aÑ Ô Ð Ø�sˆHØ ˜cˆOØð JÝ)¨!¨Z¸ÑBÔB�Ø×!Ò! !Ñ$Ô$Ð$Ø—’˜Q‘”�Ý&)¨!¯+ª+°a©.¬.Ñ&9Ô&9¸HÑ&DÐ#Ø—Z’Z Ñ0Ô0�Ý% bÑ)Ô)ð JØ'×+Ò+¨AÑ.Ô.Ð.Ø.°/ÒAÐAÝ'¨Ñ8Ô8Ð8Ð8Ð8Ø&9�O�OåÔ*Ð+HÑIÔIÐIð ð Jõ ˜OÑ,Ô,Ð,Ð,Ð,Ñ,ð1-ð -r   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	   õ   se   € õZ �a‰=Œ=ð >ÝÔÐ<Ñ=Ô=Ð=à€JÝÔ*¨1Ñ-Ô-ð 2ð 2ˆÝ˜¥S¨¡[¤[Ñ1Ô1ˆ
ˆ
Ø˜‰>Ðr   c                 óÜ   — t          j        | ¦  «        dk    rt          j        d¦  «        ‚|                      ¦   «         }|dk     rdS |                      ¦   «         }||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?   +  sv   € å	Ô˜aÑ Ô  1Ò$Ð$ÝÔÐHÑIÔIÐIØ	×ÒÑÔ€AØˆ1‚u€uØˆtØ	×ÒÑÔ€AØ�a˜!‘e‘ Ñ!€IØ�	Š>Ðr   c                 óØ   — t          | ¦  «        }| D ]W}|t          t          | |                              ¦   «         ¦  «        |gz   ¦  «        z
  }|r||                     ¦   «         fc S ŒXdS )z5Given a non-complete graph G, returns a missing edge.N)r#   ÚlistÚkeysÚpop)r   r   r,   Úmissings       r   Ú_find_missing_edgerT   7  sy   € å�‰FŒF€EØð &ð &ˆØ�#�d 1 Q¤4§9¢9¡;¤;Ñ/Ô/°1°#Ñ5Ñ6Ô6Ñ6ˆØð 	&Ø�w—{’{‘}”}Ð%Ð%Ð%Ð%ð	&ð&ð &r   c                 ól   ‡— d}|D ]-}t          ˆfd„| |         D ¦   «         ¦  «        }||k    r|}|}Œ.|S )z`Returns a the node in choices that has more connections in G
    to nodes in wanna_connect.
    rG   c                 ó   •— g | ]}|‰v ¯|‘Œ	S r   r   )r5   ÚyÚwanna_connects     €r   ú
<listcomp>z)_max_cardinality_node.<locals>.<listcomp>F  s#   ø€ Ð<Ð<Ð<˜A¨¨mÐ);Ð);�aÐ);Ð);Ð);r   )r   )r   ÚchoicesrX   Ú
max_numberÚxÚnumberÚmax_cardinality_nodes     `    r   r=   r=   @  s\   ø€ ð €JØð %ð %ˆÝÐ<Ð<Ð<Ð<  1¤Ð<Ñ<Ô<Ñ=Ô=ˆØ�JÒÐØˆJØ#$Ð øØÐr   c                 ób  — t          | ¦  «        dk    rt          j        d¦  «        ‚t          | ¦  «        }|€t	          | ¦  «        }|                     |¦  «         |h}d}|rËt          | ||¦  «        }|                     |¦  «         |                     |¦  «         t          | |         ¦  «        |z  }|                      |¦  «        }t          |¦  «        r;t          |t          |¦  «        ¦  «        }||k    rt          j        d|› �¦  «        ‚nt          |¦  «        \  }	}
|	||
fS |°ËdS )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.NrG   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  sN  € õ ˆ1�v„v�‚{€{ÝÔ)Ð*?Ñ@Ô@Ð@Ý�Q‘”€JØ€yÝ˜aÑ Ô ˆØ×Ò�aÑÔÐØˆs€HØÐØ
ð Ý! ! Z°Ñ:Ô:ˆØ×Ò˜!ÑÔÐØ�Š�Q‰ŒˆÝ˜a œd™)œ) hÑ.ˆØ�ZŠZ˜Ñ(Ô(ˆÝ˜bÑ!Ô!ð 	å #Ð$5µs¸?Ñ7KÔ7KÑ LÔ LÐØ  ?Ò2Ð2ÝÔ7ØDÐ1BÐDÐDñô ð ð 3õ (¨Ñ+Ô+‰FˆQ�Ø�q˜!�9Ðð# ð ð$ ˆ2r   T)Úreturns_graphc           	      óv  ‡‡— |                       ¦   «         }d„ |D ¦   «         }t          j        |¦  «        r||fS t          ¦   «         }d„ |                     ¦   «         D ¦   «         Št          |                     ¦   «         ¦  «        }t          t          |                     ¦   «         ¦  «        dd¦  «        D ]é}t          |ˆfd„¬¦  «        }| 	                    |¦  «         |||<   g }|D ]Ÿ}|  
                    ||¦  «        r|                     |¦  «         Œ.‰|         Šˆˆfd„|D ¦   «         }	t          j        |                     |	||gz   ¦  «        ||¦  «        r,|                     |¦  «         |                     ||f¦  «         Œ |D ]}
‰|
xx         dz  cc<   ŒŒê|                     |¦  «         ||fS )	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)
    c                 ó   — i | ]}|d “ŒS ©r   r   ©r5   Únodes     r   ú
<dictcomp>z-complete_to_chordal_graph.<locals>.<dictcomp>Ÿ  s   € Ð#Ð#Ð#˜ˆT�1Ð#Ð#Ð#r   c                 ó   — i | ]}|d “ŒS re   r   rf   s     r   rh   z-complete_to_chordal_graph.<locals>.<dictcomp>£  s   € Ð,Ð,Ð,˜$ˆd�AÐ,Ð,Ð,r   r   rG   c                 ó   •— ‰|          S r2   r   )rg   Úweights    €r   ú<lambda>z+complete_to_chordal_graph.<locals>.<lambda>§  s   ø€ °6¸$´<€ r   )Úkeyc                 ó,   •— g | ]}‰|         ‰k     ¯|‘ŒS r   r   )r5   rg   rk   Úy_weights     €€r   rY   z-complete_to_chordal_graph.<locals>.<listcomp>±  s.   ø€ ð ð ð Ø!¸À¼ÈÒ9PÐ9P�DÐ9PÐ9PÐ9Pr   r8   )r4   r   r   r#   r   rP   Úranger   rH   r<   Úhas_edgeÚappendÚhas_pathr3   r%   Úadd_edges_from)r   r)   ÚalphaÚchordsÚunnumbered_nodesÚiÚzÚupdate_nodesrW   Úlower_nodesrg   rk   ro   s              @@r   r   r   t  s÷  øø€ ðT 	
�Š‰Œ€AØ#Ð# Ð#Ñ#Ô#€EÝ	„}�QÑÔð Ø�%ˆxˆÝ‰UŒU€FØ,Ð, !§'¢'¡)¤)Ð,Ñ,Ô,€FÝ˜AŸGšG™IœI‘”ÐÝ•3�q—w’w‘y”y‘>”> 1 bÑ)Ô)ð ð ˆåÐ Ð&?Ð&?Ð&?Ð&?Ð@Ñ@Ô@ˆØ×Ò Ñ"Ô"Ð"Øˆˆa‰ØˆØ!ð 	'ð 	'ˆAØ�zŠz˜!˜QÑÔð 
'Ø×#Ò# AÑ&Ô&Ð&Ð&ð " !œ9�ðð ð ð ð Ø%5ðñ ô �õ ”;˜qŸzšz¨+¸¸A¸Ñ*>Ñ?Ô?ÀÀAÑFÔFð 'Ø ×'Ò'¨Ñ*Ô*Ð*Ø—J’J  1˜vÑ&Ô&Ð&øà ð 	ð 	ˆDØ�4ˆLˆLŒL˜AÑˆLˆL‰LˆLð	à×Ò�VÑÔÐØˆeˆ8€Or   )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Ð AÐ AÐ AÐ AÐ AÐ AÐ Aðð ð €ðð ð ð ð  RÔ%9ñ ô ð ð
 Ð�ZÑ Ô ØÐ�\Ñ"Ô"ØÔð81ð 81ñ Ôñ #Ô"ñ !Ô ð81ðv ÔØ03´ð Lð Lð Lñ ÔðLð^ ÔðE-ð E-ñ ÔðE-ðP Ôð2ð 2ñ Ôð2ðj	ð 	ð 	ð&ð &ð &ð
 ð 
 ð 
 ð #'¸¼ð $ð $ð $ð $ðN Ð�ZÑ Ô Ø€Ô Ð%Ñ%Ô%ðEð Eñ &Ô%ñ !Ô ðEð Eð Er   