Repository: networkx/networkx

Issue:
Closeness centrality assumes symmetric distance when "distance" parameter is used
At the beginning of `nx.closeness_centrality` code there is this logic:

```python
    if distance is not None:
        # use Dijkstra's algorithm with specified attribute as edge weight
        path_length = functools.partial(nx.single_source_dijkstra_path_length,
                                        weight=distance)
    else:  # handle either directed or undirected
        if G.is_directed() and not reverse:
            path_length = nx.single_target_shortest_path_length
        else:
            path_length = nx.single_source_shortest_path_length
```

This means that if `distance` parameter is passed then the direction of the edges is ignored, and the `reverse` parameter has no effect.

Is this a design decision? I have directed networks with non-symmetric distances and am interested in both inbound and outbound centralities. It looks to me this would be a simple change (checking `reverse` and using `nx.single_target_dijkstra_path_length` if needed). Am willing to make a PR if this is deemed an appropriate change.


Discussion:
This actually looks like a bug to me -- at least on first look.
The dijkstra method works for an undirected graph. 
Does it even work for a directed graph? Say: a single edge (0, 1). 

Also, there is no function ```single_target_dijkstra_path_length```, so the quick fix is different. Now that we have an efficient way to reverse graphs (nx 2.x), it might be best to simply check the reverse flag at the beginning and just use ```G=G.reverse()``` or similar to handle that case. 

But first thing is to check that a directed graph is treated correctly for weighted edges.

Thanks!
> Does it even work for a directed graph? Say: a single edge (0, 1).

It looks like so:

```python
g = nx.DiGraph()
g.add_nodes_from([0,1])

g.add_edge(0, 1, distance=1)
g.add_edge(1, 0, distance=2)

nx.closeness_centrality(g, distance="distance")
```
outputs `{0: 1.0, 1: 0.5}`, and using `nx.reverse(g)` instead of `g` transposes the numbers as expected.
If the second edge is removed, then output is `{0: 1.0, 1: 0.0}`, as expected (and also works after manually reversing).  

If `nx.reverse` is efficient and not too memory taxing, I agree that adding a conditional

```
if reverse:
    G = nx.reverse(G)
```
at the beginning of the computation makes more sense. My networks are small, so for me that will not be an issue, but larger networks might take a hit. Perhaps `nx.reverse_view` instead, or using `copy=False` if that is more resource friendly?

**EDIT**: Upon closer look, it looks like the values are wrongly reversed when the graphs are directed? The docstring claims to compute the *inbound* closeness, but in the one-edge example it seems it is computing the outbound one instead.

Your edited comment is key:  The djikstra shortest path computes outward closeness, not inward as we advertise.  I think that means that currently if our graph has all edge weights 1, we get reversed results for using weighted as compared to unweighted methods.   Hmmm... 

Fixing this could provide a backward compatible headache. We should document it with strong warnings that for NX2.3+ using directed weighted edges gives correct (inward) values whereas for previous versions the directed weighted edges give correct (outward) values and ```reverse``` had no affect.

Assuming ```reverse=False```, in order to compute the inward closeness, we will need to reverse the edges in the weighted case. For the unweighted case, we essentially do that inside ```single_target_shortest_path_length```.  Maybe it would be cleaner to reverse the edges in both cases and use ```single_source_shortest_path_length``` for the unweighted case.  

When ```reverse=True```, then we would NOT reverse the edges...   A little turned around perhaps, but it stems from closeness centrality being defined as looking at inward connections.  

Thoughts?
I don't see a way of fixing this without breaking backwards compatibility. On the other hands, the old results are not what was documented, so I believe it is a necessary collateral damage; documentation and strong warnings can certainly alleviate the pain.

Regarding the API,  I think is is perverse that `reverse=True` means that the graph is not reversed, but I don't see an easy way out of it. Options are redefine closeness to be outwards by default (breaking all the old code!), or changing the `reverse` flag name to something else that is more sensible.

