§
    bŠtj§.  ã                   óJ  — d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddgZ
 G d	„ d
e¦  «        Zd„ Z e	ed¦  «        Zej        d„ ¦   «         Zej        d„ ¦   «         Zej        d„ ¦   «         Z ej        d¬¦  «        dd„¦   «         Zeej        d„ ¦   «         ¦   «         ZdS )zHFunctions for measuring the quality of a partition (into
communities).

é    )ÚcombinationsN)ÚNetworkXError)Úis_partition)ÚargmapÚ
modularityÚpartition_qualityc                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )ÚNotAPartitionz0Raised if a given collection is not a partition.c                 óX   •— |› d|› �}t          ¦   «                              |¦  «         d S )Nz' is not a valid partition of the graph )ÚsuperÚ__init__)ÚselfÚGÚ
collectionÚmsgÚ	__class__s       €úc/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/networkx/algorithms/community/quality.pyr   zNotAPartition.__init__   s4   ø€ ØÐGÐGÀAÐGÐGˆÝ‰Œ×Ò˜ÑÔÐÐÐó    )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__classcell__)r   s   @r   r
   r
      s>   ø€ € € € € Ø:Ð:ðð ð ð ð ð ð ð ð r   r
   c                 óR   — t          | |¦  «        r| |fS t          j        d¦  «        ‚)aÿ  Decorator to check that a valid partition is input to a function

    Raises :exc:`networkx.NetworkXError` if the partition is not valid.

    This decorator should be used on functions whose first two arguments
    are a graph and a partition of the nodes of that graph (in that
    order)::

        >>> @require_partition
        ... def foo(G, partition):
        ...     print("partition is valid!")
        ...
        >>> G = nx.complete_graph(5)
        >>> partition = [{0, 1}, {2, 3}, {4}]
        >>> foo(G, partition)
        partition is valid!
        >>> partition = [{0}, {2, 3}, {4}]
        >>> foo(G, partition)
        Traceback (most recent call last):
          ...
        networkx.exception.NetworkXError: `partition` is not a valid partition of the nodes of G
        >>> partition = [{0, 1}, {1, 2, 3}, {4}]
        >>> foo(G, partition)
        Traceback (most recent call last):
          ...
        networkx.exception.NetworkXError: `partition` is not a valid partition of the nodes of G

    z6`partition` is not a valid partition of the nodes of G)r   Únxr   ©r   Ú	partitions     r   Ú_require_partitionr      s2   € õ: �A�yÑ!Ô!ð Ø�)ˆ|ÐÝ
