Repository: networkx/networkx

Issue:
Communicability Betweenness Centrality Error For normalized=False
If you run the method communicability_betweenness_centrality(G, normalized) where normalized is false, you will get the following error:
```
File "../../test/driver_auto_communicability_betweenness_centrality_v01.py", line 186, in main
    libraryMethodReturnTypeVariable  = nx.communicability_betweenness_centrality(Graph,normalized)
local variable 'scale' referenced before assignment
```

---------------------------------------------
```
def _rescale(cbc, normalized):
    # helper to rescale betweenness centrality
    if normalized is True:
        order = len(cbc)
        if order <= 2:
            scale = None
        else:
            scale = 1.0 / ((order - 1.0) ** 2 - (order - 1.0))
    if scale is not None:
        for v in cbc:
            cbc[v] *= scale
    return cbc
```
This is because communicability_betweenness_centrality calls the above method, and as you can see, scale is not defined on the line `if scale is not None`.

I'm not sure what scale should be if normalization is not True.


Discussion:
Good catch and nice diagnosis. I also agree that it's not clear what the behavior *should* be when `normalization=False`, perhaps the linked reference in the docstring of `communicability_betweenness_centrality` would have some info on this?
> 
> 
> Good catch and nice diagnosis. I also agree that it's not clear what the behavior _should_ be when `normalization=False`, perhaps the linked reference in the docstring of `communicability_betweenness_centrality` would have some info on this?

The docstring links to https://arxiv.org/ftp/arxiv/papers/0905/0905.4102.pdf. If you go to page 7, there should be a definition of communicability betweenness. I don't even see a version without normalization.
Wow --- this bug has been there for 9 years. :)  
Looks like the ```_rescale``` function should be moved inline with the function and it's really just a way to avoid dividing by 0 for graphs with 2 or fewer nodes. It sets the 1/((N-1)*(N-2)) term to 1 if <=2 nodes. That's not really a "normalization"... And we can tell that no one wanted the "unnormalized version" because it leads to an exception because of this bug.

I suggest we deprecate the ```normalized``` parameter and replace the function with a scaling that occurs in the function only ```if G.order() > 2:```. 
> 
> 
> Wow --- this bug has been there for 9 years. :)
> Looks like the `_rescale` function should be moved inline with the function and it's really just a way to avoid dividing by 0 for graphs with 2 or fewer nodes. It sets the 1/((N-1)*(N-2)) term to 1 if <=2 nodes. That's not really a "normalization"... And we can tell that no one wanted the "unnormalized version" because it leads to an exception because of this bug.
> 
> I suggest we deprecate the `normalized` parameter and replace the function with a scaling that occurs in the function only `if G.order() > 2:`.

That seems like the most reasonable course of action. 
This Issue requires a deprecation to fix


Resolving patch:
diff --git a/networkx/algorithms/centrality/subgraph_alg.py b/networkx/algorithms/centrality/subgraph_alg.py
--- a/networkx/algorithms/centrality/subgraph_alg.py
+++ b/networkx/algorithms/centrality/subgraph_alg.py
@@ -188,7 +188,7 @@ def subgraph_centrality(G):
 
 @not_implemented_for("directed")
 @not_implemented_for("multigraph")
-def communicability_betweenness_centrality(G, normalized=True):
+def communicability_betweenness_centrality(G):
     r"""Returns subgraph communicability for all pairs of nodes in G.
 
     Communicability betweenness measure makes use of the number of walks
@@ -281,20 +281,10 @@ def communicability_betweenness_centrality(G, normalized=True):
         # put row and col back
         A[i, :] = row
         A[:, i] = col
-    # rescaling
-    cbc = _rescale(cbc, normalized=normalized)
-    return cbc
-
-
-def _rescale(cbc, normalized):
-    # helper to rescale betweenness centrality
-    if normalized is True:
-        order = len(cbc)
-        if order <= 2:
-            scale = None
-        else:
-            scale = 1.0 / ((order - 1.0) ** 2 - (order - 1.0))
-    if scale is not None:
+    # rescale when more than two nodes
+    order = len(cbc)
+    if order > 2:
+        scale = 1.0 / ((order - 1.0) ** 2 - (order - 1.0))
         for v in cbc:
             cbc[v] *= scale
     return cbc


Test patch:
diff --git a/networkx/algorithms/centrality/tests/test_subgraph.py b/networkx/algorithms/centrality/tests/test_subgraph.py
--- a/networkx/algorithms/centrality/tests/test_subgraph.py
+++ b/networkx/algorithms/centrality/tests/test_subgraph.py
@@ -53,6 +53,25 @@ def test_subgraph_centrality_big_graph(self):
         comm200 = nx.subgraph_centrality(g200)
         comm200_exp = nx.subgraph_centrality_exp(g200)
 
+    def test_communicability_betweenness_centrality_small(self):
+        result = communicability_betweenness_centrality(nx.path_graph(2))
+        assert result == {0: 0, 1: 0}
+
+        result = communicability_betweenness_centrality(nx.path_graph(1))
+        assert result == {0: 0}
+
+        result = communicability_betweenness_centrality(nx.path_graph(0))
+        assert result == {}
+
+        answer = {0: 0.1411224421177313, 1: 1.0, 2: 0.1411224421177313}
+        result = communicability_betweenness_centrality(nx.path_graph(3))
+        for k, v in result.items():
+            assert answer[k] == pytest.approx(result[k], abs=1e-7)
+
+        result = communicability_betweenness_centrality(nx.complete_graph(3))
+        for k, v in result.items():
+            assert 0.49786143366223296 == pytest.approx(result[k], abs=1e-7)
+
     def test_communicability_betweenness_centrality(self):
         answer = {
             0: 0.07017447951484615,