Skip to content

Commit

Permalink
Docstring changes to try out formats. pep8 too
Browse files Browse the repository at this point in the history
richclub.py is a good example to get "right"
and we can work from there.  It has many special
formatting tasks and is short enough to refer people to.
  • Loading branch information
dschult committed Jan 30, 2016
1 parent ec6dfae commit 886034c
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 75 deletions.
21 changes: 14 additions & 7 deletions networkx/algorithms/richclub.py
@@ -1,22 +1,29 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2004-2016 by
# Aric Hagberg <hagberg@lanl.gov>
# Dan Schult <dschult@colgate.edu>
# Pieter Swart <swart@lanl.gov>
# All rights reserved.
# BSD license.
#
# Authors: Ben Edwards (bedwards@cs.unm.edu)
# Aric Hagberg (hagberg@lanl.gov)
"""Functions for computing rich-club coefficients."""
from __future__ import division

import networkx as nx
from networkx.utils import accumulate
from networkx.utils import not_implemented_for

__author__ = """\n""".join(['Ben Edwards',
'Aric Hagberg <hagberg@lanl.gov>'])

__all__ = ['rich_club_coefficient']


@not_implemented_for('directed')
@not_implemented_for('multigraph')
def rich_club_coefficient(G, normalized=True, Q=100):
r"""Returns the rich-club coefficient of the graph ``G``.
For each degree *k, the *rich-club coefficient* is the ratio of the
For each degree *k*, the *rich-club coefficient* is the ratio of the
number of actual to the number of potential edges for nodes with
degree greater than *k*:
Expand All @@ -32,10 +39,10 @@ def rich_club_coefficient(G, normalized=True, Q=100):
G : NetworkX graph
Undirected graph with neither parallel edges nor self-loops.
normalized : bool (optional)
Normalize using randomized network (see [1]_)
Normalize using randomized network as in [1]_
Q : float (optional, default=100)
If ``normalized`` is ``True``, perform ``Q * m`` double-edge
swaps, where ``m`` is the number of edges in ``G``, to use as a
If ``normalized`` is ``True``, perform `Q * m` double-edge
swaps, where `m` is the number of edges in ``G``, to use as a
null-model for normalization.
Returns
Expand Down
144 changes: 76 additions & 68 deletions networkx/algorithms/shortest_paths/generic.py
@@ -1,25 +1,27 @@
# -*- coding: utf-8 -*-
"""
Compute the shortest paths and path lengths between nodes in the graph.
These algorithms work with undirected and directed graphs.
"""
# Copyright (C) 2004-2016 by
# Aric Hagberg <hagberg@lanl.gov>
# Dan Schult <dschult@colgate.edu>
# Pieter Swart <swart@lanl.gov>
# All rights reserved.
# BSD license.
#
# Authors: Aric Hagberg <aric.hagberg@gmail.com>
# Sérgio Nery Simões <sergionery@gmail.com>
"""
Compute the shortest paths and path lengths between nodes in the graph.
These algorithms work with undirected and directed graphs.
"""
import networkx as nx
__author__ = """\n""".join(['Aric Hagberg <aric.hagberg@gmail.com>',
'Sérgio Nery Simões <sergionery@gmail.com>'])

__all__ = ['shortest_path', 'all_shortest_paths',
'shortest_path_length', 'average_shortest_path_length',
'has_path']


def has_path(G, source, target):
"""Return True if G has a path from source to target, False otherwise.
"""Return *True* if *G* has a path from *source* to *target*.
Parameters
----------
Expand All @@ -32,7 +34,7 @@ def has_path(G, source, target):
Ending node for path
"""
try:
sp = nx.shortest_path(G,source, target)
sp = nx.shortest_path(G, source, target)
except nx.NetworkXNoPath:
return False
return True
Expand All @@ -46,12 +48,12 @@ def shortest_path(G, source=None, target=None, weight=None):
G : NetworkX graph
source : node, optional
Starting node for path.
If not specified, compute shortest paths using all nodes as source nodes.
Starting node for path. If not specified, compute shortest
paths for each possible starting node.
target : node, optional
Ending node for path.
If not specified, compute shortest paths using all nodes as target nodes.
Ending node for path. If not specified, compute shortest
paths to all possible nodes.
weight : None or string, optional (default = None)
If None, every edge has weight/distance/cost 1.
Expand Down Expand Up @@ -79,16 +81,16 @@ def shortest_path(G, source=None, target=None, weight=None):
Examples
--------
>>> G=nx.path_graph(5)
>>> print(nx.shortest_path(G,source=0,target=4))
>>> G = nx.path_graph(5)
>>> print(nx.shortest_path(G, source=0, target=4))
[0, 1, 2, 3, 4]
>>> p=nx.shortest_path(G,source=0) # target not specified
>>> p = nx.shortest_path(G, source=0) # target not specified
>>> p[4]
[0, 1, 2, 3, 4]
>>> p=nx.shortest_path(G,target=4) # source not specified
>>> p = nx.shortest_path(G, target=4) # source not specified
>>> p[0]
[0, 1, 2, 3, 4]
>>> p=nx.shortest_path(G) # source,target not specified
>>> p = nx.shortest_path(G) # source, target not specified
>>> p[0][4]
[0, 1, 2, 3, 4]
Expand All @@ -106,35 +108,37 @@ def shortest_path(G, source=None, target=None, weight=None):
"""
if source is None:
if target is None:
## Find paths between all pairs.
# Find paths between all pairs.
if weight is None:
paths=nx.all_pairs_shortest_path(G)
paths = nx.all_pairs_shortest_path(G)
else:
paths=nx.all_pairs_dijkstra_path(G,weight=weight)
paths = nx.all_pairs_dijkstra_path(G, weight=weight)
else:
## Find paths from all nodes co-accessible to the target.
# Find paths from all nodes co-accessible to the target.
with nx.utils.reversed(G):
if weight is None:
paths=nx.single_source_shortest_path(G, target)
paths = nx.single_source_shortest_path(G, target)
else:
paths=nx.single_source_dijkstra_path(G, target, weight=weight)
paths = nx.single_source_dijkstra_path(G, target,
weight=weight)
# Now flip the paths so they go from a source to the target.
for target in paths:
paths[target] = list(reversed(paths[target]))

else:
if target is None:
## Find paths to all nodes accessible from the source.
# Find paths to all nodes accessible from the source.
if weight is None:
paths=nx.single_source_shortest_path(G,source)
paths = nx.single_source_shortest_path(G, source)
else:
paths=nx.single_source_dijkstra_path(G,source,weight=weight)
paths = nx.single_source_dijkstra_path(G, source,
weight=weight)
else:
## Find shortest source-target path.
# Find shortest source-target path.
if weight is None:
paths=nx.bidirectional_shortest_path(G,source,target)
paths = nx.bidirectional_shortest_path(G, source, target)
else:
paths=nx.dijkstra_path(G,source,target,weight)
paths = nx.dijkstra_path(G, source, target, weight)

return paths

Expand Down Expand Up @@ -188,16 +192,16 @@ def shortest_path_length(G, source=None, target=None, weight=None):
Examples
--------
>>> G=nx.path_graph(5)
>>> nx.shortest_path_length(G,source=0,target=4)
>>> G = nx.path_graph(5)
>>> nx.shortest_path_length(G, source=0, target=4)
4
>>> p=nx.shortest_path_length(G,source=0) # target not specified
>>> p = nx.shortest_path_length(G, source=0) # target not specified
>>> dict(p)[4]
4
>>> p=nx.shortest_path_length(G,target=4) # source not specified
>>> p = nx.shortest_path_length(G, target=4) # source not specified
>>> dict(p)[0]
4
>>> p=nx.shortest_path_length(G) # source,target not specified
>>> p = nx.shortest_path_length(G) # source,target not specified
>>> dict(p)[0][4]
4
Expand All @@ -220,35 +224,37 @@ def shortest_path_length(G, source=None, target=None, weight=None):
"""
if source is None:
if target is None:
## Find paths between all pairs.
# Find paths between all pairs.
if weight is None:
paths = nx.all_pairs_shortest_path_length(G)
else:
paths=nx.all_pairs_dijkstra_path_length(G, weight=weight)
paths = nx.all_pairs_dijkstra_path_length(G, weight=weight)
else:
## Find paths from all nodes co-accessible to the target.
# Find paths from all nodes co-accessible to the target.
with nx.utils.reversed(G):
if weight is None:
# We need to exhaust the iterator as Graph needs
# to be reversed.
paths = list(nx.single_source_shortest_path_length(G, target))
paths = list(nx.single_source_shortest_path_length(G,
target))
else:
paths=nx.single_source_dijkstra_path_length(G, target,
weight=weight)
paths = nx.single_source_dijkstra_path_length(G, target,
weight=weight)
else:
if target is None:
## Find paths to all nodes accessible from the source.
# Find paths to all nodes accessible from the source.
if weight is None:
paths = nx.single_source_shortest_path_length(G,source)
paths = nx.single_source_shortest_path_length(G, source)
else:
paths=nx.single_source_dijkstra_path_length(G,source,weight=weight)
paths = nx.single_source_dijkstra_path_length(G, source,
weight=weight)
else:
## Find shortest source-target path.
# Find shortest source-target path.
if weight is None:
p=nx.bidirectional_shortest_path(G,source,target)
paths=len(p)-1
p = nx.bidirectional_shortest_path(G, source, target)
paths = len(p)-1
else:
paths=nx.dijkstra_path_length(G,source,target,weight)
paths = nx.dijkstra_path_length(G, source, target, weight)
return paths


