We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Parameter 'nodes' is not effective in nx.effective_size()
https://github.com/networkx/networkx/blob/ca839ad24da9ec72abf920eaa33d3fce0a888f4a/networkx/algorithms/structuralholes.py#L144-L162

Parameter variable `nodes` is not used anymore after assigning the default value, which is `G`, at line 145. As another function `nx.constraint()` does in the same file, it seems that for-loops in this code snippet should iterate over `nodes`, not `G`.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `networkx/algorithms/structuralholes.py`
Content:
```
1 # -*- encoding: utf-8 -*-
2 #
3 # Copyright 2008-2017 NetworkX developers.
4 #    Aric Hagberg <hagberg@lanl.gov>
5 #    Dan Schult <dschult@colgate.edu>
6 #    Pieter Swart <swart@lanl.gov>
7 #    All rights reserved.
8 #    BSD license.
9 """Functions for computing measures of structural holes."""
10 from __future__ import division
11 
12 import networkx as nx
13 
14 __all__ = ['constraint', 'local_constraint', 'effective_size']
15 
16 
17 def mutual_weight(G, u, v, weight=None):
18     """Returns the sum of the weights of the edge from `u` to `v` and
19     the edge from `v` to `u` in `G`.
20 
21     `weight` is the edge data key that represents the edge weight. If
22     the specified key is `None` or is not in the edge data for an edge,
23     that edge is assumed to have weight 1.
24 
25     Pre-conditions: `u` and `v` must both be in `G`.
26 
27     """
28     try:
29         a_uv = G[u][v].get(weight, 1)
30     except KeyError:
31         a_uv = 0
32     try:
33         a_vu = G[v][u].get(weight, 1)
34     except KeyError:
35         a_vu = 0
36     return a_uv + a_vu
37 
38 
39 def normalized_mutual_weight(G, u, v, norm=sum, weight=None):
40     """Returns normalized mutual weight of the edges from `u` to `v`
41     with respect to the mutual weights of the neighbors of `u` in `G`.
42 
43     `norm` specifies how the normalization factor is computed. It must
44     be a function that takes a single argument and returns a number.
45     The argument will be an iterable of mutual weights
46     of pairs ``(u, w)``, where ``w`` ranges over each (in- and
47     out-)neighbor of ``u``. Commons values for `normalization` are
48     ``sum`` and ``max``.
49 
50     `weight` can be ``None`` or a string, if None, all edge weights
51     are considered equal. Otherwise holds the name of the edge
52     attribute used as weight.
53 
54     """
55     scale = norm(mutual_weight(G, u, w, weight)
56                  for w in set(nx.all_neighbors(G, u)))
57     return 0 if scale == 0 else mutual_weight(G, u, v, weight) / scale
58 
59 
60 def effective_size(G, nodes=None, weight=None):
61     r"""Returns the effective size of all nodes in the graph ``G``.
62 
63     The *effective size* of a node's ego network is based on the concept
64     of redundancy. A person's ego network has redundancy to the extent
65     that her contacts are connected to each other as well. The
66     nonredundant part of a person's relationships it's the effective
67     size of her ego network [1]_.  Formally, the effective size of a
68     node $u$, denoted $e(u)$, is defined by
69 
70     .. math::
71 
72        e(u) = \sum_{v \in N(u) \setminus \{u\}}
73        \left(1 - \sum_{w \in N(v)} p_{uw} m_{vw}\right)
74 
75     where $N(u)$ is the set of neighbors of $u$ and $p_{uw}$ is the
76     normalized mutual weight of the (directed or undirected) edges
77     joining $u$ and $v$, for each vertex $u$ and $v$ [1]_. And $m_{vw}$
78     is the mutual weight of $v$ and $w$ divided by $v$ highest mutual
79     weight with any of its neighbors. The *mutual weight* of $u$ and $v$
80     is the sum of the weights of edges joining them (edge weights are
81     assumed to be one if the graph is unweighted).
82 
83     For the case of unweighted and undirected graphs, Borgatti proposed
84     a simplified formula to compute effective size [2]_
85 
86     .. math::
87 
88        e(u) = n - \frac{2t}{n}
89 
90     where `t` is the number of ties in the ego network (not including
91     ties to ego) and `n` is the number of nodes (excluding ego).
92 
93     Parameters
94     ----------
95     G : NetworkX graph
96         The graph containing ``v``. Directed graphs are treated like
97         undirected graphs when computing neighbors of ``v``.
98 
99     nodes : container, optional
100         Container of nodes in the graph ``G``.
101 
102     weight : None or string, optional
103       If None, all edge weights are considered equal.
104       Otherwise holds the name of the edge attribute used as weight.
105 
106     Returns
107     -------
108     dict
109         Dictionary with nodes as keys and the constraint on the node as values.
110 
111     Notes
112     -----
113     Burt also defined the related concept of *efficency* of a node's ego
114     network, which is its effective size divided by the degree of that
115     node [1]_. So you can easily compute efficencty:
116 
117     >>> G = nx.DiGraph()
118     >>> G.add_edges_from([(0, 1), (0, 2), (1, 0), (2, 1)])
119     >>> esize = nx.effective_size(G)
120     >>> efficency = {n: v / G.degree(n) for n, v in esize.items()}
121 
122     See also
123     --------
124     constraint
125 
126     References
127     ----------
128     .. [1] Burt, Ronald S.
129            *Structural Holes: The Social Structure of Competition.*
130            Cambridge: Harvard University Press, 1995.
131 
132     .. [2] Borgatti, S.
133            "Structural Holes: Unpacking Burt's Redundancy Measures"
134            CONNECTIONS 20(1):35-38.
135            http://www.analytictech.com/connections/v20(1)/holes.htm
136 
137     """
138     def redundancy(G, u, v, weight=None):
139         nmw = normalized_mutual_weight
140         r = sum(nmw(G, u, w, weight=weight) * nmw(G, v, w, norm=max, weight=weight)
141                 for w in set(nx.all_neighbors(G, u)))
142         return 1 - r
143     effective_size = {}
144     if nodes is None:
145         nodes = G
146     # Use Borgatti's simplified formula for unweighted and undirected graphs
147     if not G.is_directed() and weight is None:
148         for v in G:
149             # Effective size is not defined for isolated nodes
150             if len(G[v]) == 0:
151                 effective_size[v] = float('nan')
152                 continue
153             E = nx.ego_graph(G, v, center=False, undirected=True)
154             effective_size[v] = len(E) - (2 * E.size()) / len(E)
155     else:
156         for v in G:
157             # Effective size is not defined for isolated nodes
158             if len(G[v]) == 0:
159                 effective_size[v] = float('nan')
160                 continue
161             effective_size[v] = sum(redundancy(G, v, u, weight)
162                                     for u in set(nx.all_neighbors(G, v)))
163     return effective_size
164 
165 
166 def constraint(G, nodes=None, weight=None):
167     r"""Returns the constraint on all nodes in the graph ``G``.
168 
169     The *constraint* is a measure of the extent to which a node *v* is
170     invested in those nodes that are themselves invested in the
171     neighbors of *v*. Formally, the *constraint on v*, denoted `c(v)`,
172     is defined by
173 
174     .. math::
175 
176        c(v) = \sum_{w \in N(v) \setminus \{v\}} \ell(v, w)
177 
178     where `N(v)` is the subset of the neighbors of `v` that are either
179     predecessors or successors of `v` and `\ell(v, w)` is the local
180     constraint on `v` with respect to `w` [1]_. For the definition of local
181     constraint, see :func:`local_constraint`.
182 
183     Parameters
184     ----------
185     G : NetworkX graph
186         The graph containing ``v``. This can be either directed or undirected.
187 
188     nodes : container, optional
189         Container of nodes in the graph ``G``.
190 
191     weight : None or string, optional
192       If None, all edge weights are considered equal.
193       Otherwise holds the name of the edge attribute used as weight.
194 
195     Returns
196     -------
197     dict
198         Dictionary with nodes as keys and the constraint on the node as values.
199 
200     See also
201     --------
202     local_constraint
203 
204     References
205     ----------
206     .. [1] Burt, Ronald S.
207            "Structural holes and good ideas".
208            American Journal of Sociology (110): 349–399.
209 
210     """
211     if nodes is None:
212         nodes = G
213     constraint = {}
214     for v in nodes:
215         # Constraint is not defined for isolated nodes
216         if len(G[v]) == 0:
217             constraint[v] = float('nan')
218             continue
219         constraint[v] = sum(local_constraint(G, v, n, weight)
220                             for n in set(nx.all_neighbors(G, v)))
221     return constraint
222 
223 
224 def local_constraint(G, u, v, weight=None):
225     r"""Returns the local constraint on the node ``u`` with respect to
226     the node ``v`` in the graph ``G``.
227 
228     Formally, the *local constraint on u with respect to v*, denoted
229     $\ell(v)$, is defined by
230 
231     .. math::
232 
233        \ell(u, v) = \left(p_{uv} + \sum_{w \in N(v)} p_{uw} p{wv}\right)^2,
234 
235     where $N(v)$ is the set of neighbors of $v$ and $p_{uv}$ is the
236     normalized mutual weight of the (directed or undirected) edges
237     joining $u$ and $v$, for each vertex $u$ and $v$ [1]_. The *mutual
238     weight* of $u$ and $v$ is the sum of the weights of edges joining
239     them (edge weights are assumed to be one if the graph is
240     unweighted).
241 
242     Parameters
243     ----------
244     G : NetworkX graph
245         The graph containing ``u`` and ``v``. This can be either
246         directed or undirected.
247 
248     u : node
249         A node in the graph ``G``.
250 
251     v : node
252         A node in the graph ``G``.
253 
254     weight : None or string, optional
255       If None, all edge weights are considered equal.
256       Otherwise holds the name of the edge attribute used as weight.
257 
258     Returns
259     -------
260     float
261         The constraint of the node ``v`` in the graph ``G``.
262 
263     See also
264     --------
265     constraint
266 
267     References
268     ----------
269     .. [1] Burt, Ronald S.
270            "Structural holes and good ideas".
271            American Journal of Sociology (110): 349–399.
272 
273     """
274     nmw = normalized_mutual_weight
275     direct = nmw(G, u, v, weight=weight)
276     indirect = sum(nmw(G, u, w, weight=weight) * nmw(G, w, v, weight=weight)
277                    for w in set(nx.all_neighbors(G, u)))
278     return (direct + indirect) ** 2
279
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/networkx/algorithms/structuralholes.py b/networkx/algorithms/structuralholes.py
--- a/networkx/algorithms/structuralholes.py
+++ b/networkx/algorithms/structuralholes.py
@@ -97,7 +97,8 @@
         undirected graphs when computing neighbors of ``v``.
 
     nodes : container, optional
-        Container of nodes in the graph ``G``.
+        Container of nodes in the graph ``G`` to compute the effective size.
+        If None, the effective size of every node is computed.
 
     weight : None or string, optional
       If None, all edge weights are considered equal.
@@ -145,7 +146,7 @@
         nodes = G
     # Use Borgatti's simplified formula for unweighted and undirected graphs
     if not G.is_directed() and weight is None:
-        for v in G:
+        for v in nodes:
             # Effective size is not defined for isolated nodes
             if len(G[v]) == 0:
                 effective_size[v] = float('nan')
@@ -153,7 +154,7 @@
             E = nx.ego_graph(G, v, center=False, undirected=True)
             effective_size[v] = len(E) - (2 * E.size()) / len(E)
     else:
-        for v in G:
+        for v in nodes:
             # Effective size is not defined for isolated nodes
             if len(G[v]) == 0:
                 effective_size[v] = float('nan')
@@ -186,7 +187,8 @@
         The graph containing ``v``. This can be either directed or undirected.
 
     nodes : container, optional
-        Container of nodes in the graph ``G``.
+        Container of nodes in the graph ``G`` to compute the constraint. If
+        None, the constraint of every node is computed.
 
     weight : None or string, optional
       If None, all edge weights are considered equal.

{"golden_diff": "diff --git a/networkx/algorithms/structuralholes.py b/networkx/algorithms/structuralholes.py\n--- a/networkx/algorithms/structuralholes.py\n+++ b/networkx/algorithms/structuralholes.py\n@@ -97,7 +97,8 @@\n         undirected graphs when computing neighbors of ``v``.\n \n     nodes : container, optional\n-        Container of nodes in the graph ``G``.\n+        Container of nodes in the graph ``G`` to compute the effective size.\n+        If None, the effective size of every node is computed.\n \n     weight : None or string, optional\n       If None, all edge weights are considered equal.\n@@ -145,7 +146,7 @@\n         nodes = G\n     # Use Borgatti's simplified formula for unweighted and undirected graphs\n     if not G.is_directed() and weight is None:\n-        for v in G:\n+        for v in nodes:\n             # Effective size is not defined for isolated nodes\n             if len(G[v]) == 0:\n                 effective_size[v] = float('nan')\n@@ -153,7 +154,7 @@\n             E = nx.ego_graph(G, v, center=False, undirected=True)\n             effective_size[v] = len(E) - (2 * E.size()) / len(E)\n     else:\n-        for v in G:\n+        for v in nodes:\n             # Effective size is not defined for isolated nodes\n             if len(G[v]) == 0:\n                 effective_size[v] = float('nan')\n@@ -186,7 +187,8 @@\n         The graph containing ``v``. This can be either directed or undirected.\n \n     nodes : container, optional\n-        Container of nodes in the graph ``G``.\n+        Container of nodes in the graph ``G`` to compute the constraint. If\n+        None, the constraint of every node is computed.\n \n     weight : None or string, optional\n       If None, all edge weights are considered equal.\n", "issue": "Parameter 'nodes' is not effective in nx.effective_size()\nhttps://github.com/networkx/networkx/blob/ca839ad24da9ec72abf920eaa33d3fce0a888f4a/networkx/algorithms/structuralholes.py#L144-L162\r\n\r\nParameter variable `nodes` is not used anymore after assigning the default value, which is `G`, at line 145. As another function `nx.constraint()` does in the same file, it seems that for-loops in this code snippet should iterate over `nodes`, not `G`.\n", "before_files": [{"content": "# -*- encoding: utf-8 -*-\n#\n# Copyright 2008-2017 NetworkX developers.\n#    Aric Hagberg <hagberg@lanl.gov>\n#    Dan Schult <dschult@colgate.edu>\n#    Pieter Swart <swart@lanl.gov>\n#    All rights reserved.\n#    BSD license.\n\"\"\"Functions for computing measures of structural holes.\"\"\"\nfrom __future__ import division\n\nimport networkx as nx\n\n__all__ = ['constraint', 'local_constraint', 'effective_size']\n\n\ndef mutual_weight(G, u, v, weight=None):\n    \"\"\"Returns the sum of the weights of the edge from `u` to `v` and\n    the edge from `v` to `u` in `G`.\n\n    `weight` is the edge data key that represents the edge weight. If\n    the specified key is `None` or is not in the edge data for an edge,\n    that edge is assumed to have weight 1.\n\n    Pre-conditions: `u` and `v` must both be in `G`.\n\n    \"\"\"\n    try:\n        a_uv = G[u][v].get(weight, 1)\n    except KeyError:\n        a_uv = 0\n    try:\n        a_vu = G[v][u].get(weight, 1)\n    except KeyError:\n        a_vu = 0\n    return a_uv + a_vu\n\n\ndef normalized_mutual_weight(G, u, v, norm=sum, weight=None):\n    \"\"\"Returns normalized mutual weight of the edges from `u` to `v`\n    with respect to the mutual weights of the neighbors of `u` in `G`.\n\n    `norm` specifies how the normalization factor is computed. It must\n    be a function that takes a single argument and returns a number.\n    The argument will be an iterable of mutual weights\n    of pairs ``(u, w)``, where ``w`` ranges over each (in- and\n    out-)neighbor of ``u``. Commons values for `normalization` are\n    ``sum`` and ``max``.\n\n    `weight` can be ``None`` or a string, if None, all edge weights\n    are considered equal. Otherwise holds the name of the edge\n    attribute used as weight.\n\n    \"\"\"\n    scale = norm(mutual_weight(G, u, w, weight)\n                 for w in set(nx.all_neighbors(G, u)))\n    return 0 if scale == 0 else mutual_weight(G, u, v, weight) / scale\n\n\ndef effective_size(G, nodes=None, weight=None):\n    r\"\"\"Returns the effective size of all nodes in the graph ``G``.\n\n    The *effective size* of a node's ego network is based on the concept\n    of redundancy. A person's ego network has redundancy to the extent\n    that her contacts are connected to each other as well. The\n    nonredundant part of a person's relationships it's the effective\n    size of her ego network [1]_.  Formally, the effective size of a\n    node $u$, denoted $e(u)$, is defined by\n\n    .. math::\n\n       e(u) = \\sum_{v \\in N(u) \\setminus \\{u\\}}\n       \\left(1 - \\sum_{w \\in N(v)} p_{uw} m_{vw}\\right)\n\n    where $N(u)$ is the set of neighbors of $u$ and $p_{uw}$ is the\n    normalized mutual weight of the (directed or undirected) edges\n    joining $u$ and $v$, for each vertex $u$ and $v$ [1]_. And $m_{vw}$\n    is the mutual weight of $v$ and $w$ divided by $v$ highest mutual\n    weight with any of its neighbors. The *mutual weight* of $u$ and $v$\n    is the sum of the weights of edges joining them (edge weights are\n    assumed to be one if the graph is unweighted).\n\n    For the case of unweighted and undirected graphs, Borgatti proposed\n    a simplified formula to compute effective size [2]_\n\n    .. math::\n\n       e(u) = n - \\frac{2t}{n}\n\n    where `t` is the number of ties in the ego network (not including\n    ties to ego) and `n` is the number of nodes (excluding ego).\n\n    Parameters\n    ----------\n    G : NetworkX graph\n        The graph containing ``v``. Directed graphs are treated like\n        undirected graphs when computing neighbors of ``v``.\n\n    nodes : container, optional\n        Container of nodes in the graph ``G``.\n\n    weight : None or string, optional\n      If None, all edge weights are considered equal.\n      Otherwise holds the name of the edge attribute used as weight.\n\n    Returns\n    -------\n    dict\n        Dictionary with nodes as keys and the constraint on the node as values.\n\n    Notes\n    -----\n    Burt also defined the related concept of *efficency* of a node's ego\n    network, which is its effective size divided by the degree of that\n    node [1]_. So you can easily compute efficencty:\n\n    >>> G = nx.DiGraph()\n    >>> G.add_edges_from([(0, 1), (0, 2), (1, 0), (2, 1)])\n    >>> esize = nx.effective_size(G)\n    >>> efficency = {n: v / G.degree(n) for n, v in esize.items()}\n\n    See also\n    --------\n    constraint\n\n    References\n    ----------\n    .. [1] Burt, Ronald S.\n           *Structural Holes: The Social Structure of Competition.*\n           Cambridge: Harvard University Press, 1995.\n\n    .. [2] Borgatti, S.\n           \"Structural Holes: Unpacking Burt's Redundancy Measures\"\n           CONNECTIONS 20(1):35-38.\n           http://www.analytictech.com/connections/v20(1)/holes.htm\n\n    \"\"\"\n    def redundancy(G, u, v, weight=None):\n        nmw = normalized_mutual_weight\n        r = sum(nmw(G, u, w, weight=weight) * nmw(G, v, w, norm=max, weight=weight)\n                for w in set(nx.all_neighbors(G, u)))\n        return 1 - r\n    effective_size = {}\n    if nodes is None:\n        nodes = G\n    # Use Borgatti's simplified formula for unweighted and undirected graphs\n    if not G.is_directed() and weight is None:\n        for v in G:\n            # Effective size is not defined for isolated nodes\n            if len(G[v]) == 0:\n                effective_size[v] = float('nan')\n                continue\n            E = nx.ego_graph(G, v, center=False, undirected=True)\n            effective_size[v] = len(E) - (2 * E.size()) / len(E)\n    else:\n        for v in G:\n            # Effective size is not defined for isolated nodes\n            if len(G[v]) == 0:\n                effective_size[v] = float('nan')\n                continue\n            effective_size[v] = sum(redundancy(G, v, u, weight)\n                                    for u in set(nx.all_neighbors(G, v)))\n    return effective_size\n\n\ndef constraint(G, nodes=None, weight=None):\n    r\"\"\"Returns the constraint on all nodes in the graph ``G``.\n\n    The *constraint* is a measure of the extent to which a node *v* is\n    invested in those nodes that are themselves invested in the\n    neighbors of *v*. Formally, the *constraint on v*, denoted `c(v)`,\n    is defined by\n\n    .. math::\n\n       c(v) = \\sum_{w \\in N(v) \\setminus \\{v\\}} \\ell(v, w)\n\n    where `N(v)` is the subset of the neighbors of `v` that are either\n    predecessors or successors of `v` and `\\ell(v, w)` is the local\n    constraint on `v` with respect to `w` [1]_. For the definition of local\n    constraint, see :func:`local_constraint`.\n\n    Parameters\n    ----------\n    G : NetworkX graph\n        The graph containing ``v``. This can be either directed or undirected.\n\n    nodes : container, optional\n        Container of nodes in the graph ``G``.\n\n    weight : None or string, optional\n      If None, all edge weights are considered equal.\n      Otherwise holds the name of the edge attribute used as weight.\n\n    Returns\n    -------\n    dict\n        Dictionary with nodes as keys and the constraint on the node as values.\n\n    See also\n    --------\n    local_constraint\n\n    References\n    ----------\n    .. [1] Burt, Ronald S.\n           \"Structural holes and good ideas\".\n           American Journal of Sociology (110): 349\u2013399.\n\n    \"\"\"\n    if nodes is None:\n        nodes = G\n    constraint = {}\n    for v in nodes:\n        # Constraint is not defined for isolated nodes\n        if len(G[v]) == 0:\n            constraint[v] = float('nan')\n            continue\n        constraint[v] = sum(local_constraint(G, v, n, weight)\n                            for n in set(nx.all_neighbors(G, v)))\n    return constraint\n\n\ndef local_constraint(G, u, v, weight=None):\n    r\"\"\"Returns the local constraint on the node ``u`` with respect to\n    the node ``v`` in the graph ``G``.\n\n    Formally, the *local constraint on u with respect to v*, denoted\n    $\\ell(v)$, is defined by\n\n    .. math::\n\n       \\ell(u, v) = \\left(p_{uv} + \\sum_{w \\in N(v)} p_{uw} p{wv}\\right)^2,\n\n    where $N(v)$ is the set of neighbors of $v$ and $p_{uv}$ is the\n    normalized mutual weight of the (directed or undirected) edges\n    joining $u$ and $v$, for each vertex $u$ and $v$ [1]_. The *mutual\n    weight* of $u$ and $v$ is the sum of the weights of edges joining\n    them (edge weights are assumed to be one if the graph is\n    unweighted).\n\n    Parameters\n    ----------\n    G : NetworkX graph\n        The graph containing ``u`` and ``v``. This can be either\n        directed or undirected.\n\n    u : node\n        A node in the graph ``G``.\n\n    v : node\n        A node in the graph ``G``.\n\n    weight : None or string, optional\n      If None, all edge weights are considered equal.\n      Otherwise holds the name of the edge attribute used as weight.\n\n    Returns\n    -------\n    float\n        The constraint of the node ``v`` in the graph ``G``.\n\n    See also\n    --------\n    constraint\n\n    References\n    ----------\n    .. [1] Burt, Ronald S.\n           \"Structural holes and good ideas\".\n           American Journal of Sociology (110): 349\u2013399.\n\n    \"\"\"\n    nmw = normalized_mutual_weight\n    direct = nmw(G, u, v, weight=weight)\n    indirect = sum(nmw(G, u, w, weight=weight) * nmw(G, w, v, weight=weight)\n                   for w in set(nx.all_neighbors(G, u)))\n    return (direct + indirect) ** 2\n", "path": "networkx/algorithms/structuralholes.py"}], "after_files": [{"content": "# -*- encoding: utf-8 -*-\n#\n# Copyright 2008-2017 NetworkX developers.\n#    Aric Hagberg <hagberg@lanl.gov>\n#    Dan Schult <dschult@colgate.edu>\n#    Pieter Swart <swart@lanl.gov>\n#    All rights reserved.\n#    BSD license.\n\"\"\"Functions for computing measures of structural holes.\"\"\"\nfrom __future__ import division\n\nimport networkx as nx\n\n__all__ = ['constraint', 'local_constraint', 'effective_size']\n\n\ndef mutual_weight(G, u, v, weight=None):\n    \"\"\"Returns the sum of the weights of the edge from `u` to `v` and\n    the edge from `v` to `u` in `G`.\n\n    `weight` is the edge data key that represents the edge weight. If\n    the specified key is `None` or is not in the edge data for an edge,\n    that edge is assumed to have weight 1.\n\n    Pre-conditions: `u` and `v` must both be in `G`.\n\n    \"\"\"\n    try:\n        a_uv = G[u][v].get(weight, 1)\n    except KeyError:\n        a_uv = 0\n    try:\n        a_vu = G[v][u].get(weight, 1)\n    except KeyError:\n        a_vu = 0\n    return a_uv + a_vu\n\n\ndef normalized_mutual_weight(G, u, v, norm=sum, weight=None):\n    \"\"\"Returns normalized mutual weight of the edges from `u` to `v`\n    with respect to the mutual weights of the neighbors of `u` in `G`.\n\n    `norm` specifies how the normalization factor is computed. It must\n    be a function that takes a single argument and returns a number.\n    The argument will be an iterable of mutual weights\n    of pairs ``(u, w)``, where ``w`` ranges over each (in- and\n    out-)neighbor of ``u``. Commons values for `normalization` are\n    ``sum`` and ``max``.\n\n    `weight` can be ``None`` or a string, if None, all edge weights\n    are considered equal. Otherwise holds the name of the edge\n    attribute used as weight.\n\n    \"\"\"\n    scale = norm(mutual_weight(G, u, w, weight)\n                 for w in set(nx.all_neighbors(G, u)))\n    return 0 if scale == 0 else mutual_weight(G, u, v, weight) / scale\n\n\ndef effective_size(G, nodes=None, weight=None):\n    r\"\"\"Returns the effective size of all nodes in the graph ``G``.\n\n    The *effective size* of a node's ego network is based on the concept\n    of redundancy. A person's ego network has redundancy to the extent\n    that her contacts are connected to each other as well. The\n    nonredundant part of a person's relationships it's the effective\n    size of her ego network [1]_.  Formally, the effective size of a\n    node $u$, denoted $e(u)$, is defined by\n\n    .. math::\n\n       e(u) = \\sum_{v \\in N(u) \\setminus \\{u\\}}\n       \\left(1 - \\sum_{w \\in N(v)} p_{uw} m_{vw}\\right)\n\n    where $N(u)$ is the set of neighbors of $u$ and $p_{uw}$ is the\n    normalized mutual weight of the (directed or undirected) edges\n    joining $u$ and $v$, for each vertex $u$ and $v$ [1]_. And $m_{vw}$\n    is the mutual weight of $v$ and $w$ divided by $v$ highest mutual\n    weight with any of its neighbors. The *mutual weight* of $u$ and $v$\n    is the sum of the weights of edges joining them (edge weights are\n    assumed to be one if the graph is unweighted).\n\n    For the case of unweighted and undirected graphs, Borgatti proposed\n    a simplified formula to compute effective size [2]_\n\n    .. math::\n\n       e(u) = n - \\frac{2t}{n}\n\n    where `t` is the number of ties in the ego network (not including\n    ties to ego) and `n` is the number of nodes (excluding ego).\n\n    Parameters\n    ----------\n    G : NetworkX graph\n        The graph containing ``v``. Directed graphs are treated like\n        undirected graphs when computing neighbors of ``v``.\n\n    nodes : container, optional\n        Container of nodes in the graph ``G`` to compute the effective size.\n        If None, the effective size of every node is computed.\n\n    weight : None or string, optional\n      If None, all edge weights are considered equal.\n      Otherwise holds the name of the edge attribute used as weight.\n\n    Returns\n    -------\n    dict\n        Dictionary with nodes as keys and the constraint on the node as values.\n\n    Notes\n    -----\n    Burt also defined the related concept of *efficency* of a node's ego\n    network, which is its effective size divided by the degree of that\n    node [1]_. So you can easily compute efficencty:\n\n    >>> G = nx.DiGraph()\n    >>> G.add_edges_from([(0, 1), (0, 2), (1, 0), (2, 1)])\n    >>> esize = nx.effective_size(G)\n    >>> efficency = {n: v / G.degree(n) for n, v in esize.items()}\n\n    See also\n    --------\n    constraint\n\n    References\n    ----------\n    .. [1] Burt, Ronald S.\n           *Structural Holes: The Social Structure of Competition.*\n           Cambridge: Harvard University Press, 1995.\n\n    .. [2] Borgatti, S.\n           \"Structural Holes: Unpacking Burt's Redundancy Measures\"\n           CONNECTIONS 20(1):35-38.\n           http://www.analytictech.com/connections/v20(1)/holes.htm\n\n    \"\"\"\n    def redundancy(G, u, v, weight=None):\n        nmw = normalized_mutual_weight\n        r = sum(nmw(G, u, w, weight=weight) * nmw(G, v, w, norm=max, weight=weight)\n                for w in set(nx.all_neighbors(G, u)))\n        return 1 - r\n    effective_size = {}\n    if nodes is None:\n        nodes = G\n    # Use Borgatti's simplified formula for unweighted and undirected graphs\n    if not G.is_directed() and weight is None:\n        for v in nodes:\n            # Effective size is not defined for isolated nodes\n            if len(G[v]) == 0:\n                effective_size[v] = float('nan')\n                continue\n            E = nx.ego_graph(G, v, center=False, undirected=True)\n            effective_size[v] = len(E) - (2 * E.size()) / len(E)\n    else:\n        for v in nodes:\n            # Effective size is not defined for isolated nodes\n            if len(G[v]) == 0:\n                effective_size[v] = float('nan')\n                continue\n            effective_size[v] = sum(redundancy(G, v, u, weight)\n                                    for u in set(nx.all_neighbors(G, v)))\n    return effective_size\n\n\ndef constraint(G, nodes=None, weight=None):\n    r\"\"\"Returns the constraint on all nodes in the graph ``G``.\n\n    The *constraint* is a measure of the extent to which a node *v* is\n    invested in those nodes that are themselves invested in the\n    neighbors of *v*. Formally, the *constraint on v*, denoted `c(v)`,\n    is defined by\n\n    .. math::\n\n       c(v) = \\sum_{w \\in N(v) \\setminus \\{v\\}} \\ell(v, w)\n\n    where `N(v)` is the subset of the neighbors of `v` that are either\n    predecessors or successors of `v` and `\\ell(v, w)` is the local\n    constraint on `v` with respect to `w` [1]_. For the definition of local\n    constraint, see :func:`local_constraint`.\n\n    Parameters\n    ----------\n    G : NetworkX graph\n        The graph containing ``v``. This can be either directed or undirected.\n\n    nodes : container, optional\n        Container of nodes in the graph ``G`` to compute the constraint. If\n        None, the constraint of every node is computed.\n\n    weight : None or string, optional\n      If None, all edge weights are considered equal.\n      Otherwise holds the name of the edge attribute used as weight.\n\n    Returns\n    -------\n    dict\n        Dictionary with nodes as keys and the constraint on the node as values.\n\n    See also\n    --------\n    local_constraint\n\n    References\n    ----------\n    .. [1] Burt, Ronald S.\n           \"Structural holes and good ideas\".\n           American Journal of Sociology (110): 349\u2013399.\n\n    \"\"\"\n    if nodes is None:\n        nodes = G\n    constraint = {}\n    for v in nodes:\n        # Constraint is not defined for isolated nodes\n        if len(G[v]) == 0:\n            constraint[v] = float('nan')\n            continue\n        constraint[v] = sum(local_constraint(G, v, n, weight)\n                            for n in set(nx.all_neighbors(G, v)))\n    return constraint\n\n\ndef local_constraint(G, u, v, weight=None):\n    r\"\"\"Returns the local constraint on the node ``u`` with respect to\n    the node ``v`` in the graph ``G``.\n\n    Formally, the *local constraint on u with respect to v*, denoted\n    $\\ell(v)$, is defined by\n\n    .. math::\n\n       \\ell(u, v) = \\left(p_{uv} + \\sum_{w \\in N(v)} p_{uw} p{wv}\\right)^2,\n\n    where $N(v)$ is the set of neighbors of $v$ and $p_{uv}$ is the\n    normalized mutual weight of the (directed or undirected) edges\n    joining $u$ and $v$, for each vertex $u$ and $v$ [1]_. The *mutual\n    weight* of $u$ and $v$ is the sum of the weights of edges joining\n    them (edge weights are assumed to be one if the graph is\n    unweighted).\n\n    Parameters\n    ----------\n    G : NetworkX graph\n        The graph containing ``u`` and ``v``. This can be either\n        directed or undirected.\n\n    u : node\n        A node in the graph ``G``.\n\n    v : node\n        A node in the graph ``G``.\n\n    weight : None or string, optional\n      If None, all edge weights are considered equal.\n      Otherwise holds the name of the edge attribute used as weight.\n\n    Returns\n    -------\n    float\n        The constraint of the node ``v`` in the graph ``G``.\n\n    See also\n    --------\n    constraint\n\n    References\n    ----------\n    .. [1] Burt, Ronald S.\n           \"Structural holes and good ideas\".\n           American Journal of Sociology (110): 349\u2013399.\n\n    \"\"\"\n    nmw = normalized_mutual_weight\n    direct = nmw(G, u, v, weight=weight)\n    indirect = sum(nmw(G, u, w, weight=weight) * nmw(G, w, v, weight=weight)\n                   for w in set(nx.all_neighbors(G, u)))\n    return (direct + indirect) ** 2\n", "path": "networkx/algorithms/structuralholes.py"}]}