ó žÃÒYc@s÷dZddlZddlmZmZddlZddlmZddl m Z ddl m Z ddl m Zddl mZddlmZd jd gƒZd gZe d ƒd d„Zd„Zdd„Zdejfd„ƒYZdS(s. Fast approximation for k-component structure iÿÿÿÿN(t defaultdicttMapping(t NetworkXError(tnot_implemented_for(tlocal_node_connectivity(t!build_auxiliary_node_connectivity(tbuild_residual_networks s%Jordi Torrents t k_componentstdirectedgffffffî?c Csœttƒ}t}tj}tj}tj}tj}tj }xItj |ƒD]8} t | ƒ} t | ƒdkrO|dj | ƒqOqOWxItj|ƒD]8} t | ƒ} t | ƒdkr›|dj | ƒq›q›W||ƒ} t| jƒƒ}x td|dƒD]‹}|||d| ƒ}xm||ƒD]_}t |ƒ|krOq1n|j|ƒ}tƒ}|j|jƒƒxT||dƒD]C\}}||||d|ƒ}||krŠ|j||ƒqŠqŠWx¼||ƒD]®}t |ƒ|krüqÞn|j|ƒ}x~t||||ƒD]g}x^||ƒD]P}tj|j|ƒ|ƒ}t |ƒ|krmq4n||j t |ƒƒq4Wq!WqÞWq1Wq W|S(s(Returns the approximate k-component structure of a graph G. A `k`-component is a maximal subgraph of a graph G that has, at least, node connectivity `k`: we need to remove at least `k` nodes to break it into more components. `k`-components have an inherent hierarchical structure because they are nested in terms of connectivity: a connected graph can contain several 2-components, each of which can contain one or more 3-components, and so forth. This implementation is based on the fast heuristics to approximate the `k`-component sturcture of a graph [1]_. Which, in turn, it is based on a fast approximation algorithm for finding good lower bounds of the number of node independent paths between two nodes [2]_. Parameters ---------- G : NetworkX graph Undirected graph min_density : Float Density relaxation treshold. Default value 0.95 Returns ------- k_components : dict Dictionary with connectivity level `k` as key and a list of sets of nodes that form a k-component of level `k` as values. Examples -------- >>> # Petersen graph has 10 nodes and it is triconnected, thus all >>> # nodes are in a single component on all three connectivity levels >>> from networkx.algorithms import approximation as apxa >>> G = nx.petersen_graph() >>> k_components = apxa.k_components(G) Notes ----- The logic of the approximation algorithm for computing the `k`-component structure [1]_ is based on repeatedly applying simple and fast algorithms for `k`-cores and biconnected components in order to narrow down the number of pairs of nodes over which we have to compute White and Newman's approximation algorithm for finding node independent paths [2]_. More formally, this algorithm is based on Whitney's theorem, which states an inclusion relation among node connectivity, edge connectivity, and minimum degree for any graph G. This theorem implies that every `k`-component is nested inside a `k`-edge-component, which in turn, is contained in a `k`-core. Thus, this algorithm computes node independent paths among pairs of nodes in each biconnected part of each `k`-core, and repeats this procedure for each `k` from 3 to the maximal core number of a node in the input graph. Because, in practice, many nodes of the core of level `k` inside a bicomponent actually are part of a component of level k, the auxiliary graph needed for the algorithm is likely to be very dense. Thus, we use a complement graph data structure (see `AntiGraph`) to save memory. AntiGraph only stores information of the edges that are *not* present in the actual auxiliary graph. When applying algorithms to this complement graph data structure, it behaves as if it were the dense version. See also -------- k_components References ---------- .. [1] Torrents, J. and F. Ferraro (2015) Structural Cohesion: Visualization and Heuristics for Fast Computation. https://arxiv.org/pdf/1503.04476v1 .. [2] White, Douglas R., and Mark Newman (2001) A Fast Algorithm for Node-Independent Paths. Santa Fe Institute Working Paper #01-07-035 http://eclectic.ss.uci.edu/~drwhite/working.pdf .. [3] Moody, J. and D. White (2003). Social cohesion and embeddedness: A hierarchical conception of social groups. American Sociological Review 68(1), 103--28. http://www2.asanet.org/journals/ASRFeb03MoodyWhite.pdf iiit core_numbertcutoff(RtlistRtnxtk_coreR tbiconnected_componentstdensityt itertoolst combinationstconnected_componentstsettlentappendtmaxtvaluestrangetsubgrapht _AntiGraphtadd_nodes_fromtnodestadd_edget_cliques_heuristic(tGt min_densityRtnode_connectivityR R RRRt componenttcompt bicomponenttbicompt g_cnumbertmax_coretktCRtSGtHtutvtKth_nodestSHtGctk_nodestGk((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRsPU           +c #sëtj|ƒ}xÕttt|jƒƒdtƒƒD]¯\}‰t‡fd†|jƒDƒƒ‰|dkrwt}n<tj gˆD]&}t‡fd†||Dƒƒ^q„Œ}|rát |ƒ|krá|j ˆ|Bƒ}n|j ˆƒ}tj|ƒ} tj |j |ƒ|ƒ} xÆt | ƒo;tj|ƒ|ksÝ|j | ƒjƒ}t |ƒ|kriPntj|ƒ} t|jƒƒ} t| jƒƒ‰|j‡fd†| jƒDƒƒtj |j |ƒ|ƒ} qW| Vq4WdS(Ntreversec3s'|]\}}|ˆkr|VqdS(N((t.0tntc(tc_value(sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pys ªsic3s!|]}|ˆkr|VqdS(N((R5tx(tcands(sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pys °sc3s'|]\}}|ˆkr|VqdS(N((R5R6td(tmin_deg(sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pys Às(R R t enumeratetsortedRRtTruetitemstFalset intersectionRRR t_sameRtcopytdicttdegreetmintremove_nodes_from( RR+R(R t h_cnumbertitoverlapR6R0t sh_cnumberR*tsh_deg((R8R:R<sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyR§s.1"  3$#icCs6t|jƒƒ}t|ƒt|ƒ|kr2tStS(N(RRRRGR?RA(tmeasurettoltvals((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRCÆsRcBs´eZdZidd6Zd„ZeZd„Zd„Zdefd„ƒYZ de fd „ƒYZ e d „ƒZ d „Z d ejjfd „ƒYZe d„ƒZd„ZRS(sü Class for complement graphs. The main goal is to be able to work with big and dense graphs with a low memory foodprint. In this class you add the edges that *do not exist* in the dense graph, the report methods of the class return the neighbors, the edges and the degree as if it was the dense graph. Thus it's possible to use an instance of this class with some of NetworkX functions. In this case we only use k-core, connected_components, and biconnected_components. itweightcCs|jS(N(t all_edge_dict(tself((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pytsingle_edge_dictÝscsJ|j‰t‡fd†t|jƒt|j|ƒt|gƒDƒƒS(sReturn a dict of neighbors of node n in the dense graph. Parameters ---------- n : node A node in the graph. Returns ------- adj_dict : dictionary The adjacency dictionary for nodes connected to n. c3s|]}|ˆfVqdS(N((R5tnode(RR(sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pys ðs(RRRERt_adj(RSR6((RRsƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyt __getitem__ás cCs`y5tt|jƒt|j|ƒt|gƒƒSWn$tk r[td|fƒ‚nXdS(sXReturn an iterator over all neighbors of node n in the dense graph. s The node %s is not in the graph.N(titerRRVtKeyErrorR(RSR6((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyt neighborsós5 t AntiAtlasViewcBs2eZdZd„Zd„Zd„Zd„ZRS(s%An adjacency inner dict for AntiGraphcCs&||_|j||_||_dS(N(t_graphRVt_atlast_node(RStgraphRU((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyt__init__s cCst|jƒt|jƒdS(Ni(RR\R](RS((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyt__len__scs‡fd†ˆjDƒS(Nc3s3|])}|ˆjkr|ˆjkr|VqdS(N(R]R^(R5R6(RS(sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pys s(R\(RS((RSsƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyt__iter__scCsUt|jjƒt|jƒt|jgƒ}||krE|jjSt|ƒ‚dS(N(RR\RVR]R^RRRY(RStnbrtnbrs((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRW s/  (t__name__t __module__t__doc__R`RaRbRW(((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyR[ýs    tAntiAdjacencyViewcBs2eZdZd„Zd„Zd„Zd„ZRS(s%An adjacency outer dict for AntiGraphcCs||_|j|_dS(N(R\RVR](RSR_((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyR`s cCs t|jƒS(N(RR](RS((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRascCs t|jƒS(N(RXR\(RS((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRbscCs4||jkrt|ƒ‚n|jj|j|ƒS(N(R\RYR[(RSRU((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRWs(ReRfRgR`RaRbRW(((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRhs    cCs |j|ƒS(N(Rh(RS((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pytadj#scCs­t|ƒ}tƒ}|j|ƒxx|D]p}|jƒ}||j|>> G = nx.path_graph(4) >>> G.degree(0) # node 0 with degree 1 1 >>> list(G.degree([0,1])) [(0, 1), (1, 2)] (Rl(RS((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRFBs%ccsJxC|jD]8}|t|jƒt|j|ƒt|gƒfVq WdS(szReturn an iterator of (node, adjacency set) tuples for all nodes in the dense graph. This is the fastest way to look at every edge. For directed graphs, only outgoing adjacencies are included. Returns ------- adj_iter : iterator An iterator of (node, adjacency set) for all nodes in the graph. N(RVR(RSR6((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyt adjacencyis(ReRfRgRRRTtedge_attr_dict_factoryRWRZRR[RhtpropertyRiRR t reportviewst DegreeViewRlRFRp(((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyRÍs       '(RgRt collectionsRRtnetworkxR tnetworkx.exceptionRtnetworkx.utilsRt!networkx.algorithms.approximationRt networkx.algorithms.connectivitytexact_local_node_connectivityRtnetworkx.algorithms.flowRtjoint __author__t__all__RRRCtGraphR(((sƒ/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/algorithms/approximation/kcomponents.pyts      Š