about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/networkx/algorithms/centrality/dispersion.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/networkx/algorithms/centrality/dispersion.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-4a52a71956a8d46fcb7294ac71734504bb09bcc2.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/networkx/algorithms/centrality/dispersion.py')
-rw-r--r--.venv/lib/python3.12/site-packages/networkx/algorithms/centrality/dispersion.py107
1 files changed, 107 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/networkx/algorithms/centrality/dispersion.py b/.venv/lib/python3.12/site-packages/networkx/algorithms/centrality/dispersion.py
new file mode 100644
index 00000000..a3fa6858
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/networkx/algorithms/centrality/dispersion.py
@@ -0,0 +1,107 @@
+from itertools import combinations
+
+import networkx as nx
+
+__all__ = ["dispersion"]
+
+
+@nx._dispatchable
+def dispersion(G, u=None, v=None, normalized=True, alpha=1.0, b=0.0, c=0.0):
+    r"""Calculate dispersion between `u` and `v` in `G`.
+
+    A link between two actors (`u` and `v`) has a high dispersion when their
+    mutual ties (`s` and `t`) are not well connected with each other.
+
+    Parameters
+    ----------
+    G : graph
+        A NetworkX graph.
+    u : node, optional
+        The source for the dispersion score (e.g. ego node of the network).
+    v : node, optional
+        The target of the dispersion score if specified.
+    normalized : bool
+        If True (default) normalize by the embeddedness of the nodes (u and v).
+    alpha, b, c : float
+        Parameters for the normalization procedure. When `normalized` is True,
+        the dispersion value is normalized by::
+
+            result = ((dispersion + b) ** alpha) / (embeddedness + c)
+
+        as long as the denominator is nonzero.
+
+    Returns
+    -------
+    nodes : dictionary
+        If u (v) is specified, returns a dictionary of nodes with dispersion
+        score for all "target" ("source") nodes. If neither u nor v is
+        specified, returns a dictionary of dictionaries for all nodes 'u' in the
+        graph with a dispersion score for each node 'v'.
+
+    Notes
+    -----
+    This implementation follows Lars Backstrom and Jon Kleinberg [1]_. Typical
+    usage would be to run dispersion on the ego network $G_u$ if $u$ were
+    specified.  Running :func:`dispersion` with neither $u$ nor $v$ specified
+    can take some time to complete.
+
+    References
+    ----------
+    .. [1] Romantic Partnerships and the Dispersion of Social Ties:
+        A Network Analysis of Relationship Status on Facebook.
+        Lars Backstrom, Jon Kleinberg.
+        https://arxiv.org/pdf/1310.6753v1.pdf
+
+    """
+
+    def _dispersion(G_u, u, v):
+        """dispersion for all nodes 'v' in a ego network G_u of node 'u'"""
+        u_nbrs = set(G_u[u])
+        ST = {n for n in G_u[v] if n in u_nbrs}
+        set_uv = {u, v}
+        # all possible ties of connections that u and b share
+        possib = combinations(ST, 2)
+        total = 0
+        for s, t in possib:
+            # neighbors of s that are in G_u, not including u and v
+            nbrs_s = u_nbrs.intersection(G_u[s]) - set_uv
+            # s and t are not directly connected
+            if t not in nbrs_s:
+                # s and t do not share a connection
+                if nbrs_s.isdisjoint(G_u[t]):
+                    # tick for disp(u, v)
+                    total += 1
+        # neighbors that u and v share
+        embeddedness = len(ST)
+
+        dispersion_val = total
+        if normalized:
+            dispersion_val = (total + b) ** alpha
+            if embeddedness + c != 0:
+                dispersion_val /= embeddedness + c
+
+        return dispersion_val
+
+    if u is None:
+        # v and u are not specified
+        if v is None:
+            results = {n: {} for n in G}
+            for u in G:
+                for v in G[u]:
+                    results[u][v] = _dispersion(G, u, v)
+        # u is not specified, but v is
+        else:
+            results = dict.fromkeys(G[v], {})
+            for u in G[v]:
+                results[u] = _dispersion(G, v, u)
+    else:
+        # u is specified with no target v
+        if v is None:
+            results = dict.fromkeys(G[u], {})
+            for v in G[u]:
+                results[v] = _dispersion(G, u, v)
+        # both u and v are specified
+        else:
+            results = _dispersion(G, u, v)
+
+    return results