ó
    …~iÅ   ã                   óD  • S r SSKrSSKrSSKJrJrJr  SSKrSSK	J
r
  SS/r\
" S5      \
" S5      \R                  " S	S
9S 5       5       5       r\
" S5      \
" S5      \R                  " S	S
9S 5       5       5       r " S S5      rS r\R                  " S	S
9\4S j5       rg)a,  Functions for computing treewidth decomposition.

Treewidth of an undirected graph is a number associated with the graph.
It can be defined as the size of the largest vertex set (bag) in a tree
decomposition of the graph minus one.

`Wikipedia: Treewidth <https://en.wikipedia.org/wiki/Treewidth>`_

The notions of treewidth and tree decomposition have gained their
attractiveness partly because many graph and network problems that are
intractable (e.g., NP-hard) on arbitrary graphs become efficiently
solvable (e.g., with a linear time algorithm) when the treewidth of the
input graphs is bounded by a constant [1]_ [2]_.

There are two different functions for computing a tree decomposition:
:func:`treewidth_min_degree` and :func:`treewidth_min_fill_in`.

.. [1] Hans L. Bodlaender and Arie M. C. A. Koster. 2010. "Treewidth
      computations I.Upper bounds". Inf. Comput. 208, 3 (March 2010),259-275.
      http://dx.doi.org/10.1016/j.ic.2009.03.008

.. [2] Hans L. Bodlaender. "Discovering Treewidth". Institute of Information
      and Computing Sciences, Utrecht University.
      Technical Report UU-CS-2005-018.
      http://www.cs.uu.nl

.. [3] K. Wang, Z. Lu, and J. Hicks *Treewidth*.
      https://web.archive.org/web/20210507025929/http://web.eecs.utk.edu/~cphill25/cs594_spring2015_projects/treewidth.pdf

é    N)ÚheapifyÚheappopÚheappush)Únot_implemented_forÚtreewidth_min_degreeÚtreewidth_min_fill_inÚdirectedÚ
multigraphT)Úreturns_graphc                 ó:   ^• [        U 5      m[        U U4S j5      $ )aä  Returns a treewidth decomposition using the Minimum Degree heuristic.

The heuristic chooses the nodes according to their degree, i.e., first
the node with the lowest degree is chosen, then the graph is updated
and the corresponding node is removed. Next, a new node with the lowest
degree is chosen, and so on.

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

Returns
-------
Treewidth decomposition : (int, Graph) tuple
      2-tuple with treewidth and the corresponding decomposed tree.
c                 ó&   >• TR                  U 5      $ ©N)Ú	best_node)ÚgraphÚdeg_heuristics    €Úh/home/mande/repo/quber/.venv/lib/python3.13/site-packages/networkx/algorithms/approximation/treewidth.pyÚ<lambda>Ú&treewidth_min_degree.<locals>.<lambda>?   s   ø€ ¨]×-DÑ-DÀUÔ-Kó    )ÚMinDegreeHeuristicÚtreewidth_decomp)ÚGr   s    @r   r   r   *   s   ø€ ô( ' qÓ)€MÜ˜AÔKÓLÐLr   c                 ó"   • [        U [        5      $ )a�  Returns a treewidth decomposition using the Minimum Fill-in heuristic.

The heuristic chooses a node from the graph, where the number of edges
added turning the neighborhood of the chosen node into clique is as
small as possible.

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

Returns
-------
Treewidth decomposition : (int, Graph) tuple
    2-tuple with treewidth and the corresponding decomposed tree.
)r   Úmin_fill_in_heuristic)r   s    r   r   r   B   s   € ô& ˜AÔ4Ó5Ð5r   c                   ó$   • \ rS rSrSrS rS rSrg)r   éX   a1  Implements the Minimum Degree heuristic.

