llama3 / airllm-env /lib /python3.11 /site-packages /networkx /algorithms /centrality /dispersion.py
| from itertools import combinations | |
| import networkx as nx | |
| __all__ = ["dispersion"] | |
| 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 | |