ó žÃÒYc @sHdZddlmZddlZddlZddlmZmZm Z ddl Tdj ddd d gƒZ d d d ddddddddg Z d„Zd„Zd„Zd„Zdd„Zd„Zedƒd„ƒZedƒd„ƒZedƒd„ƒZedƒd d!d"„ƒZedƒd d!d#„ƒZdS($sÞAlgorithms for directed acyclic graphs (DAGs). Note that most of these functions are only guaranteed to work for DAGs. In general, these functions do not check for acyclic-ness, so it is up to the user to check for that. iÿÿÿÿ(tgcdN(tconsumetarbitrary_elementtpairwise(t*s s%Aric Hagberg s Dan Schult (dschult@colgate.edu)s!Ben Edwards (bedwards@cs.unm.edu)s%Neil Girdhar (neil.girdhar@mcgill.ca)t descendantst ancestorsttopological_sortt lexicographical_topological_sorttis_directed_acyclic_grapht is_aperiodicttransitive_closurettransitive_reductiont antichainstdag_longest_pathtdag_longest_path_lengthcCsW|j|ƒs%tjd|ƒ‚ntj|d|ƒ}t|ƒt|gƒ}|S(sûReturn all nodes reachable from `source` in `G`. Parameters ---------- G : NetworkX DiGraph A directed acyclic graph (DAG) source : node in `G` Returns ------- set() The descendants of `source` in `G` s The node %s is not in the graph.tsource(thas_nodetnxt NetworkXErrortshortest_path_lengthtset(tGRtspltdes((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR&s cCsW|j|ƒs%tjd|ƒ‚ntj|d|ƒ}t|ƒt|gƒ}|S(s÷Return all nodes having a path to `source` in `G`. Parameters ---------- G : NetworkX DiGraph A directed acyclic graph (DAG) source : node in `G` Returns ------- set() The ancestors of source in G s The node %s is not in the graph.ttarget(RRRRR(RRRtanc((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR;s cCsD|jƒstSytt|ƒƒtSWntjk r?tSXdS(sÞReturn True if the graph `G` is a directed acyclic graph (DAG) or False if not. Parameters ---------- G : NetworkX graph Returns ------- bool True if `G` is a DAG, False otherwise N(t is_directedtFalseRRtTrueRtNetworkXUnfeasible(R((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR Ps ccs5|jƒstjdƒ‚nd„|jƒDƒ}g|jƒD]\}}|dkrA|^qA}x±|r|jƒ}||kr•tdƒ‚nxx|j|ƒD]g\}}y||cd8>> DG = nx.DiGraph([(1, 2), (2, 3)]) >>> list(reversed(list(nx.topological_sort(DG)))) [3, 2, 1] Notes ----- This algorithm is based on a description and proof in "Introduction to Algorithms: A Creative Approach" [1]_ . See also -------- is_directed_acyclic_graph, lexicographical_topological_sort References ---------- .. [1] Manber, U. (1989). "Introduction to Algorithms: A Creative Approach." Addison-Wesley. s2Topological sort not defined on undirected graphs.cSs+i|]!\}}|dkr||“qS(i((t.0tvtd((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pys Ÿs isGraph changed during iterationis8Graph contains a cycle or graph changed during iterationN( RRRt in_degreetpopt RuntimeErrortedgestKeyErrortappendR(Rt indegree_mapR R!t zero_indegreetnodet_tchild((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyRfs(5  1      c #s|jƒstjdƒ‚nˆd kr6d„‰n‡fd†}d„|jƒDƒ}g|jƒD]$\}}|dkrh||ƒ^qh}tj|ƒxÃ|rdtj|ƒ\}}||krØtdƒ‚nx|j |ƒD]p\}} y|| cd8îscsˆ|ƒ|fS(N((R*(tkey(sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyt create_tupleðscSs+i|]!\}}|dkr||“qS(i((RR R!((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pys ós isGraph changed during iterationis8Graph contains a cycle or graph changed during iterationN( RRRtNoneR"theapqtheapifytheappopR$R%R&theappushR( RR/R0R(R R!R)R+R*R,((R/sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR·s02    7     c Cs2|jƒstjdƒ‚nt|ƒ}id|6}|g}d}d}x‹|rÙg}xh|D]`}xW||D]K}||kr§t|||||dƒ}qs|j|ƒ||| 1 that divides the length of every cycle in the graph. Parameters ---------- G : NetworkX DiGraph A directed graph Returns ------- bool True if the graph is aperiodic False otherwise Raises ------ NetworkXError If `G` is not directed Notes ----- This uses the method outlined in [1]_, which runs in $O(m)$ time given $m$ edges in `G`. Note that a graph is not aperiodic if it is acyclic as every integer trivial divides length 0 cycles. References ---------- .. [1] Jarvis, J. P.; Shier, D. R. (1996), "Graph-theoretic analysis of finite Markov chains," in Shier, D. R.; Wallenius, K. T., Applied Mathematical Modeling: A Multidisciplinary Approach, CRC Press. s.is_aperiodic not defined for undirected graphsiiN( RRRRRR'tlenR tsubgraphR( Rtstlevelst this_leveltgtlt next_leveltuR ((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR s*"        "  t undirectedcsstjƒ}|j|jƒƒ|j|jƒƒx:|D]2‰|j‡fd†tj|dˆƒDƒƒq9W|S(sE Returns transitive closure of a directed graph The transitive closure of G = (V,E) is a graph G+ = (V,E+) such that for all v,w in V there is an edge (v,w) in E+ if and only if there is a non-null path from v to w in G. Parameters ---------- G : NetworkX DiGraph A directed graph Returns ------- NetworkX DiGraph The transitive closure of `G` Raises ------ NetworkXNotImplemented If `G` is not directed References ---------- .. [1] http://www.ics.uci.edu/~eppstein/PADS/PartialOrder.py c3s'|]}ˆ|krˆ|fVqdS(N((RR>(R (sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pys isR(RtDiGraphtadd_nodes_fromtnodestadd_edges_fromR%tdfs_preorder_nodes(RtTC((R sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR Is   0cs´t|ƒstjdƒ‚ntjƒ}|j|jƒƒxp|D]h‰t|ˆƒ}x2|ˆD]&}|d„tj||ƒDƒ8}qeW|j‡fd†|DƒƒqDW|S(sæ Returns transitive reduction of a directed graph The transitive reduction of G = (V,E) is a graph G- = (V,E-) such that for all v,w in V there is an edge (v,w) in E- if and only if (v,w) is in E and there is no path from v to w in G with length greater than 1. Parameters ---------- G : NetworkX DiGraph A directed acyclic graph (DAG) Returns ------- NetworkX DiGraph The transitive reduction of `G` Raises ------ NetworkXError If `G` is not a directed acyclic graph (DAG) transitive reduction is not uniquely defined and a :exc:`NetworkXError` exception is raised. References ---------- https://en.wikipedia.org/wiki/Transitive_reduction sFTransitive reduction only uniquely defined on directed acyclic graphs.cSsh|]\}}|’qS(((RR-ty((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pys “s c3s|]}ˆ|fVqdS(N((RR (R>(sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pys ”s( R RRR@RARBRt dfs_edgesRC(RtTRtu_edgesR ((R>sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR ns    $!c csÓtj|ƒ}gttttj|ƒƒƒƒfg}x“|rÎ|jƒ\}}|Vxo|rÊ|jƒ}||g}g|D],}|||kp¥|||ks‚|^q‚}|j||fƒq\Wq<WdS(s€Generates antichains from a directed acyclic graph (DAG). An antichain is a subset of a partially ordered set such that any two elements in the subset are incomparable. Parameters ---------- G : NetworkX DiGraph A directed acyclic graph (DAG) Returns ------- generator object Raises ------ NetworkXNotImplemented If `G` is not directed NetworkXUnfeasible If `G` contains a cycle Notes ----- This function was originally developed by Peter Jipsen and Franco Saliola for the SAGE project. It's included in NetworkX with permission from the authors. Original SAGE code at: https://github.com/sagemath/sage/blob/master/src/sage/combinat/posets/hasse_diagram.py References ---------- .. [1] Free Lattices, by R. Freese, J. Jezek and J. B. Nation, AMS, Vol 42, 1995, p. 226. N(RR tlisttreversedRR#R'( RREtantichains_stackst antichaintstackR-t new_antichainttt new_stack((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyR ˜s%*    9tweightic s i‰x®tj|ƒD]}g|j|jƒD]0\}}ˆ|d|j||ƒ|f^q0}|rt|dd„ƒn d|f}|ddkr£|n d|fˆ|tdatatustmaxutpath((RSsm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyRÍsG'*  cCsZtj|||ƒ}d}x8t|ƒD]*\}}||||j||ƒ7}q(W|S(sõReturns the longest path length in a DAG Parameters ---------- G : NetworkX DiGraph A directed acyclic graph (DAG) weight : string, optional Edge data key to use for weight default_weight : int, optional The weight of edges that do not have a weight attribute Returns ------- int Longest path length Raises ------ NetworkXNotImplemented If `G` is not directed See also -------- dag_longest_path i(RRRRV(RRRRYR]t path_lengthR>R ((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pyRþs "(t__doc__t fractionsRR2tnetworkxRtnetworkx.utilsRRRtnetworkx.utils.decoratorstjoint __author__t__all__RRR RR1RR tnot_implemented_forR R R RR(((sm/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/dag.pytsB          Q V <%*5 0