ó žÃÒYc@sodZddlmZddlmZddddgZd„Zd „Zd „Zd „Ze d d „Z dS(s;Functions for computing and verifying matchings in a graph.iÿÿÿÿ(t combinations(trepeatt is_matchingtis_maximal_matchingtmax_weight_matchingtmaximal_matchingcCs‡tƒ}tƒ}xn|jƒD]`\}}||kr||kr||kr|j||fƒ|j|ƒ|j|ƒqqW|S(sûFind 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. 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. (tsettedgestadd(tGtmatchingtnodestutv((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyRs  $ cCsttt|jƒƒƒS(sConverts 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``. (Rtmapt frozensettitems(R ((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pytmatching_dict_to_set8scCs;t|tƒrt|ƒ}ntd„t|dƒDƒƒS(sÈDecides whether the given set or dictionary represents a valid matching in ``G``. A *matching* in a graph is a set of edges in which no two distinct edges share a common endpoint. 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. css7|]-\}}tt|ƒt|ƒ@ƒdkVqdS(iN(tlenR(t.0te1te2((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pys gsi(t isinstancetdictRtallR(R R ((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyRKs csˆtˆtƒrtˆƒ‰ntˆˆƒs1tStttˆjƒƒƒ}tttˆƒƒ}||}t ‡‡fd†|DƒƒS(sóDecides whether the given set or dictionary represents a valid maximal matching in ``G``. A *maximal matching* in a graph is a matching in which adding any edge would cause the set to no longer be a valid matching. 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 maximal matching in the graph. c3s&|]}tˆˆ|hBƒ VqdS(N(R(Rte(R R (sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pys ”s( RRRRtFalseRRRRR(R R t all_edgest matched_edgestunmatched_edges((R R sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyRks tweightc s; ddd„ƒY‰dd‡fd†ƒY‰tˆƒ‰ ˆ sBiSd}t}xˆjdtƒD]m\}}}|jˆdƒ}||kr£||kr£|}n|oËtt|ƒƒjdƒddk}qaWi‰i‰i‰ttˆ ˆ ƒƒ‰ ttˆ t dƒƒƒ‰ ttˆ ˆ ƒƒ‰i‰ttˆ t |ƒƒƒ‰ i‰i‰g‰‡‡ ‡fd †‰‡‡‡‡‡ ‡‡‡‡f d †‰‡‡‡ ‡‡‡fd †} ‡‡‡‡‡‡ ‡ ‡‡‡‡‡f d†} ‡‡‡‡‡‡‡ ‡ ‡ ‡‡‡f d†‰ ‡‡‡‡ ‡fd†‰‡‡‡‡ ‡‡‡fd†} ‡‡‡ ‡ ‡ ‡‡‡fd†} x®ˆj ƒˆj ƒˆj ƒxˆD]} d| _ qžWˆj ƒgˆ(xFˆ D]>}|ˆkrɈjˆ |ƒdkrɈ|ddƒqÉqÉWd}xfxeˆr{| r{ˆj ƒ}ˆˆ |dksJt‚x+ˆj|ƒD]}||krrqZnˆ |}ˆ |}||kr˜qZn||fˆkréˆ||ƒ}|dkrétˆ||f<ˆ||fx!|jƒD] }|Vq,Wq |Vq WdS(N(R$Rtleaves(tselfttR (R#(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyR&ñs  (R R!R"t __slots__R&((R#(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyR#ßsitdatait'tinttlongcs,ˆ|ˆ|dˆ||jˆdƒS(Nii(tget(R tw(R tdualvarR(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pytslackNscs ˆ|}ˆj|ƒdkr4ˆj|ƒdks:t‚|ˆ|<ˆ|<|dk rs||fˆ|<ˆ|(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyt scanBlossomls.     "   cs.ˆ|}ˆ|}ˆ|}ˆƒ}|ˆ|R?R1(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyt addBlossom‘sˆ          #     ##     $   !    c s—x~|jD]s}dˆ|(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyR`ïst               cs¹|}xˆ||kr&ˆ|}q Wt|ˆƒrFˆ||ƒn|jj|ƒ}}|d@r‚|t|jƒ8}d}nd}xÉ|dkrS||7}|j|}|dkrÐ|j|\}}n|j|d\}}t|ˆƒrˆ||ƒn||7}|j|}t|ˆƒr<ˆ||ƒn|ˆ|<|ˆ|(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyRbOs8        csPxI||f||ffD]/\}}x ˆ|}ˆ|dksHt‚ˆ|dkrhˆ|ˆksŠˆ|dˆˆ|ksŠt‚t|ˆƒr©ˆ||ƒn|ˆ|<ˆ|dkrÇPnˆ|d}ˆ|}ˆ|dksõt‚ˆ|\}}ˆ||kst‚t|ˆƒr:ˆ||ƒn|ˆ|(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pytaugmentMatching|s&%  "  c sëˆr%tdtˆjƒƒ ƒ}nd}tˆjƒƒ|dksMt‚tˆƒdks}tˆjƒƒdks}t‚x ˆjdtƒD]Œ\}}}|jˆdƒ}||krÃqnˆ|ˆ|d|}|g}|g}x-ˆ|ddk r|j ˆ|dƒqòWx-ˆ|ddk rN|j ˆ|dƒq"W|j ƒ|j ƒx?t ||ƒD].\}} || krPn|dˆ|7}qsW|dks·t‚ˆj|ƒ|ksáˆj|ƒ|krˆ||krˆ||kst‚|dkst‚qqWx4ˆD],} | ˆks'ˆ| |dks't‚q'WxˆD]…} ˆ| dkr^t| jƒddks“t‚xM| jddd…D]2\}}ˆ||krÖˆ||ksªt‚qªWq^q^WdS(NiR*iiiÿÿÿÿ( tmaxtminRER3RRRWR.R2R5RBtzip( t vdualoffsetRMRNtdtwtRZt iblossomst jblossomstbiROR R6(R RSRTR0tgnodesR>tmaxcardinalityR(sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyt verifyOptimumsB"0"      *& * #iiÿÿÿÿg@ii(((sintslongN(RDRWRR.tstrttypetsplitRRhRR2tclearR%RXR3RCRgRER RfR5Rtkeys(R RpRt maxweightt allintegerRMRNRjRkRARUReRqR6R t augmentedR/RGRHRQR7t deltatypetdeltat deltaedget deltablossom((R#R RR_R8RbR9R:RSRTR0R`RoR;R<R=R>RpR?R1Rsr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyR—s8D " "   '%0^0`-!!$-       %       $    %   %              % N( R"t itertoolsRRt__all__RRRRRR(((sr/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/matching.pyts   !  ,