Ô
ÐSÑ
TÔ
TÐTr   )r   é   c                 ó:   ‡ — t          ˆ fd„|D ¦   «         ¦  «        S )aR  Returns the number of intra-community edges for a partition of `G`.

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

    partition : iterable of sets of nodes
        This must be a partition of the nodes of `G`.

    The "intra-community edges" are those edges joining a pair of nodes
    in the same block of the partition.

    c              3   óf   •K  — | ]+}‰                      |¦  «                             ¦   «         V — Œ,d S ©N)ÚsubgraphÚsize)Ú.0Úblockr   s     €r   ú	<genexpr>z(intra_community_edges.<locals>.<genexpr>L   s;   øè è € Ð?Ð?¨Eˆq�zŠz˜%Ñ Ô ×%Ò%Ñ'Ô'Ð?Ð?Ð?Ð?Ð?Ð?r   )Úsumr   s   ` r   Úintra_community_edgesr)   =   s(   ø€ õ Ð?Ð?Ð?Ð?°YÐ?Ñ?Ô?Ñ?Ô?Ð?r   c                 ó¬   — |                       ¦   «         rt          j        nt          j        }t          j        | ||¬¦  «                             ¦   «         S )a  Returns the number of inter-community edges for a partition of `G`.
    according to the given
    partition of the nodes of `G`.

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

    partition : iterable of sets of nodes
        This must be a partition of the nodes of `G`.

    The *inter-community edges* are those edges joining a pair of nodes
    in different blocks of the partition.

    Implementation note: this function creates an intermediate graph
    that may require the same amount of memory as that of `G`.

    )Úcreate_using)Úis_directedr   ÚMultiDiGraphÚ
MultiGraphÚquotient_graphr$   )r   r   ÚMGs      r   Úinter_community_edgesr1   O   sB   € ð8 ŸMšM™OœOÐ	>�Œˆµ´€BÝÔ˜Q 	¸Ð;Ñ;Ô;×@Ò@ÑBÔBÐBr   c                 óF   — t          t          j        | ¦  «        |¦  «        S )aƒ  Returns the number of inter-community non-edges according to the
    given partition of the nodes of `G`.

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

    partition : iterable of sets of nodes
        This must be a partition of the nodes of `G`.

    A *non-edge* is a pair of nodes (undirected if `G` is undirected)
    that are not adjacent in `G`. The *inter-community non-edges* are
    those non-edges on a pair of nodes in different blocks of the
    partition.

    Implementation note: this function creates two intermediate graphs,
    which may require up to twice the amount of memory as required to
    store `G`.

    )r1   r   Ú
complementr   s     r   Úinter_community_non_edgesr4   o   s   € õ< !¥¤¨qÑ!1Ô!1°9Ñ=Ô=Ð=r   Úweight)Ú
edge_attrsr   c                 óž  ‡ ‡‡‡‡‡‡	‡
— t          |t          ¦  «        st          |¦  «        }t          ‰ |¦  «        st          ‰ |¦  «        ‚‰                      ¦   «         Š‰rpt          ‰                      ‰¬¦  «        ¦  «        Š
t          ‰                      ‰¬¦  «        ¦  «        Št          ‰
 	                    ¦   «         ¦  «        Šd‰dz  z  Š	nSt          ‰  
                    ‰¬¦  «        ¦  «        xŠ
Št          ‰
 	                    ¦   «         ¦  «        }|dz  Šd|dz  z  Š	ˆ ˆˆˆˆ	ˆ
ˆˆfd„}t          t          ||¦  «        ¦  «        S )a7  Returns the modularity of the given partition of the graph.

    Modularity is defined in [1]_ as

    .. math::
        Q = \frac{1}{2m} \sum_{ij} \left( A_{ij} - \gamma\frac{k_ik_j}{2m}\right)
            \delta(c_i,c_j)

    where $m$ is the number of edges (or sum of all edge weights as in [5]_),
    $A$ is the adjacency matrix of `G`, $k_i$ is the (weighted) degree of $i$,
    $\gamma$ is the resolution parameter, and $\delta(c_i, c_j)$ is 1 if $i$ and
    $j$ are in the same community else 0.

    According to [2]_ (and verified by some algebra) this can be reduced to

    .. math::
       Q = \sum_{c=1}^{n}
       \left[ \frac{L_c}{m} - \gamma\left( \frac{k_c}{2m} \right) ^2 \right]

    where the sum iterates over all communities $c$, $m$ is the number of edges,
    $L_c$ is the number of intra-community links for community $c$,
    $k_c$ is the sum of degrees of the nodes in community $c$,
    and $\gamma$ is the resolution parameter.

    The resolution parameter sets an arbitrary tradeoff between intra-group
    edges and inter-group edges. More complex grouping patterns can be
    discovered by analyzing the same network with multiple values of gamma
    and then combining the results [3]_. That said, it is very common to
    simply use gamma=1. More on the choice of gamma is in [4]_.

    The second formula is the one actually used in calculation of the modularity.
    For directed graphs the second formula replaces $k_c$ with $k^{in}_c k^{out}_c$.

    Parameters
    ----------
    G : NetworkX Graph

    communities : list or iterable of set of nodes
        These node sets must represent a partition of G's nodes.

    weight : string or None, optional (default="weight")
        The edge attribute that holds the numerical value used
        as a weight. If None or an edge does not have that attribute,
        then that edge has weight 1.

    resolution : float (default=1)
        If resolution is less than 1, modularity favors larger communities.
        Greater than 1 favors smaller communities.

    Returns
    -------
    Q : float
        The modularity of the partition.

    Raises
    ------
    NotAPartition
        If `communities` is not a partition of the nodes of `G`.

    Examples
    --------
    >>> G = nx.barbell_graph(3, 0)
    >>> nx.community.modularity(G, [{0, 1, 2}, {3, 4, 5}])
    0.35714285714285715
    >>> nx.community.modularity(G, nx.community.label_propagation_communities(G))
    0.35714285714285715

    References
    ----------
    .. [1] M. E. J. Newman "Networks: An Introduction", page 224.
       Oxford University Press, 2011.
    .. [2] Clauset, Aaron, Mark EJ Newman, and Cristopher Moore.
       "Finding community structure in very large networks."
       Phys. Rev. E 70.6 (2004). <https://arxiv.org/abs/cond-mat/0408187>
    .. [3] Reichardt and Bornholdt "Statistical Mechanics of Community Detection"
       Phys. Rev. E 74, 016110, 2006. https://doi.org/10.1103/PhysRevE.74.016110
    .. [4] M. E. J. Newman, "Equivalence between modularity optimization and
       maximum likelihood methods for community detection"
       Phys. Rev. E 94, 052315, 2016. https://doi.org/10.1103/PhysRevE.94.052315
    .. [5] Blondel, V.D. et al. "Fast unfolding of communities in large
       networks" J. Stat. Mech 10008, 1-12 (2008).
       https://doi.org/10.1088/1742-5468/2008/10/P10008
    )r5   r   é   c                 ó  •‡— t          | ¦  «        Št          ˆfd„‰                     ‰‰d¬¦  «        D ¦   «         ¦  «        }t          ˆ
fd„‰D ¦   «         ¦  «        }‰rt          ˆfd„‰D ¦   «         ¦  «        n|}|‰z  ‰|z  |z  ‰	z  z
  S )Nc              3   ó,   •K  — | ]\  }}}|‰v ¯
|V — Œd S r"   © )r%   ÚuÚvÚwtÚcomms       €r   r'   z=modularity.<locals>.community_contribution.<locals>.<genexpr>ø   s.   øè è € ÐXÐX™˜˜A˜rÈaÐSWÈiÈi�"ÈiÈiÈiÈiÐXÐXr   r   )ÚdataÚdefaultc              3   ó(   •K  — | ]}‰|         V — Œd S r"   r;   )r%   r<   Ú
out_degrees     €r   r'   z=modularity.<locals>.community_contribution.<locals>.<genexpr>ú   s'   øè è € Ð9Ð9¨q˜Z¨œ]Ð9Ð9Ð9Ð9Ð9Ð9r   c              3   ó(   •K  — | ]}‰|         V — Œd S r"   r;   )r%   r<   Ú	in_degrees     €r   r'   z=modularity.<locals>.community_contribution.<locals>.<genexpr>û   s'   øè è € Ð7Ð7¨Q˜I aœLÐ7Ð7Ð7Ð7Ð7Ð7r   )Úsetr(   Úedges)Ú	communityÚL_cÚout_degree_sumÚin_degree_sumr?   r   ÚdirectedrE   ÚmÚnormrC   Ú
resolutionr5   s       @€€€€€€€€r   Úcommunity_contributionz*modularity.<locals>.community_contributionö   s¯   øø€ Ý�9‰~Œ~ˆÝÐXÐXÐXÐX Q§W¢W¨T¸È WÑ%JÔ%JÐXÑXÔXÑXÔXˆåÐ9Ð9Ð9Ð9°DÐ9Ñ9Ô9Ñ9Ô9ˆØ;CÐW�Ð7Ð7Ð7Ð7°$Ð7Ñ7Ô7Ñ7Ô7Ð7Èˆà�Q‰w˜ nÑ4°}ÑDÀtÑKÑKÐKr   )Ú
isinstanceÚlistr   r
   r,   ÚdictrC   rE   r(   ÚvaluesÚdegreeÚmap)r   Úcommunitiesr5   rO   Údeg_sumrP   rL   rE   rM   rN   rC   s   ` ``  @@@@@r   r   r   �   ss  øøøøøøøø€ õj �k¥4Ñ(Ô(ð (Ý˜;Ñ'Ô'ˆÝ˜˜;Ñ'Ô'ð ,Ý˜A˜{Ñ+Ô+Ð+à�}Š}‰Œ€HØð 	Ý˜!Ÿ,š,¨f˜,Ñ5Ô5Ñ6Ô6ˆ
Ý˜Ÿš¨F˜Ñ3Ô3Ñ4Ô4ˆ	Ý�
×!Ò!Ñ#Ô#Ñ$Ô$ˆØ�1�a‘4‰xˆˆå!% a§h¢h°f hÑ&=Ô&=Ñ!>Ô!>Ð>ˆ
�YÝ�j×'Ò'Ñ)Ô)Ñ*Ô*ˆØ�a‰KˆØ�7˜A‘:‰~ˆðLð Lð Lð Lð Lð Lð Lð Lð Lð Lð Lð Lõ �sÐ)¨;Ñ7Ô7Ñ8Ô8Ð8r   c                 óN  — i }t          |¦  «        D ]\  }}|D ]}|||<   ŒŒ|                      ¦   «         sAt          d„ t          |d¦  «        D ¦   «         ¦  «        }|                      ¦   «         r|dz  }nd}t          | ¦  «        }||dz
  z  }|                      ¦   «         s|dz  }d}	|}
