Skip to content

Commit

Permalink
added degree centrality, fixed closeness definition
Browse files Browse the repository at this point in the history
  • Loading branch information
IngoScholtes committed Sep 24, 2018
1 parent 26b88e5 commit 3226554
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 9 deletions.
55 changes: 51 additions & 4 deletions pathpy/algorithms/centralities.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,51 @@ def rank_centralities(centralities):
return ranked_nodes


def degree(network, mode='degree'):
"""
Calculates different notions of degree centrality (directed, weighted) in a network
Parameters:
-----------
mode: str
'degree'
'weight'
'indegree'
'inweight'
'outdegree'
'outweight'
"""

assert mode == 'degree' or mode == 'weight' or mode == 'indegree' or mode == 'outdegree' \
or mode == 'inweight' or mode == 'outweight', 'Error: Invalid mode'

degree_centralities = defaultdict(lambda: 0.0)

for n in network.nodes:
# undirected network: only distinguish between degree and weighted degree
if not network.directed and (mode == 'degree' or mode == 'outdegree' or mode == 'indegree'):
degree_centralities[n] = float(network.nodes[n]['degree'])
if not network.directed and (mode == 'weight' or mode == 'outweight' or mode == 'inweight'):
degree_centralities[n] = float(network.nodes[n]['inweight'])

# directed network: distinguish between degree, weighted degree, inweight, outweight, indegree and outdegree
if network.directed and mode == 'degree':
degree_centralities[n] = float(network.nodes[n]['indegree'])
degree_centralities[n] += float(network.nodes[n]['outdegree'])
if network.directed and mode == 'weight':
degree_centralities[n] = float(network.nodes[n]['inweight'])
degree_centralities[n] += float(network.nodes[n]['outweight'])
elif network.directed and mode == 'indegree':
degree_centralities[n] = float(network.nodes[n]['indegree'])
elif network.directed and mode == 'outdegree':
degree_centralities[n] = float(network.nodes[n]['outdegree'])
elif network.directed and mode == 'inweight':
degree_centralities[n] = float(network.nodes[n]['inweight'])
elif network.directed and mode == 'outweight':
degree_centralities[n] = float(network.nodes[n]['outweight'])
return degree_centralities


@singledispatch
def betweenness(network, normalized=False):
Expand Down Expand Up @@ -261,14 +306,16 @@ def closeness(network, normalized=False):
Log.add('Calculating closeness in network ...', Severity.INFO)

# calculate closeness values
for x in network.nodes:
for d in network.nodes:
for d in network.nodes:
for x in network.nodes:
if d != x and distances[d][x] < _np.inf:
node_centralities[x] += 1.0 / distances[d][x]
node_centralities[x] += distances[d][x]

# assign centrality zero to nodes not occurring on higher-order shortest paths
for v in network.nodes:
node_centralities[v] += 0
node_centralities[v] += 0.0
if node_centralities[v] > 0.0:
node_centralities[v] = (network.ncount() - 1.0) / node_centralities[v]

if normalized:
max_centr = max(node_centralities.values())
Expand Down
15 changes: 10 additions & 5 deletions pathpy/classes/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ def __add__(self, other):
Network
Default operator +, which returns the sum of two Network objects
"""
n_sum = Network()
n_sum.directed = self.directed
n_sum = Network(directed = self.directed or other.directed)
n_sum.nodes = copy.deepcopy(self.nodes)
n_sum.edges = copy.deepcopy(self.edges)
n_sum.successors = copy.deepcopy(self.successors)
Expand Down Expand Up @@ -532,9 +531,9 @@ def total_edge_weight(self):

def node_properties(self, prop):
"""
Returns a sequence of arbitrary node properties in the network,
Returns a list of arbitrary node properties in the network,
where entries have the same order as in network.nodes. If a property
is not present for a given node, None will be added to the sequence.
is not present for a given node, None will be added to the list.
"""
properties = []
for v in self.nodes:
Expand All @@ -548,7 +547,9 @@ def node_properties(self, prop):
def degrees(self, mode='degree'):
"""
Returns the sequence of node degrees in the network, where
entries have the same order as in network.nodes.
entries have the same order as in network.nodes. Note that
if mode == 'degree' for a directed network, the degree sequence
of the undirected network will be returned.
Parameters:
-----------
Expand All @@ -557,6 +558,10 @@ def degrees(self, mode='degree'):
"""
assert mode is 'degree' or mode is 'indegree' or mode is 'outdegree', \
'Only "degree", "indegree", or "outdegree" are supported.'

if self.directed and mode == 'degree':
return self.to_undirected().degrees()

return self.node_properties(mode)


Expand Down

0 comments on commit 3226554

Please sign in to comment.