Spaces:
Sleeping
Sleeping
"""Function for computing walks in a graph. | |
""" | |
import networkx as nx | |
__all__ = ["number_of_walks"] | |
def number_of_walks(G, walk_length): | |
"""Returns the number of walks connecting each pair of nodes in `G` | |
A *walk* is a sequence of nodes in which each adjacent pair of nodes | |
in the sequence is adjacent in the graph. A walk can repeat the same | |
edge and go in the opposite direction just as people can walk on a | |
set of paths, but standing still is not counted as part of the walk. | |
This function only counts the walks with `walk_length` edges. Note that | |
the number of nodes in the walk sequence is one more than `walk_length`. | |
The number of walks can grow very quickly on a larger graph | |
and with a larger walk length. | |
Parameters | |
---------- | |
G : NetworkX graph | |
walk_length : int | |
A nonnegative integer representing the length of a walk. | |
Returns | |
------- | |
dict | |
A dictionary of dictionaries in which outer keys are source | |
nodes, inner keys are target nodes, and inner values are the | |
number of walks of length `walk_length` connecting those nodes. | |
Raises | |
------ | |
ValueError | |
If `walk_length` is negative | |
Examples | |
-------- | |
>>> G = nx.Graph([(0, 1), (1, 2)]) | |
>>> walks = nx.number_of_walks(G, 2) | |
>>> walks | |
{0: {0: 1, 1: 0, 2: 1}, 1: {0: 0, 1: 2, 2: 0}, 2: {0: 1, 1: 0, 2: 1}} | |
>>> total_walks = sum(sum(tgts.values()) for _, tgts in walks.items()) | |
You can also get the number of walks from a specific source node using the | |
returned dictionary. For example, number of walks of length 1 from node 0 | |
can be found as follows: | |
>>> walks = nx.number_of_walks(G, 1) | |
>>> walks[0] | |
{0: 0, 1: 1, 2: 0} | |
>>> sum(walks[0].values()) # walks from 0 of length 1 | |
1 | |
Similarly, a target node can also be specified: | |
>>> walks[0][1] | |
1 | |
""" | |
import numpy as np | |
if walk_length < 0: | |
raise ValueError(f"`walk_length` cannot be negative: {walk_length}") | |
A = nx.adjacency_matrix(G, weight=None) | |
# TODO: Use matrix_power from scipy.sparse when available | |
# power = sp.sparse.linalg.matrix_power(A, walk_length) | |
power = np.linalg.matrix_power(A.toarray(), walk_length) | |
result = { | |
u: {v: power[u_idx, v_idx] for v_idx, v in enumerate(G)} | |
for u_idx, u in enumerate(G) | |
} | |
return result | |