|                      ¦   «         D ]+}||d                  ||d                  k    r|	dz  }	Œ&|
dz  }
Œ,|	t          | j        ¦  «        z  }|                      ¦   «         rd}n|	|
z   |z  }||fS )aW  Returns the coverage and performance of a partition of G.

    The *coverage* of a partition is the ratio of the number of
    intra-community edges to the total number of edges in the graph.

    The *performance* of a partition is the number of
    intra-community edges plus inter-community non-edges divided by the total
    number of potential edges.

    This algorithm has complexity $O(C^2 + L)$ where C is the number of
    communities and L is the number of links.

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

    partition : sequence
        Partition of the nodes of `G`, represented as a sequence of
        sets of nodes (blocks). Each block of the partition represents a
        community.

    Returns
    -------
    (float, float)
        The (coverage, performance) tuple of the partition, as defined above.

    Raises
    ------
    NetworkXError
        If `partition` is not a valid partition of the nodes of `G`.

    Notes
    -----
    If `G` is a multigraph;
        - for coverage, the multiplicity of edges is counted
        - for performance, the result is -1 (total number of possible edges is not defined)

    References
    ----------
    .. [1] Santo Fortunato.
           "Community Detection in Graphs".
           *Physical Reports*, Volume 486, Issue 3--5 pp. 75--174
           <https://arxiv.org/abs/0906.0612>
    c              3   óZ   K  — | ]&\  }}t          |¦  «        t          |¦  «        z  V — Œ'd S r"   )Úlen)r%   Úp1Úp2s      r   r'   z$partition_quality.<locals>.<genexpr>:  sH   è è € ð -
