12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- """Algorithms to calculate reciprocity in a directed graph."""
- import networkx as nx
- from networkx import NetworkXError
- from ..utils import not_implemented_for
- __all__ = ["reciprocity", "overall_reciprocity"]
- @nx._dispatch
- @not_implemented_for("undirected", "multigraph")
- def reciprocity(G, nodes=None):
- r"""Compute the reciprocity in a directed graph.
- The reciprocity of a directed graph is defined as the ratio
- of the number of edges pointing in both directions to the total
- number of edges in the graph.
- Formally, $r = |{(u,v) \in G|(v,u) \in G}| / |{(u,v) \in G}|$.
- The reciprocity of a single node u is defined similarly,
- it is the ratio of the number of edges in both directions to
- the total number of edges attached to node u.
- Parameters
- ----------
- G : graph
- A networkx directed graph
- nodes : container of nodes, optional (default=whole graph)
- Compute reciprocity for nodes in this container.
- Returns
- -------
- out : dictionary
- Reciprocity keyed by node label.
- Notes
- -----
- The reciprocity is not defined for isolated nodes.
- In such cases this function will return None.
- """
-
- if nodes is None:
- return overall_reciprocity(G)
-
-
- if nodes in G:
- reciprocity = next(_reciprocity_iter(G, nodes))[1]
- if reciprocity is None:
- raise NetworkXError("Not defined for isolated nodes.")
- else:
- return reciprocity
-
-
- return dict(_reciprocity_iter(G, nodes))
- def _reciprocity_iter(G, nodes):
- """Return an iterator of (node, reciprocity)."""
- n = G.nbunch_iter(nodes)
- for node in n:
- pred = set(G.predecessors(node))
- succ = set(G.successors(node))
- overlap = pred & succ
- n_total = len(pred) + len(succ)
-
-
- if n_total == 0:
- yield (node, None)
- else:
- reciprocity = 2 * len(overlap) / n_total
- yield (node, reciprocity)
- @nx._dispatch
- @not_implemented_for("undirected", "multigraph")
- def overall_reciprocity(G):
- """Compute the reciprocity for the whole graph.
- See the doc of reciprocity for the definition.
- Parameters
- ----------
- G : graph
- A networkx graph
- """
- n_all_edge = G.number_of_edges()
- n_overlap_edge = (n_all_edge - G.to_undirected().number_of_edges()) * 2
- if n_all_edge == 0:
- raise NetworkXError("Not defined for empty graphs")
- return n_overlap_edge / n_all_edge
|