
    h                     L    S r SSKrS/r\R                  " SS9SS j5       rS rg)	z@Functions for computing communities based on centrality notions.    Ngirvan_newmanmost_valuable_edge)preserve_edge_attrsc              #   z  #    U R                  5       S:X  a"  [        [        R                  " U 5      5      v   gUc  S nU R	                  5       R                  5       nUR                  [        R                  " U5      5        UR                  5       S:  a$  [        X!5      v   UR                  5       S:  a  M#  gg7f)us  Finds communities in a graph using the Girvan–Newman method.

Parameters
----------
G : NetworkX graph

most_valuable_edge : function
    Function that takes a graph as input and outputs an edge. The
    edge returned by this function will be recomputed and removed at
    each iteration of the algorithm.

    If not specified, the edge with the highest
    :func:`networkx.edge_betweenness_centrality` will be used.

Returns
-------
iterator
    Iterator over tuples of sets of nodes in `G`. Each set of node
    is a community, each tuple is a sequence of communities at a
    particular level of the algorithm.

Examples
--------
To get the first pair of communities::

    >>> G = nx.path_graph(10)
    >>> comp = nx.community.girvan_newman(G)
    >>> tuple(sorted(c) for c in next(comp))
    ([0, 1, 2, 3, 4], [5, 6, 7, 8, 9])

To get only the first *k* tuples of communities, use
:func:`itertools.islice`::

    >>> import itertools
    >>> G = nx.path_graph(8)
    >>> k = 2
    >>> comp = nx.community.girvan_newman(G)
    >>> for communities in itertools.islice(comp, k):
    ...     print(tuple(sorted(c) for c in communities))
    ...
    ([0, 1, 2, 3], [4, 5, 6, 7])
    ([0, 1], [2, 3], [4, 5, 6, 7])

To stop getting tuples of communities once the number of communities
is greater than *k*, use :func:`itertools.takewhile`::

    >>> import itertools
    >>> G = nx.path_graph(8)
    >>> k = 4
    >>> comp = nx.community.girvan_newman(G)
    >>> limited = itertools.takewhile(lambda c: len(c) <= k, comp)
    >>> for communities in limited:
    ...     print(tuple(sorted(c) for c in communities))
    ...
    ([0, 1, 2, 3], [4, 5, 6, 7])
    ([0, 1], [2, 3], [4, 5, 6, 7])
    ([0, 1], [2, 3], [4, 5], [6, 7])

To just choose an edge to remove based on the weight::

    >>> from operator import itemgetter
    >>> G = nx.path_graph(10)
    >>> edges = G.edges()
    >>> nx.set_edge_attributes(G, {(u, v): v for u, v in edges}, "weight")
    >>> def heaviest(G):
    ...     u, v, w = max(G.edges(data="weight"), key=itemgetter(2))
    ...     return (u, v)
    ...
    >>> comp = nx.community.girvan_newman(G, most_valuable_edge=heaviest)
    >>> tuple(sorted(c) for c in next(comp))
    ([0, 1, 2, 3, 4, 5, 6, 7, 8], [9])

To utilize edge weights when choosing an edge with, for example, the
highest betweenness centrality::

    >>> from networkx import edge_betweenness_centrality as betweenness
    >>> def most_central_edge(G):
    ...     centrality = betweenness(G, weight="weight")
    ...     return max(centrality, key=centrality.get)
    ...
    >>> G = nx.path_graph(10)
    >>> comp = nx.community.girvan_newman(G, most_valuable_edge=most_central_edge)
    >>> tuple(sorted(c) for c in next(comp))
    ([0, 1, 2, 3, 4], [5, 6, 7, 8, 9])

To specify a different ranking algorithm for edges, use the
`most_valuable_edge` keyword argument::

    >>> from networkx import edge_betweenness_centrality
    >>> from random import random
    >>> def most_central_edge(G):
    ...     centrality = edge_betweenness_centrality(G)
    ...     max_cent = max(centrality.values())
    ...     # Scale the centrality values so they are between 0 and 1,
    ...     # and add some random noise.
    ...     centrality = {e: c / max_cent for e, c in centrality.items()}
    ...     # Add some random noise.
    ...     centrality = {e: c + random() for e, c in centrality.items()}
    ...     return max(centrality, key=centrality.get)
    ...
    >>> G = nx.path_graph(10)
    >>> comp = nx.community.girvan_newman(G, most_valuable_edge=most_central_edge)

Notes
-----
The Girvan–Newman algorithm detects communities by progressively
removing edges from the original graph. The algorithm removes the
"most valuable" edge, traditionally the edge with the highest
betweenness centrality, at each step. As the graph breaks down into
pieces, the tightly knit community structure is exposed and the
result can be depicted as a dendrogram.

r   Nc                 T    [         R                  " U 5      n[        XR                  S9$ )zLReturns the edge with the highest betweenness centrality
in the graph `G`.

)key)nxedge_betweenness_centralitymaxget)Gbetweennesss     Z/var/www/html/env/lib/python3.13/site-packages/networkx/algorithms/community/centrality.pyr   )girvan_newman.<locals>.most_valuable_edge   s#     88;K{88    )	number_of_edgestupler	   connected_componentscopyto_undirectedremove_edges_fromselfloop_edges_without_most_central_edges)r   r   gs      r   r   r      s     j 	aB++A.// !	9 	
 A ))!,-




!)!@@ 



!s   B5B;9B;c                     [         R                  " U 5      nUnX2::  aH  U" U 5      nU R                  " U6   [        [         R                  " U 5      5      n[        U5      nX2::  a  MH  W$ )a  Returns the connected components of the graph that results from
repeatedly removing the most "valuable" edge in the graph.

`G` must be a non-empty graph. This function modifies the graph `G`
in-place; that is, it removes edges on the graph `G`.

`most_valuable_edge` is a function that takes the graph `G` as input
(or a subgraph with one or more edges of `G` removed) and returns an
edge. That edge will be removed and this process will be repeated
until the number of connected components in the graph increases.

)r	   number_connected_componentsremove_edger   r   len)r   r   original_num_componentsnum_new_componentsedgenew_componentss         r   r   r      sg     !<<Q?0

7!!$	tr66q9: 0	 
7
 r   )N)__doc__networkxr	   __all___dispatchabler   r    r   r   <module>r(      s=    F 
 &:;KA <KA\r   