ð -
Ù"( " b�C�‰GŒG•c˜"‘g”gÑð-
ð -
ð -
ð -
ð -
ð -
r   r8   r   r   g      ð¿)Ú	enumerateÚis_multigraphr(   r   r,   r[   rG   )r   r   Únode_communityÚirH   ÚnodeÚpossible_inter_community_edgesÚnÚtotal_pairsr)   r4   ÚeÚcoverageÚperformances                 r   r   r     s�  € ð` €NÝ! )Ñ,Ô,ð %ð %‰ˆˆ9Øð 	%ð 	%ˆDØ#$ˆN˜4Ñ Ð ð	%ð �?Š?ÑÔð 	+å),ð -
ð -
Ý,8¸ÀAÑ,FÔ,Fð-
ñ -
ô -
ñ *
ô *
Ð&ð �=Š=‰?Œ?ð 	0Ø*¨aÑ/Ð*øà)*Ð&õ 	ˆA‰Œ€AØ�q˜1‘u‘+€KØ�=Š=‰?Œ?ð Ø˜ÑˆàÐØ >Ðð �WŠW‰YŒYð +ð +ˆØ˜!˜Aœ$Ô >°!°A´$Ô#7Ò7Ð7Ø! QÑ&Ð!Ð!à%¨Ñ*Ð%Ð%à$¥s¨1¬7¡|¤|Ñ3€Hà‡‚ÑÔð XØˆˆà,Ð/HÑHÈKÑWˆà�[Ð Ð r   )r5   r   )r   Ú	itertoolsr   Únetworkxr   r   Ú-networkx.algorithms.community.community_utilsr   Únetworkx.utils.decoratorsr   Ú__all__r
   r   Úrequire_partitionÚ_dispatchabler)   r1   r4   r   r   r;   r   r   ú<module>rp      s•  ððð ð
 #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ø FÐ FÐ FÐ FÐ FÐ FØ ,Ð ,Ð ,Ð ,Ð ,Ð ,àÐ,Ð
-€ðð ð ð ð �Mñ ô ð ðUð Uð UðD �FÐ-¨vÑ6Ô6Ð ð Ôð@ð @ñ Ôð@ð" ÔðCð Cñ ÔðCð> Ôð>ð >ñ Ôð>ð@ €Ô˜XÐ&Ñ&Ô&ðn9ð n9ð n9ñ 'Ô&ðn9ðb ØÔðW!ð W!ñ Ôñ ÔðW!ð W!ð W!r   