K idZddlmZmZddlZddlmZgdZededejdZ d Z ejd Z ejd Z ejd Zededejd ddZededejd ddZy)z;Functions for computing and verifying matchings in a graph.) combinationsrepeatN)not_implemented_for) is_matchingis_maximal_matchingis_perfect_matchingmax_weight_matchingmin_weight_matchingmaximal_matching multigraphdirectedct}t}|jD]9}|\}}||vs ||vs||k7s|j||j|;|S)aFind a maximal matching in the graph. A matching is a subset of edges in which no node occurs more than once. A maximal matching cannot add more edges and still be a matching. Parameters ---------- G : NetworkX graph Undirected graph Returns ------- matching : set A maximal matching of the graph. Examples -------- >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5)]) >>> sorted(nx.maximal_matching(G)) [(1, 2), (3, 5)] Notes ----- The algorithm greedily selects a maximal matching M of the graph G (i.e. no superset of M exists). It runs in $O(|E|)$ time. )setedgesaddupdateGmatchingnodesedgeuvs b/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/networkx/algorithms/matching.pyr r sd<uH EE 1 E>auna LL  LL   Oct}|jD]@}|\}}||f|vs||vr||k(rtjd||j |B|S)a?Converts matching dict format to matching set format Converts a dictionary representing a matching (as returned by :func:`max_weight_matching`) to a set representing a matching (as returned by :func:`maximal_matching`). In the definition of maximal matching adopted by NetworkX, self-loops are not allowed, so the provided dictionary is expected to never have any mapping from a key to itself. However, the dictionary is expected to have mirrored key/value pairs, for example, key ``u`` with value ``v`` and key ``v`` with value ``u``. z%Selfloops cannot appear in matchings )ritemsnx NetworkXErrorr)rrrrrs rmatching_dict_to_setr <sp EE 1 q6U?dem  6""%J4&#QR R $  Lrc`t|tr t|}t}|D]}t |dk7rt j d||\}}||vs||vrt j d|d||k(ry|j||sy||vs||vry|j|y)aReturn True if ``matching`` is a valid matching of ``G`` A *matching* in a graph is a set of edges in which no two distinct edges share a common endpoint. Each node is incident to at most one edge in the matching. The edges are said to be independent. Parameters ---------- G : NetworkX graph matching : dict or set A dictionary or set representing a matching. If a dictionary, it must have ``matching[u] == v`` and ``matching[v] == u`` for each edge ``(u, v)`` in the matching. If a set, it must have elements of the form ``(u, v)``, where ``(u, v)`` is an edge in the matching. Returns ------- bool Whether the given set or dictionary represents a valid matching in the graph. Raises ------ NetworkXError If the proposed matching has an edge to a node not in G. Or if the matching is not a collection of 2-tuple edges. Examples -------- >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5)]) >>> nx.is_maximal_matching(G, {1: 3, 2: 4}) # using dict to represent matching True >>> nx.is_matching(G, {(1, 3), (2, 4)}) # using set to represent matching True matching has non-2-tuple edge matching contains edge  with node not in GFT isinstancedictr rlenrrhas_edgerrs rrrUsR(D!'1 EE  t9>""%CD6#JK K1 A:!""%>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (3, 4), (3, 5)]) >>> nx.is_maximal_matching(G, {(1, 2), (3, 4)}) True r"r#r$r%FT) r'r(r rr)rrr*rrr)rrrrrrrs rrrs>(D!'1 EE EE t9>""%CD6#JK K1 A:!""%>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5), (4, 6)]) >>> my_match = {1: 2, 3: 5, 4: 6} >>> nx.is_perfect_matching(G, my_match) True r"r#r$r%Fr&rs rrrs@(D!'1 EE  t9>""%CD6#JK K1 A:!""%z&min_weight_matching..:s2wq!Q2sc36K|]\}}}|||z fywr5r6)r7rrr9 max_weights rr:z&min_weight_matching..<s" ;1aaJN # ;sr-)r)rr maxrGraphadd_weighted_edges_from)rr-G_edgesInvGrr<s @rr r sf 177|q"1T&IIgg61g-GS2'222J 88:D ;7 ;E  v 6 tD HHrc   !"#$%&'()*GddGfddt$$s tSd}d}jdD]P\}}}|jd}||k7r||kDr|}|xr(t t |j d dd v}Ri(i&i'tt$$%tt$td "tt$$ itt$t|#i!ig)#fd * %&'()f d  %&'(fd}  !"%&'()*f d}  !"%&'(f d}  "(fd %&'(fd} !"#$(fd} &j'jj!D] }d |_ jg)d d $D]&}|(vs&j%||dd (d} )rk|sh)j}&%|dk(sJj|D]0}||k(r %|}%|}||k(r||fvr*||}|dkrdx||f<||f<||fvr~&j| |d|^&j|dk(r%| ||}|ur | |||| ||d}n&j|&|dk(sJd&|<||f'|<&j|dk(r%j| *|ks||f|<&j| j| *|ks*||f|<3)r|sh|rnqd}d x}x}}sd}t#j}j!D]E}&j%|j|**|}|dk(s||ks=|}d}|}G"D]b}"| &j|dk(sj|0*|}|r|dzdk(sJ|dz}n|dz }|dk(s||ksZ|}d}|}d!D]4}"| &j|dk(s|dk(s !||ks,!|}d}|}6|dk(r)sJd}t#dt#j}$D]L}&j%|dk(r#|xx|zcc<(&j%|dk(s@#|xx|z cc<N!D]L}"| &j|dk(r!|xx|z cc<+&j|dk(s@!|xx|zcc<N|dk(rn~|dk(r2|\}}&%|dk(sJdx||f<||f<)j%|nE|dk(r2|\}}dx||f<||f<&%|dk(sJ)j%|n|dk(r | |d(D]}((||k(rJ|snRt!j'D]4}|!vr"|&j|dk(s#!|dk(s,| |d6|r| t)(S)aCompute a maximum-weighted matching of G. A matching is a subset of edges in which no node occurs more than once. The weight of a matching is the sum of the weights of its edges. A maximal matching cannot add more edges and still be a matching. The cardinality of a matching is the number of matched edges. Parameters ---------- G : NetworkX graph Undirected graph maxcardinality: bool, optional (default=False) If maxcardinality is True, compute the maximum-cardinality matching with maximum weight among all maximum-cardinality matchings. weight: string, optional (default='weight') Edge data key corresponding to the edge weight. If key not found, uses 1 as weight. Returns ------- matching : set A maximal matching of the graph. Examples -------- >>> G = nx.Graph() >>> edges = [(1, 2, 6), (1, 3, 2), (2, 3, 1), (2, 4, 7), (3, 5, 9), (4, 5, 3)] >>> G.add_weighted_edges_from(edges) >>> sorted(nx.max_weight_matching(G)) [(2, 4), (5, 3)] Notes ----- If G has edges with weight attributes the edge data are used as weight values else the weights are assumed to be 1. This function takes time O(number_of_nodes ** 3). If all edge weights are integers, the algorithm uses only integer computations. If floating point weights are used, the algorithm could return a slightly suboptimal matching due to numeric precision errors. This method is based on the "blossom" method for finding augmenting paths and the "primal-dual" method for finding a matching of maximum weight, both methods invented by Jack Edmonds [1]_. Bipartite graphs can also be matched using the functions present in :mod:`networkx.algorithms.bipartite.matching`. References ---------- .. [1] "Efficient Algorithms for Finding Maximum Matching in Graphs", Zvi Galil, ACM Computing Surveys, 1986. ceZdZdZy)#max_weight_matching..NoNodez-Dummy value which is different from any node.N)__name__ __module__ __qualname____doc__r6rrNoNoderEs;rrJc$eZdZdZgdZfdZy)$max_weight_matching..Blossomz7Representation of a non-trivial blossom or sub-blossom.)childsr mybestedgesc3Kg|j}|r@|j}t|r|j|jn||r?yywr5)rMpopr'extend)selfstacktBlossoms rleavesz+max_weight_matching..Blossom.leavessF"dkkNEIIKa)LL*G s AAAN)rFrGrHrI __slots__rV)rUsrrUrLsE6  rrUrTr2r1')intlongNcR||zd||jdzz S)Nr"r1)get)rr9rdualvarr-s rslackz"max_weight_matching..slacks3qzGAJ&QqT!W[[-C)CCCrch |} j| j|J|x |< |<| ||fx |< |<n dx |< |<dx|<|<|dk(r>t|r j|jy j |y|dk(r|} |d|yy)Nr1r")r]r'rQrVappend)r9rTrbbaserU assignLabelbestedge blossombase inblossomlabel labeledgematequeues rrdz(max_weight_matching..assignLabels aLyy|# ! (<<<a58 =+,a& 0IaL9Q<*. .IaL9Q<$(( hqk 6!W% QXXZ( Q !Vq>D T At , rc6g}}|ur|}|dzr|}np|dk(sJ|j|d|< | | vsJ}n2 |d |k(sJ |d}|}|dk(sJ |d}|ur||}}|ur|D]}d|< |S)Nr1rr")ra) rr9pathrcrbrJrfrgrhrirjs r scanBlossomz(max_weight_matching..scanBlossomsvo! AQx!|"1~8q= = KKNE!H|#"1~T111 |A${1~*>>>>aLOaLQx1}$}aLO!1/vo2 AE!H  rc |}|}|}}||<d|<||<gx|_}||fgx|_}||k7r`||<|j||j||dk(s|dk(r|d|k(sJ|d}|}||k7r`|j||j|j||k7rk||<|j||j|d|df|dk(s|dk(r|d|k(sJ|d}|}||k7rk|dk(sJd|<||<d|<|j D]#}|dk(rj|||<%i} |D]}t |r^|j |j } d|_nd|j Dcgc]"}j|D] }||k7s ||f$} }}n&j|Dcgc] }||k7s ||f} }| D]O} | \} } | |k(r| | } } | }||k7sj|dk(s4|| vs| | | |ksK| | |<Qd|<t| j|_d}d|<|j D]} | }||ks| }|}||<ycc}}wcc}w)Nr"r1r) rMrrareverserVr'rN neighborsr]listvalues)rcrr9bbbvbwrbroedgs bestedgetonblistkijbj mybestedgekslack mybestslackrUrrerf blossomdual blossomparentrgrhrirjrkr_s r addBlossomz'max_weight_matching..addBlossomBs t_ q\ q\ I A a b4a&!$Bh !M"  KKO KK " &9>b Q9R=#3tKO7L#L " a A1BBh B  Bh !M"  KKO KK2q)9R=+;< =9>b Q9R=#3tKO7L#L " a A1BBhRyA~~a } !  A AYq\"a' QIaL    B"g&>>-^^F%)BN )+ #$Q[[^89qTUvAF,-;;r?FabAg2q'FF 'AQ<1$aqAq\!G " *J.5A; SUAW3W%&JrN ' HRL7 8Z..01    %AAYF!Vk%9 $  % ! 7GsK9K K#Kc   f d}|||g}|r9|d}|D]}|j|||n|j|r8yy)Nc38 K|jD]B}d|<t| r*|r |dk(r|#|jD]}||< >||<D|sj|dk(r|d}|jj |}|dzr|t |jz}d}nd}|\}}|dk7r|dk(r|j |\}} n|j |dz \} }d|<d| <|d|dx || f< | |f<||z }|dk(r|j |\}}n|j |dz \}}dx ||f< ||f<||z }|dk7r|j|} dx|<| <||fx|<| <d| <||z }|j||k7r|j|} j| dk(r||z };t| r)| jD]}j|snn| }j|r4|dk(sJ|| k(sJd|<d| <|d|d||z }|j||k7rj|dj|dj|d|=|=|=yw)Nrr"r1T)rMr'rVr]indexr)rrP)rbendstagesr entrychildr~jstepr9pqrxrwrU allowedgerdrerfrrrgrhrirjs r_recursez.expandBlossom.._recursesXX %#' a a)KNa$7!"-A+,IaL-$%IaL %%))A,!"3 'y|A7 HHNN:.q5QXX&AEE |11fz wwqz1 wwq1u~1#E!H#E!H1a(<@@Iq!f% 1a&(9JAz wwqz1 wwq1u~1<@@Iq!f% 1a&(9JA%1f*XXa['((a59011v5 ! y}# U hhqkZ/!Byy})U  !"g.!#&A$yy| %&yy|$Qx1},}(|r111#'a7;d;r?34#Aq)A,q/:JA1hhqkZ/4 IIa  MM!T " LLD !a AAsEJBJ7A"JAJrrarP)rbrrrStoprrUrrdrerfrrrgrhrirjs r expandBlossomz*max_weight_matching..expandBlossomsb [ [ D!X&')C  Xa23  rc fd}|||g}|r5|d}|D]}|j||n|j|r4yy)Nc3K|} ||k7r |} ||k7rt|r||f|jj|x}}|dzr|t|jz}d}nd}|dk7r||z }|j|}|dk(r|j|\}}n|j|dz \}}t|r||f||z }|j|}t|r||f| |<| |<|dk7r|j|d|jd|z|_|j|d|jd|z|_ |jd |< ||k(sJyw)Nr1rr)r'rMrr)r) rbrrTr}r~rr9xrUrfrrjs rrz=max_weight_matching..augmentBlossom.._recursesA"a'!!$ "a'!W%!f HHNN1% %A1uS]"q&U HHQKA:771:DAq771q5>DAqa)a&LU HHQKa)a&LQQ#q&&xx|ahhrl2AHggabkAGGBQK/AG(!5KNq>Q& &&sE#CE#;A(E#rr) rbrrrSrargsrUrfrrjs raugmentBlossomz+max_weight_matching..augmentBlossomsW ) '`!Q )C  Xt_-  rcJ||f||ffD]\}} |} |dk(sJ | | vs |d |k(sJt|r ||| |< |U |d} |} |dk(sJ |\}} ||k(sJt|r ||| |<y)Nr1rr")r')rr9rr~bsrTbtrUrrfrgrhrirjs raugmentMatchingz,max_weight_matching..augmentMatchingVsVaV$ DAqq\RyA~%~!" -+b/2MbM!$[_(==b'*"2q)QR=(bM!$q\RyA~%~ }1"2!+++b'*"2q)Q3  rc,r%tdtj }nd}tj|zdk\sJt dk(st jdk\sJ j dD]\}}}|j d}||k(r ||zd|zz }|g}|g}|d |j |d|d |d |j |d|d |j|jt||D]\}} || k7rn |d |zz }|dk\sJj ||k(sj ||k(s||k(r||k(sJ|dk(rJD]} | vr| |zdk(rJ D]T} | dkDs t| jdzdk(sJ| jdddD]\}}||k(r ||k(rJVy)NrTrXr1r"r) r>minrur)rr]rarrzip) vdualoffsetr}r~dwtr iblossoms jblossomsbirrrbrrrr^gnodesrjr0r-s r verifyOptimumz*max_weight_matching..verifyOptimumws a#gnn&6"7!78KK7>>#${2a777;1$K,>,>,@(AQ(FFFwwDw) GAq!vq!BAv WQZ'!b&0AII " .:  y}!=> " .: " .:  y}!=> " .:        i3 )B8QR(( )6M6xx{a488A;!#3Aw!|Q1 44Av v) , @AI'!*{":a"? ?? @ 9A1~!177|a'1,,,GGADqDM9DAq7arakeysr )+rr0r- maxweight allintegerr}r~rrrprrrrrbr augmentedr9rwrxrrc deltatypedelta deltaedge deltablossomrUrJrrdrrerfrrr^rrgrhrirjrkr_s+``` @@@@@@@@@@@@@@@@@rr r AsX<<8!WF u IJ777%U1a UU61  6b9nITSb]%8%8%=a%@O%S U D EIS()I VVD\23Ms66*+KH3vvi012G K I ED --2  J\!\!~ooh=BB)9)9Z    !A AM ! a (A 599Yq\#:#BAq$' (   IIKYq\*a///Q41AAv "1B"1BRx 1vY.!&q!!Q;DHHIq!f- 1a&0A1v* 99R=0(1a0"YYr]a/$/q!#4D#61!+4A 6!01 5,- %"YYq\1 $)9>1>'(E!H,-q6IaL2!+$<<+3vxPR|@T7T,-q6HRL1-$<<?2fuhqk?R6R+,a&HQKi41  x I/3 3E 3I " GNN,-WWY 099Yq\*2x||A7Rx{+A B!e) !$% $,QK  0# 0!!$, ! ) Q3"HQK0F! & q000"aK"SL B!e) !$% $,QK  0$! %!!$, ! )"bKNU,B'NE !I#$L %B&%~ As7>>#345 (99Yq\*a/AJ%'JYYy|,1AJ%'J  (! 0 #+yy|q(#A%/1*#A%/ 0A~a"AYq\*a///8<< 1a&!Iq!f$5 Qa"A8<< 1a&!Iq!f$5Yq\*a/// QalE2QZ &AQ=A% %% & k&&() 'A #Q'EIIaLA,=+a.TUBUa&  'c p  %%rr=)Fr-)rI itertoolsrrnetworkxrnetworkx.utilsr__all__ _dispatchabler r rrrr r r6rrrsA*. \"Z $!#$N299x::z0 0 f\"Z X&7I'!#7It\"Z X&{ &'!#{ &r