Expand Down Expand Up @@ -276,18 +282,18 @@ def average_shortest_path_length(G, weight=None):
Raises
------
NetworkXError:
NetworkXError :
if the graph is not connected.
Examples
--------
>>> G=nx.path_graph(5)
>>> G = nx.path_graph(5)
>>> print(nx.average_shortest_path_length(G))
2.0
For disconnected graphs you can compute the average shortest path
length for each component:
>>> G=nx.Graph([(1,2),(3,4)])
>>> G = nx.Graph([(1, 2), (3, 4)])
>>> for g in nx.connected_component_subgraphs(G):
... print(nx.average_shortest_path_length(g))
1.0
Expand All @@ -300,16 +306,17 @@ def average_shortest_path_length(G, weight=None):
else:
if not nx.is_connected(G):
raise nx.NetworkXError("Graph is not connected.")
avg=0.0
avg = 0.0
if weight is None:
for node in G:
path_length=nx.single_source_shortest_path_length(G, node)
path_length = nx.single_source_shortest_path_length(G, node)
avg += sum(dist for n, dist in path_length)
else:
for node in G:
path_length=nx.single_source_dijkstra_path_length(G, node, weight=weight)
path_length = nx.single_source_dijkstra_path_length(G, node,
weight=weight)
avg += sum(dist for n, dist in path_length)
n=len(G)
n = len(G)
return avg/(n*(n-1))


