K i'LdZddlmZddlmZmZddlmZddlZ ddl m Z m Z gdZ e de d e jdd Ze jdd Zd Zd ZGddeZdZdZe jddZdZe de jddZe jd dZe de d e jdddZdZdZe de d e jdZy)!zL ======================== Cycle finding algorithms ======================== ) defaultdict) combinationsproduct)infN)not_implemented_forpairwise) cycle_basis simple_cyclesrecursive_simple_cycles find_cycleminimum_cycle_basischordless_cyclesgirthdirected multigraphcRtj|}g}|r ||jd}|g}||i}|ti}|r|j }||}||D]} | |vr||| <|j | |h|| <$| |k(r|j |g<| |vsA|| } | |g} ||} | | vr| j | || } | | vr| j | |j | || j ||r|D]} |j | dd}|r |S)avReturns a list of cycles which form a basis for cycles of G. A basis for cycles of a network is a minimal collection of cycles such that any cycle in the network can be written as a sum of cycles in the basis. Here summation of cycles is defined as "exclusive or" of the edges. Cycle bases are useful, e.g. when deriving equations for electric circuits using Kirchhoff's Laws. Parameters ---------- G : NetworkX Graph root : node, optional Specify starting node for basis. Returns ------- A list of cycle lists. Each cycle list is a list of nodes which forms a cycle (loop) in G. Examples -------- >>> G = nx.Graph() >>> nx.add_cycle(G, [0, 1, 2, 3]) >>> nx.add_cycle(G, [0, 3, 4, 5]) >>> nx.cycle_basis(G, 0) [[3, 4, 5, 0], [1, 2, 3, 0]] Notes ----- This is adapted from algorithm CACM 491 [1]_. References ---------- .. [1] Paton, K. An algorithm for finding a fundamental set of cycles of a graph. Comm. ACM 12, 9 (Sept 1969), 514-518. See Also -------- simple_cycles minimum_cycle_basis Nr)dictfromkeyspopitemsetpopappendadd)Grootgnodescyclesstackpredusedzzusednbrpncyclepnodes `/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/networkx/algorithms/cycles.pyr r sW\]]1 F F  <>>#A&Dd|ce} AGEt %d? !DILL%!"DIAXMM1#&%cB !HEQA2+ Q G2+LLOMM%(IMM!$! %( #D JJtT " #9 : Mc#K||dk(ry|dkr tdj}djjDEd{||dk(ryj rk|sit jjD]B\}fd|jD}fd|DEd{j D|r5tjdjjDn4tjd jjD|h|d k(rc|r`t jjD]9\}fd j|DEd{j ;y|rt|Ed{yt|Ed{y777J7"7w) aFind simple cycles (elementary circuits) of a graph. A "simple cycle", or "elementary circuit", is a closed path where no node appears twice. In a directed graph, two simple cycles are distinct if they are not cyclic permutations of each other. In an undirected graph, two simple cycles are distinct if they are not cyclic permutations of each other nor of the other's reversal. Optionally, the cycles are bounded in length. In the unbounded case, we use a nonrecursive, iterator/generator version of Johnson's algorithm [1]_. In the bounded case, we use a version of the algorithm of Gupta and Suzumura [2]_. There may be better algorithms for some cases [3]_ [4]_ [5]_. The algorithms of Johnson, and Gupta and Suzumura, are enhanced by some well-known preprocessing techniques. When `G` is directed, we restrict our attention to strongly connected components of `G`, generate all simple cycles containing a certain node, remove that node, and further decompose the remainder into strongly connected components. When `G` is undirected, we restrict our attention to biconnected components, generate all simple cycles containing a particular edge, remove that edge, and further decompose the remainder into biconnected components. Note that multigraphs are supported by this function -- and in undirected multigraphs, a pair of parallel edges is considered a cycle of length 2. Likewise, self-loops are considered to be cycles of length 1. We define cycles as sequences of nodes; so the presence of loops and parallel edges does not change the number of simple cycles in a graph. Parameters ---------- G : NetworkX Graph A networkx graph. Undirected, directed, and multigraphs are all supported. length_bound : int or None, optional (default=None) If `length_bound` is an int, generate all simple cycles of `G` with length at most `length_bound`. Otherwise, generate all simple cycles of `G`. Yields ------ list of nodes Each cycle is represented by a list of nodes along the cycle. Examples -------- >>> G = nx.DiGraph([(0, 0), (0, 1), (0, 2), (1, 2), (2, 0), (2, 1), (2, 2)]) >>> sorted(nx.simple_cycles(G)) [[0], [0, 1, 2], [0, 2], [1, 2], [2]] To filter the cycles so that they don't include certain nodes or edges, copy your graph and eliminate those nodes or edges before calling. For example, to exclude self-loops from the above example: >>> H = G.copy() >>> H.remove_edges_from(nx.selfloop_edges(G)) >>> sorted(nx.simple_cycles(H)) [[0, 1, 2], [0, 2], [1, 2]] Notes ----- When `length_bound` is None, the time complexity is $O((n+e)(c+1))$ for $n$ nodes, $e$ edges and $c$ simple circuits. Otherwise, when ``length_bound > 1``, the time complexity is $O((c+n)(k-1)d^k)$ where $d$ is the average degree of the nodes of `G` and $k$ = `length_bound`. Raises ------ ValueError when ``length_bound < 0``. References ---------- .. [1] Finding all the elementary circuits of a directed graph. D. B. Johnson, SIAM Journal on Computing 4, no. 1, 77-84, 1975. https://doi.org/10.1137/0204007 .. [2] Finding All Bounded-Length Simple Cycles in a Directed Graph A. Gupta and T. Suzumura https://arxiv.org/abs/2105.10094 .. [3] Enumerating the cycles of a digraph: a new preprocessing strategy. G. Loizou and P. Thanish, Information Sciences, v. 27, 163-182, 1982. .. [4] A search strategy for the elementary cycles of a directed graph. J.L. Szwarcfiter and P.E. Lauer, BIT NUMERICAL MATHEMATICS, v. 16, no. 2, 192-204, 1976. .. [5] Optimal Listing of Cycles and st-Paths in Undirected Graphs R. Ferreira and R. Grossi and A. Marino and N. Pisanti and R. Rizzi and G. Sacomoto https://arxiv.org/abs/1205.2766 See Also -------- cycle_basis chordless_cycles Nr!length bound must be non-negativec32K|]\}}||vs |gywN.0vGvs r( z simple_cycles..s:2!r': c3HK|]\}}|vs |t|fywr-lenr0r1Guvvisiteds r(r3z simple_cycles..s#Sfaa7lQCMS ""c38K|]\}}|dkDs |gywr5Nr.)r0r1mus r(r3z simple_cycles..sA41a1q5AAs  c3DK|]\}}|D]}||k7s ||fywr-r.r0r@Gur1s r(r3z simple_cycles..s*O%!R"OQQ1vOvO  c3DK|]\}}|D]}||k7s ||fywr-r.rBs r(r3z simple_cycles..s*M2M1a1faVMVMrDc3LK|]}j|s|gywr-has_edge)r0r1rr@s r(r3z simple_cycles..s'  1a@PQFs$ $) ValueError is_directedadjitems is_multigraphrrnxDiGraphGraph intersection_directed_cycle_search_undirected_cycle_search)r length_boundrrC multiplicityr@r;s` @@r(r r isz 1   A @A A}}H::::LA$5%UU[[] EArS SLA<A A A KKN   JJO155;;=O O HHMM MLA$5 eG 2$+$8$8$< A   )!\:::+A|<<K|]}t|dk\s|ywrFNr7r0cs r(r3z)_directed_cycle_search..<A! !<) rOstrongly_connected_componentsr8rsubgraphnextiter_johnson_cycle_search_bounded_cycle_search remove_nodeextend)rrUsccr[ componentsGcr1s r(rSrSsF * *C V3s1v{!3J3  NN  ZZ] aM  ,R!5 5 5,R!lC C C a u) path P remaining in G[C] \ (u, v), yield P. 4. Add the biconnected components of G[C] \ (u, v) to BCC. If the parameter length_bound is not None, then step 3 will be limited to simple paths of length at most length_bound. Parameters ---------- G : NetworkX Graph An undirected graph length_bound : int or None If length_bound is an int, generate all simple cycles of G with length at most length_bound. Otherwise, generate all simple cycles of G. Yields ------ list of nodes Each cycle is represented by a list of nodes along the cycle. Nc3>K|]}t|dk\s|yw)rjNr7rZs r(r3z+_undirected_cycle_search..Qr\r]) rObiconnected_componentsr8rr_listr`raedges remove_edgerbrcre)rrUbccr[rgrhuvs r(rTrT"sF # #C V3s1v{!3J3  NN  ZZ] $tBHH~& ' r  ,R4 4 4,R\B B Br.)r0rbls r(r3z(_bounded_cycle_search..s*V1BFA;*Vs)rsrrrrrar8getrrminre differencer)rrrUlockrrrblenrrr1 relax_stackr@rs @r(rcrcs2 1A ==q !DCA GE !DH+  E >D Ry AEz1g RTTXXa66 A L)d)Q T!A$Z(  IIK ABtBx,RL "Awi !'OO-EBxx<0<"3Dq3HH"."3a"7Q#***V!PT@U*VV " 1 AaDHHQK 5 sBF9 DF9!F97F9c #4K||dk(ry|dkr tdj}j}|r*djj DEd{n)djj DEd{||dk(ryt t jfdD}|r(t j|jd }nt j|d}|r|sj}t jj D]\}}|vr |r?d |j D}|D]"\} } | dkDs j|| f| |ff$Lfd |j D}|D](\} } | d k(r|| g| dkDsj|| *j||ryjj D]\\}} | D cgc]} j| |s|| g} } | Ed{j| jd | D^||d k(ry|rt j } fd}nt j"} fd}| Dcgc]}t%|d kDs|}}|r|j'}t)t+|} j-|}dx}}||| D]M\}}|r| |)t/|}||nt/|j-|}t1||||Ed{O|j3d| j-|| hz D|ryy77cc} w7_cc}w7Ow)a Find simple chordless cycles of a graph. A `simple cycle` is a closed path where no node appears twice. In a simple cycle, a `chord` is an additional edge between two nodes in the cycle. A `chordless cycle` is a simple cycle without chords. Said differently, a chordless cycle is a cycle C in a graph G where the number of edges in the induced graph G[C] is equal to the length of `C`. Note that some care must be taken in the case that G is not a simple graph nor a simple digraph. Some authors limit the definition of chordless cycles to have a prescribed minimum length; we do not. 1. We interpret self-loops to be chordless cycles, except in multigraphs with multiple loops in parallel. Likewise, in a chordless cycle of length greater than 1, there can be no nodes with self-loops. 2. We interpret directed two-cycles to be chordless cycles, except in multi-digraphs when any edge in a two-cycle has a parallel copy. 3. We interpret parallel pairs of undirected edges as two-cycles, except when a third (or more) parallel edge exists between the two nodes. 4. Generalizing the above, edges with parallel clones may not occur in chordless cycles. In a directed graph, two chordless cycles are distinct if they are not cyclic permutations of each other. In an undirected graph, two chordless cycles are distinct if they are not cyclic permutations of each other nor of the other's reversal. Optionally, the cycles are bounded in length. We use an algorithm strongly inspired by that of Dias et al [1]_. It has been modified in the following ways: 1. Recursion is avoided, per Python's limitations 2. The labeling function is not necessary, because the starting paths are chosen (and deleted from the host graph) to prevent multiple occurrences of the same path 3. The search is optionally bounded at a specified length 4. Support for directed graphs is provided by extending cycles along forward edges, and blocking nodes along forward and reverse edges 5. Support for multigraphs is provided by omitting digons from the set of forward edges Parameters ---------- G : NetworkX DiGraph A directed graph length_bound : int or None, optional (default=None) If length_bound is an int, generate all simple cycles of G with length at most length_bound. Otherwise, generate all simple cycles of G. Yields ------ list of nodes Each cycle is represented by a list of nodes along the cycle. Examples -------- >>> sorted(list(nx.chordless_cycles(nx.complete_graph(4)))) [[1, 0, 2], [1, 0, 3], [2, 0, 3], [2, 1, 3]] Notes ----- When length_bound is None, and the graph is simple, the time complexity is $O((n+e)(c+1))$ for $n$ nodes, $e$ edges and $c$ chordless cycles. Raises ------ ValueError when length_bound < 0. References ---------- .. [1] Efficient enumeration of chordless cycles E. Dias and D. Castonguay and H. Longo and W.A.R. Jradi https://arxiv.org/abs/1309.1051 See Also -------- simple_cycles Nrr+c3fK|])\}}t|j|ddk(s%|g+yw)r.r5N)r8rr/s r(r3z#chordless_cycles..Bs,NEArc"&&B-6HA6MQCNs&11c32K|]\}}||vs |gywr-r.r/s r(r3z#chordless_cycles..Ds>EAra2gQC>r4r5c3bK|]&}|vsj|D] }|vs||f(ywr-)_adj)r0r@r1rloopss r(r3z#chordless_cycles..Ms6 V!5.!&&) VQqPU~aV VV Vs // /F)as_viewc3<K|]\}}|t|fywr-r7)r0r1r:s r(r3z#chordless_cycles..nsG&!SCH Gsc3HK|]\}}|vs |t|fywr-r7r9s r(r3z#chordless_cycles..ss#W&!S!w,CH Wr<rFc3,K|] }|dddywNr~r.)r0es r(r3z#chordless_cycles..s8A$B$8sc3Kt|j||j|D]1\}}j||r|||gj||f3ywr-)rrsuccrI)Cr1r@rFrs r(stemszchordless_cycles..stemss[q 166!95 61zz!Q'a)QZZ1%555 6s ?AAc3VKfdt|dDEd{y7w)Nc3RK|]\}}||gj||f ywr-rH)r0r@rrr1s r(r3z2chordless_cycles..stems..s+X$!Q!QAJJq!$45Xs$'rF)r)rr1rs `r(rzchordless_cycles..stemss"X,qQRtUVBWX X Xs )')c3>K|]}t|dkDs|ywrYr7rZs r(r3z#chordless_cycles..sQc!fqj!Qr])rJrKrNrLrMrrOnodes_with_selfloopsrP to_undirectedrQcopyremove_edges_fromrorrIr^rlr8rr`rar_rs_chordless_cycle_searchre)rrUrrrnrr@rCrVr1r?Fudigonsseparaterr[rgFcFccBccS is_trianglerrr;s` @@@r(rrslv 1   A @A A}}H"JNQUU[[]NNN>QUU[[]>>>LA$5 ''* +E VQ VE JJu  OOEO * HHUO &AeGUU[[] EArEzGBHHJG (>DAq1u++aVaV,<=> XBHHJW (,DAqAv !f 1u a+ ,  A ,UU[[] 9EAr&(=AJJq!,|> >8NsAN%N&)NNC N1A N=A N N "N (N/N0A/NN3N7BNN9NNN NNc#$Ktt}|d}d||d<|ddD]}||D]}||xxdz cc<t||dg}|r|d} | D]x}||dk(s |t||ks||} || vr ||gz/||} || vr9| D]}||xxdz cc<|j ||j t| n6|j ||j D]}||xxdzcc<|ryyw)aThe main loop for chordless cycle enumeration. This algorithm is strongly inspired by that of Dias et al [1]_. It has been modified in the following ways: 1. Recursion is avoided, per Python's limitations 2. The labeling function is not necessary, because the starting paths are chosen (and deleted from the host graph) to prevent multiple occurrences of the same path 3. The search is optionally bounded at a specified length 4. Support for directed graphs is provided by extending cycles along forward edges, and blocking nodes along forward and reverse edges 5. Support for multigraphs is provided by omitting digons from the set of forward edges Parameters ---------- F : _NeighborhoodCache A graph of forward edges to follow in constructing cycles B : _NeighborhoodCache A graph of blocking edges to prevent the production of chordless cycles path : list A cycle prefix. All cycles generated will begin with this prefix. length_bound : int A length bound. All cycles generated will have length at most length_bound. Yields ------ list of nodes Each cycle is represented by a list of nodes along the cycle. References ---------- .. [1] Efficient enumeration of chordless cycles E. Dias and D. Castonguay and H. Longo and W.A.R. Jradi https://arxiv.org/abs/1309.1051 rr5NrFr~)rintrar8rr) rrrrUrtargetrr1rrFwBws r(rrsK^#G !WFGDG !"X1 A AJ!OJ !DG*  E Ry AqzQL$8CI Find simple cycles (elementary circuits) of a directed graph. A `simple cycle`, or `elementary circuit`, is a closed path where no node appears twice. Two elementary circuits are distinct if they are not cyclic permutations of each other. This version uses a recursive algorithm to build a list of cycles. You should probably use the iterator version called simple_cycles(). Warning: This recursive version uses lots of RAM! It appears in NetworkX for pedagogical value. Parameters ---------- G : NetworkX DiGraph A directed graph Returns ------- A list of cycles, where each cycle is represented by a list of nodes along the cycle. Example: >>> edges = [(0, 0), (0, 1), (0, 2), (1, 2), (2, 0), (2, 1), (2, 2)] >>> G = nx.DiGraph(edges) >>> nx.recursive_simple_cycles(G) [[0], [2], [0, 1, 2], [0, 2], [1, 2]] Notes ----- The implementation follows pp. 79-80 in [1]_. The time complexity is $O((n+e)(c+1))$ for $n$ nodes, $e$ edges and $c$ elementary circuits. References ---------- .. [1] Finding all the elementary circuits of a directed graph. D. B. Johnson, SIAM Journal on Computing 4, no. 1, 77-84, 1975. https://doi.org/10.1137/0204007 See Also -------- simple_cycles, cycle_basis cf|r+d|<|r |j|ryyy)z6Recursively unblock and remove nodes from B[thisnode].FN)r)thisnoder_unblockrs r(rz)recursive_simple_cycles.._unblock3s= 8  %GH H+8*+H+ r)c,d} j|d|<||D]1}||k(r j ddd}|r%|||s0d}3|r |n&||D]}||vs |j|  j|S)NFT)rr) r startnode componentrnextnoderrrcircuitrresults r(rz(recursive_simple_cycles..circuit:s H !(+ "H9$ d1g&X&8Y :!F  "  X %h/ 11X;.hK&&x0 1   r)c3:K|]}|k\s|ywr-r.)r0r'orderingss r(r3z*recursive_simple_cycles..`s RtHTNhqk4QdRsc,tfd|DS)Nc3(K|] }| ywr-r.)r0nrs r(r3z...ds4MQXa[4Ms)r)nsrs r(z)recursive_simple_cycles..ds4M"4M1Mr)keyr5FN)rboolrmrIrrorzipranger8r_rOr^r __getitem__)rr1r_ strongcompmincomprrr'dummyrrrrrrrrs @@@@@@@@r(r r s3d,( D$GDA F   ::a  MM1#  MM!Q  C5Q=)*H =::RqRR55h? j&MNJJw' y>A I8+?+?@I!  % $  Iy)>> G = nx.DiGraph([(0, 1), (0, 2), (1, 2)]) >>> nx.find_cycle(G, orientation="original") Traceback (most recent call last): ... networkx.exception.NetworkXNoCycle: No cycle found. >>> list(nx.find_cycle(G, orientation="ignore")) [(0, 1, 'forward'), (1, 2, 'forward'), (0, 2, 'reverse')] See Also -------- simple_cycles )Noriginalc |ddS)NrFr.edges r(tailheadzfind_cycle..tailheads 8Or)reversec|d|dfS)Nr5rr.rs r(rzfind_cycle..tailheads7DG# #r)ignorec0|ddk(r |d|dfS|ddS)Nr~rr5rrFr.rs r(rzfind_cycle..tailheads,Bx9$AwQ''8Or)Nr5r~rzNo cycle found.)rKr nbunch_iterrOedge_dfsrr IndexErrorrrerrr8 exceptionNetworkXNoCycle enumerate)rsource orientationrexploredr% final_node start_nodernseen active_nodes previous_headrtailhead popped_edge popped_head last_headis r(r r ps H ==?k-??   ! $    uH EJmmF+;>  ! |"|  KK:{;& %D!$JD$x(T]-B9&+iik '/{&;A&> $++K8$,U2Y$7$: 9,! LL |# U#!   & $ M& %P   OOD !o;>t5zQll**+<== U#4d^ d :   9S& "(,v sFF"!F"weight) edge_attrscXtfdtjDgS)aPReturns a minimum weight cycle basis for G Minimum weight means a cycle basis for which the total weight (length for unweighted graphs) of all the cycles is minimum. Parameters ---------- G : NetworkX Graph weight: string name of the edge attribute to use for edge weights Returns ------- A list of cycle lists. Each cycle list is a list of nodes which forms a cycle (loop) in G. Note that the nodes are not necessarily returned in a order by which they appear in the cycle Examples -------- >>> G = nx.Graph() >>> nx.add_cycle(G, [0, 1, 2, 3]) >>> nx.add_cycle(G, [0, 3, 4, 5]) >>> nx.minimum_cycle_basis(G) [[5, 4, 3, 0], [3, 2, 1, 0]] References: [1] Kavitha, Telikepalli, et al. "An O(m^2n) Algorithm for Minimum Cycle Basis of Graphs." http://link.springer.com/article/10.1007/s00453-007-9064-z [2] de Pina, J. 1995. Applications of shortest path methods. Ph.D. thesis, University of Amsterdam, Netherlands See Also -------- simple_cycles, cycle_basis c3TK|]}tj|!ywr-)_min_cycle_basisr_)r0r[rrs r(r3z&minimum_cycle_basis..:s!UQ !**Q- 0Us%()sumrOconnected_components)rrs``r(r r s*R U":Q:QRS:TU  r)c ^ g}ttj|dd}|j|z |Dchc] \}}||f c}}z }|Dcgc]}|h}}|r|j } t || |} |j | Dcgc]\}}| c}}|D cgc]\ t fd| DdzrA D chc]} | | vs| ddd| vs| c} | D chc]} | vs| ddd vs| c} zn ^}} } |r|Scc}}wcc}wcc}}wcc} wcc} wcc} } w)NF)rdatac3>K|]}|vxs |dddvywrr.)r0rorths r(r3z#_min_cycle_basis..Vs)GaAI04R4D0GsrFr~)rmrOminimum_spanning_edgesrnr _min_cyclerr) rrcb tree_edgesr@r1chordsrset_orthbase cycle_edgesrrs ` r(rr?sO Bb//$UKLJ WWz ! $C1aV$C CF$**4*H* ||~ D&1  -A1-.!  G;GG!K!IqATMQttWD5HI"Katmq2wd7J1KL     " I+%D+ . JK sMD D D % D) D  D D D)$ D$. D$9D$= D) D)c tj}|j|dD]M\}}}||f|vs||f|vr|j||dff|df|fg|1|j||f|df|dffg|Otj}|Dcic]}|||||dfd} }t | | j } | df} tj|| | d} | Dcgc] }||vr|n|d} }tt| }t}|D]K}||vr|j||ddd |vr|j|ddd ;|j|Mg}|D]b}||vr#|j||j|*|ddd |vs5|j|ddd |j|ddd d|Scc}wcc}w) z Computes the minimum weight cycle in G, orthogonal to the vector orth as per [p. 338, 1] Use (u, 1) to indicate the lifted copy of u (denoted u' in paper). r5)rdefault) Gi_weightr )rrrrrNr~)rOrQrnadd_edges_fromshortest_path_lengthrr shortest_pathrmrrrrr)rrrGir@r1wtsplrliftrend min_path_imin_pathedgelistedgesetr min_edgelists r(rr]s BGGG3H1b q6T>aVt^   Aq6{aVQK8B  G   1vAA'78B  G H ! !CMN OAs2aA{C C OD O $(( #E !*C!!"U3{SJ0::!Q!V1%:H:HX&'HeG  < NN1  ttW  NN1TrT7 # KKN L $ <    " NN1  ttW    $B$ ( NN1TrT7 # $ ? P;s G Gctx}}tjjjj }tjjjj }|D]Z}|di}tj||D];\}}} ||} | |kDr0| |ur | dz||< | |u} | | zdz| z } | |ks5| }| | z }=\|S)aReturns the girth of the graph. The girth of a graph is the length of its shortest cycle, or infinity if the graph is acyclic. The algorithm follows the description given on the Wikipedia page [1]_, and runs in time O(mn) on a graph with m edges and n nodes. Parameters ---------- G : NetworkX Graph Returns ------- int or math.inf Examples -------- All examples below (except P_5) can easily be checked using Wikipedia, which has a page for each of these famous graphs. >>> nx.girth(nx.chvatal_graph()) 4 >>> nx.girth(nx.tutte_graph()) 4 >>> nx.girth(nx.petersen_graph()) 5 >>> nx.girth(nx.heawood_graph()) 6 >>> nx.girth(nx.pappus_graph()) 6 >>> nx.girth(nx.path_graph(5)) inf References ---------- .. [1] `Wikipedia: Girth `_ rr5rF)rrO algorithms traversalbreadth_first_search TREE_EDGE LEVEL_EDGEbfs_labeled_edges) rr depth_limit tree_edge level_edgerdepthr@r1labeldudeltalengths r(rrsTEK ''<<FFI((==HHJ -A//15 -KAq%qBK !6a+b1u,E>"E"$u*K - -& Lr)r-)NN)r| collectionsr itertoolsrrmathrnetworkxrOnetworkx.utilsrr__all__ _dispatchabler r rSrTrrsrbrcrrr r r rrrr.r)r(r-s $+8 Z \"J#!JZC=C=L/=d/=d   9 x: zSRSRlJ Z\"%j&#jZ\\~Z \"X&)'#!)X<2jZ \"=#!=r)