In either case, we could keep raising `DeprecationWarning` for a while until whatever the new API/defaults settles. Since I am not a core developer, I will defer this decision to the people that are more involved with the code, I am willing to help implementing the PR with whatever is agreed on. 
I'm leaning toward getting rid of the ```reverse``` argument. We can reverse graphs easily now so users can simply call it on ```G.reverse()``` instead of ```G```. Fewer arguments also makes the interface that much cleaner. In the code we can reverse any directed graph input in order to provide the inward closeness as advertised.


Resolving patch:
diff --git a/networkx/algorithms/centrality/closeness.py b/networkx/algorithms/centrality/closeness.py
--- a/networkx/algorithms/centrality/closeness.py
+++ b/networkx/algorithms/centrality/closeness.py
@@ -18,8 +18,7 @@
 __all__ = ['closeness_centrality']
 
 
-def closeness_centrality(G, u=None, distance=None,
-                         wf_improved=True, reverse=False):
+def closeness_centrality(G, u=None, distance=None, wf_improved=True):
     r"""Compute closeness centrality for nodes.
 
     Closeness centrality [1]_ of a node `u` is the reciprocal of the
@@ -30,7 +29,9 @@ def closeness_centrality(G, u=None, distance=None,
         C(u) = \frac{n - 1}{\sum_{v=1}^{n-1} d(v, u)},
 
     where `d(v, u)` is the shortest-path distance between `v` and `u`,
-    and `n` is the number of nodes that can reach `u`.
+    and `n` is the number of nodes that can reach `u`. Notice that the
+    closeness distance function computes the incoming distance to `u`
+    for directed graphs. To use outward distance, act on `G.reverse()`.
 
     Notice that higher values of closeness indicate higher centrality.
 
@@ -63,10 +64,6 @@ def closeness_centrality(G, u=None, distance=None,
       Wasserman and Faust improved formula. For single component graphs
       it is the same as the original formula. 
 
-    reverse : bool, optional (default=False)
-      If True and G is a digraph, reverse the edges of G, using successors
-      instead of predecessors.
-
     Returns
     -------
     nodes : dictionary
@@ -89,6 +86,10 @@ def closeness_centrality(G, u=None, distance=None,
     shortest-path length will be computed using Dijkstra's algorithm with
     that edge attribute as the edge weight.
 
+    In NetworkX 2.2 and earlier a bug caused Dijkstra's algorithm to use the
+    outward distance rather than the inward distance. If you use a 'distance'
+    keyword and a DiGraph, your results will change between v2.2 and v2.3.
+
     References
     ----------
     .. [1] Linton C. Freeman: Centrality in networks: I.
@@ -98,18 +99,18 @@ def closeness_centrality(G, u=None, distance=None,
        Social Network Analysis: Methods and Applications, 1994,
        Cambridge University Press.
     """
+    if G.is_directed():
+        G = G.reverse()  # create a reversed graph view
+
     if distance is not None:
         # use Dijkstra's algorithm with specified attribute as edge weight
         path_length = functools.partial(nx.single_source_dijkstra_path_length,
                                         weight=distance)
-    else:  # handle either directed or undirected
-        if G.is_directed() and not reverse:
-            path_length = nx.single_target_shortest_path_length
-        else:
-            path_length = nx.single_source_shortest_path_length
+    else:
+        path_length = nx.single_source_shortest_path_length
 
     if u is None:
-        nodes = G.nodes()
+        nodes = G.nodes
     else:
         nodes = [u]
     closeness_centrality = {}


Test patch:
diff --git a/networkx/algorithms/centrality/tests/test_closeness_centrality.py b/networkx/algorithms/centrality/tests/test_closeness_centrality.py
--- a/networkx/algorithms/centrality/tests/test_closeness_centrality.py
+++ b/networkx/algorithms/centrality/tests/test_closeness_centrality.py
@@ -38,7 +38,7 @@ def test_wf_improved(self):
     def test_digraph(self):
         G = nx.path_graph(3, create_using=nx.DiGraph())
         c = nx.closeness_centrality(G)
-        cr = nx.closeness_centrality(G, reverse=True)
+        cr = nx.closeness_centrality(G.reverse())
         d = {0: 0.0, 1: 0.500, 2: 0.667}
         dr = {0: 0.667, 1: 0.500, 2: 0.0}
         for n in sorted(self.P3):