Expand All @@ -333,15 +340,15 @@ def all_shortest_paths(G, source, target, weight=None):
Returns
-------
paths: generator of lists
paths : generator of lists
A generator of all paths between source and target.
Examples
--------
>>> G=nx.Graph()
>>> G.add_path([0,1,2])
>>> G.add_path([0,10,2])
>>> print([p for p in nx.all_shortest_paths(G,source=0,target=2)])
>>> G = nx.Graph()
>>> G.add_path([0, 1, 2])
>>> G.add_path([0, 10, 2])
>>> print([p for p in nx.all_shortest_paths(G, source=0, target=2)])
[[0, 1, 2], [0, 10, 2]]
Notes
Expand All @@ -355,23 +362,24 @@ def all_shortest_paths(G, source, target, weight=None):
all_pairs_shortest_path()
"""
if weight is not None:
pred,dist = nx.dijkstra_predecessor_and_distance(G,source,weight=weight)
pred, dist = nx.dijkstra_predecessor_and_distance(G, source,
weight=weight)
else:
pred = nx.predecessor(G,source)
pred = nx.predecessor(G, source)
if target not in pred:
raise nx.NetworkXNoPath()
stack = [[target,0]]
stack = [[target, 0]]
top = 0
while top >= 0:
node,i = stack[top]
node, i = stack[top]
if node == source:
yield [p for p,n in reversed(stack[:top+1])]
yield [p for p, n in reversed(stack[:top+1])]
if len(pred[node]) > i:
top += 1
if top == len(stack):
stack.append([pred[node][i],0])
stack.append([pred[node][i], 0])
else:
stack[top] = [pred[node][i],0]
stack[top] = [pred[node][i], 0]
else:
stack[top-1][1] += 1
top -= 1

0 comments on commit 886034c

Please sign in to comment.