The heuristic chooses the nodes according to their degree
(number of neighbors), i.e., first the node with the lowest degree is
chosen, then the graph is updated and the corresponding node is
removed. Next, a new node with the lowest degree is chosen, and so on.
c                 ó  • Xl         / U l        / U l        [        R                  " 5       U l        U H?  nU R                  R                  [        X   5      [        U R                  5      U45        MA     [        U R                  5        g r   )	Ú_graphÚ_update_nodesÚ_degreeqÚ	itertoolsÚcountÚappendÚlenÚnextr   )Úselfr   Úns      r   Ú__init__ÚMinDegreeHeuristic.__init__a   sf   € ØŒð  ˆÔàˆŒÜ—_’_Ó&ˆŒ
ó ˆAØ�M‰M× Ñ ¤# e¡h£-´°d·j±jÓ1AÀ1Ð!EÖFñ ä�—‘Õr   c                 óV  • U R                    H:  n[        U R                  [        X   5      [	        U R
                  5      U45        M<     U R                  (       aN  [        U R                  5      u  p4nXQ;  d  [        X   5      U:w  a  MA  U[        U5      S-
  :X  a  g X   U l         U$ g )Né   )r   r   r    r$   r%   r"   r   )r&   r   r'   Ú
min_degreeÚ_Ú	elim_nodes         r   r   ÚMinDegreeHeuristic.best_nodeo   s•   € à×#Ô#ˆAä�T—]‘]¤S¨©£]´D¸¿¹Ó4DÀaÐ$HÖIñ $ð
 �m�mÜ)0°·±Ó)?Ñ&ˆZ˜IØÓ%¬¨UÑ-=Ó)>À*Ó)LáØœs 5›z¨A™~Ó-àð "'Ñ!1ˆDÔØÐð r   )r    r   r   r"   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r(   r   Ú__static_attributes__© r   r   r   r   X   s   † ñòõr   r   c                 óZ  ^ • [        T 5      S:X  a  gSn[        R                  n[        T U 4S jS9n[        T US      5      nU[        T 5      S-
  :X  a  gU HO  nSnT U   nU H%  nU[        UT U   -
  5      S-
  -  nUSU-  :¼  d  M%    O   US-  nXb:  d  MA  US:X  a  Us  $ UnUnMQ     U$ )a¨  Implements the Minimum Degree heuristic.

graph_dict: dict keyed by node to sets of neighbors (no self-loops)

Returns the node from the graph, where the number of edges added when
turning the neighborhood of the chosen node into clique is as small as
possible. This algorithm chooses the nodes using the Minimum Fill-In
heuristic. The running time of the algorithm is :math:`O(V^3)` and it uses
additional constant memory.
r   Nc                 ó    >• [        TU    5      $ r   )r$   )ÚxÚ
graph_dicts    €r   r   Ú'min_fill_in_heuristic.<locals>.<lambda>›   s   ø€ ´s¸:Àa¹=Ô7Ir   )Úkeyr+   é   )r$   ÚsysÚmaxsizeÚsorted)	r:   Úmin_fill_in_nodeÚmin_fill_inÚnodes_by_degreer,   ÚnodeÚnum_fill_inÚnbrsÚnbrs	   `        r   r   r   ‡   sß   ø€ ô ˆ:ƒ˜!ÓØàÐä—+‘+€Kô ˜ZÔ-IÑJ€OÜ�Z °Ñ 2Ñ3Ó4€Jð ”S˜“_ qÑ(Ó(ØãˆØˆØ˜$ÑˆÛˆCð œ3˜t j°¡oÑ5Ó6¸Ñ:Ñ:ˆKØ˜a +™oÕ-Ùñ ð 	�qÑˆàÕ$Ø˜aÓØ’Ø%ˆKØ#Òñ!  ð$ Ðr   c                 ó  • U  Vs0 s H  o"[        X   5      U1-
  _M     nn/ nU" U5      nUb€  X5   n[        R                  " US5       H"  u  pxXƒU   ;  d  M  X7   R                  U5        M$     UR	                  XV45        X5    H  nX7   R                  U5        M     X5	 U" U5      nUb  M€  [        R                  " 5       n	[        UR                  5       5      n
U	R                  U
5        [        U
5      S-
  nU(       aƒ  UR                  5       u  pÆSnU	R                   H  nXn::  d  M
  Un  O   Uc  U
nUR                  U5        [        U5      n[        U[        U5      S-
  5      nU	R                  Xß5        U(       a  Mƒ  X¹4$ s  snf )a  Returns a treewidth decomposition using the passed heuristic.

Parameters
----------
G : NetworkX graph
heuristic : heuristic function

Returns
-------
Treewidth decomposition : (int, Graph) tuple
    2-tuple with treewidth and the corresponding decomposed tree.
Nr=   r+   )Úsetr!   ÚpermutationsÚaddr#   ÚremoveÚnxÚGraphÚ	frozensetÚkeysÚadd_noder$   ÚpopÚnodesÚmaxÚadd_edge)r   Ú	heuristicr'   r:   Ú
node_stackr.   rF   ÚuÚvÚdecompÚ	first_bagÚ	treewidthÚ	curr_nodeÚold_bagÚbagÚnew_bags                   r   r   r   ·   s“  € ñ  /0Ó0ªa¨”S˜™“Y ! ‘_Ò$©a€JÐ0ð €Jñ ˜*Ó%€IØ
Ñ
àÑ$ˆÜ×*Ò*¨4°Ö3‰DˆAØ 1™Õ%Ø‘×!Ñ! !Ö$ñ 4ð
 	×Ñ˜9Ð+Ô,ð Ô&ˆAØ‰M× Ñ  Ö+ñ 'ð Ð!Ù˜jÓ)ˆ	ð Ó
ô$ �XŠX‹Z€FÜ˜*Ÿ/™/Ó+Ó,€IØ
‡O�O�IÔä�I“ Ñ"€Iæ
à&ŸN™NÓ,Ñˆð ˆØ—<”<ˆCØ�{Ø�Ùñ  ð
 ‰?àˆGð 	�‰�ÔÜ˜D“/ˆô ˜	¤3 w£<°!Ñ#3Ó4ˆ	ð 	�‰˜Ô)÷/ ˆ*ð2 ÐÐùòq 1s   …F	)r4   r!   r>   Úheapqr   r   r   ÚnetworkxrM   Únetworkx.utilsr   Ú__all__Ú_dispatchabler   r   r   r   r   r6   r   r   Ú<module>rf      sÒ   ðñó> Û 
ß ,Ñ ,ã Ý .à!Ð#:Ð
;€ñ �ZÓ Ù�\Ó"Ø×Ò Ñ%ñMó &ó #ó !ðMñ* �ZÓ Ù�\Ó"Ø×Ò Ñ%ñ6ó &ó #ó !ð6÷&,ñ ,ò^-ð` ×Ò Ñ%Ø"7ó Gó &ñGr   