ó žÃÒYc@sÎdZddlZddlZddlZdjdgƒZddddd gZd ejfd „ƒYZ d „Z ej d „Z d „Z d„Zd„Zd„Zd„Zdej d„Zd„ZdS(sÇ Algorithms for chordal graphs. A graph is chordal if every cycle of length at least 4 has a chord (an edge joining two nodes not adjacent in the cycle). https://en.wikipedia.org/wiki/Chordal_graph iÿÿÿÿNs s'Jesus Cerquides t is_chordaltfind_induced_nodestchordal_graph_cliquestchordal_graph_treewidthtNetworkXTreewidthBoundExceededcBseZdZRS(sVException raised when a treewidth bound has been provided and it has been exceeded(t__name__t __module__t__doc__(((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyRscCs`|jƒrtjdƒ‚n|jƒr<tjdƒ‚ntt|ƒƒdkrXtStSdS(sçChecks whether G is a chordal graph. A graph is chordal if every cycle of length at least 4 has a chord (an edge joining two nodes not adjacent in the cycle). Parameters ---------- G : graph A NetworkX graph. Returns ------- chordal : bool True if G is a chordal graph and False otherwise. Raises ------ NetworkXError The algorithm does not support DiGraph, MultiGraph and MultiDiGraph. If the input graph is an instance of one of these classes, a :exc:`NetworkXError` is raised. Examples -------- >>> import networkx as nx >>> e=[(1,2),(1,3),(2,3),(2,4),(3,4),(3,5),(3,6),(4,5),(4,6),(5,6)] >>> G=nx.Graph(e) >>> nx.is_chordal(G) True Notes ----- The routine tries to go through every node following maximum cardinality search. It returns False when it finds that the separator for any node is not a clique. Based on the algorithms in [1]_. References ---------- .. [1] R. E. Tarjan and M. Yannakakis, Simple linear-time algorithms to test chordality of graphs, test acyclicity of hypergraphs, and selectively reduce acyclic hypergraphs, SIAM J. Comput., 13 (1984), pp. 566–579. sDirected graphs not supporteds(Multiply connected graphs not supported.iN(t is_directedtnxt NetworkXErrort is_multigraphtlent_find_chordality_breakertTruetFalse(tG((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyRs,  c Cs#t|ƒstjdƒ‚ntj|ƒ}|j||ƒtƒ}t|||ƒ}xh|rÂ|\}}} |j|ƒx-|D]%} | |kr„|j|| ƒq„q„Wt|||ƒ}q[W|r|j|ƒxF||D]7}t |t||ƒ@ƒdkrá|j|ƒPqáqáWn|S(s§Returns the set of induced nodes in the path from s to t. Parameters ---------- G : graph A chordal NetworkX graph s : node Source node to look for induced nodes t : node Destination node to look for induced nodes treewith_bound: float Maximum treewidth acceptable for the graph H. The search for induced nodes will end as soon as the treewidth_bound is exceeded. Returns ------- I : Set of nodes The set of induced nodes in the path from s to t in G Raises ------ NetworkXError The algorithm does not support DiGraph, MultiGraph and MultiDiGraph. If the input graph is an instance of one of these classes, a :exc:`NetworkXError` is raised. The algorithm can only be applied to chordal graphs. If the input graph is found to be non-chordal, a :exc:`NetworkXError` is raised. Examples -------- >>> import networkx as nx >>> G=nx.Graph() >>> G = nx.generators.classic.path_graph(10) >>> I = nx.find_induced_nodes(G,1,9,2) >>> list(I) [1, 2, 3, 4, 5, 6, 7, 8, 9] Notes ----- G must be a chordal graph and (s,t) an edge that is not in G. If a treewidth_bound is provided, the search for induced nodes will end as soon as the treewidth_bound is exceeded. The algorithm is inspired by Algorithm 4 in [1]_. A formal definition of induced node can also be found on that reference. References ---------- .. [1] Learning Bounded Treewidth Bayesian Networks. Gal Elidan, Stephen Gould; JMLR, 9(Dec):2699--2731, 2008. http://jmlr.csail.mit.edu/papers/volume9/elidan08a/elidan08a.pdf sInput graph is not chordal.i( RR R tGraphtadd_edgetsetR tupdatetaddR ( Rtsttttreewidth_boundtHtIttriplettutvtwtn((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyRUs(6          cCsXt|ƒstjdƒ‚ntƒ}x*tjj|ƒD]}|t|ƒO}q:W|S(s¾Returns the set of maximal cliques of a chordal graph. The algorithm breaks the graph in connected components and performs a maximum cardinality search in each component to get the cliques. Parameters ---------- G : graph A NetworkX graph Returns ------- cliques : A set containing the maximal cliques in G. Raises ------ NetworkXError The algorithm does not support DiGraph, MultiGraph and MultiDiGraph. If the input graph is an instance of one of these classes, a :exc:`NetworkXError` is raised. The algorithm can only be applied to chordal graphs. If the input graph is found to be non-chordal, a :exc:`NetworkXError` is raised. Examples -------- >>> import networkx as nx >>> e= [(1,2),(1,3),(2,3),(2,4),(3,4),(3,5),(3,6),(4,5),(4,6),(5,6),(7,8)] >>> G = nx.Graph(e) >>> G.add_node(9) >>> setlist = nx.chordal_graph_cliques(G) sInput graph is not chordal.(RR R Rt connectedtconnected_component_subgraphst _connected_chordal_graph_cliques(RtcliquestC((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyR£s  cCs[t|ƒstjdƒ‚nd}x,tj|ƒD]}t|t|ƒƒ}q4W|dS(s£Returns the treewidth of the chordal graph G. Parameters ---------- G : graph A NetworkX graph Returns ------- treewidth : int The size of the largest clique in the graph minus one. Raises ------ NetworkXError The algorithm does not support DiGraph, MultiGraph and MultiDiGraph. If the input graph is an instance of one of these classes, a :exc:`NetworkXError` is raised. The algorithm can only be applied to chordal graphs. If the input graph is found to be non-chordal, a :exc:`NetworkXError` is raised. Examples -------- >>> import networkx as nx >>> e = [(1,2),(1,3),(2,3),(2,4),(3,4),(3,5),(3,6),(4,5),(4,6),(5,6),(7,8)] >>> G = nx.Graph(e) >>> G.add_node(9) >>> nx.chordal_graph_treewidth(G) 3 References ---------- .. [1] https://en.wikipedia.org/wiki/Tree_decomposition#Treewidth sInput graph is not chordal.iÿÿÿÿi(RR R RtmaxR (Rt max_cliquetclique((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyRÍs # cCsktj|ƒdkr'tjdƒ‚n|jƒ}|dkrCtS|jƒ}||dd}||kS(s&Returns True if G is a complete graph.is'Self loop found in _is_complete_graph()ii(R tnumber_of_selfloopsR tnumber_of_nodesRtnumber_of_edges(RRtet max_edges((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyt_is_complete_graphùs   cCs^t|ƒ}xK|D]C}|tt||jƒƒ|gƒ}|r||jƒfSqWdS(s6 Given a non-complete graph G, returns a missing edge.N(Rtlisttkeystpop(RtnodesRtmissing((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyt_find_missing_edges   'cCsed}xX|D]P}tg||D]}||kr!|^q!ƒ}||kr |}|}q q W|S(s`Returns a the node in choices that has more connections in G to nodes in wanna_connect. iÿÿÿÿ(R (Rtchoicest wanna_connectt max_numbertxtytnumbertmax_cardinality_node((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyt_max_cardinality_nodes /  c Cst|ƒ}|dkr0tjt|ƒƒ}n|j|ƒt|gƒ}d}x¾|rt|||ƒ}|j|ƒ|j|ƒt||ƒ|@}|j|ƒ}t |ƒrðt |t |ƒƒ}||krt j d|ƒ‚qqUt|ƒ\} } | || fSqUWdS(s$ Given a graph G, starts a max cardinality search (starting from s if s is given and from a random node otherwise) trying to find a non-chordal cycle. If it does find one, it returns (u,v,w) where u,v,w are the three nodes that together with s are involved in the cycle. iÿÿÿÿstreewidth_bound exceeded: %sN((RtNonetrandomtchoiceR.tremoveR;RtsubgraphR-R%R R RR3( RRRt unnumberedtnumberedtcurrent_treewidthRtclique_wanna_betsgRR((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyR s(        c Cs[|jƒdkr1t|jƒƒ}t|gƒStƒ}t|jƒƒ}tjt|ƒƒ}|j|ƒt|gƒ}t|gƒ}x±|r?t|||ƒ}|j|ƒ|j |ƒt|j |ƒƒ|@}|j |ƒ}t |ƒr-|j |ƒ||ks$|j t|ƒƒn|}qt jdƒ‚qW|j t|ƒƒ|SdS(s?Return the set of maximal cliques of a connected chordal graph.isInput graph is not chordal.N(R)t frozensetR1RR=R>R.R?R;Rt neighborsR@R-R R ( RR7R#RARRBRDtnew_clique_wanna_beRE((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyR"@s.          (RtnetworkxR R=tsystjoint __authors__t__all__tNetworkXExceptionRRtmaxsizeRRRR-R3R;R<R R"(((sq/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/chordal.pyts&     6N * , $