Skip to content

Commit

Permalink
ICEP model added
Browse files Browse the repository at this point in the history
  • Loading branch information
letiziam committed Jun 3, 2020
1 parent 172271b commit 898f764
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/ndlib.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 106 additions & 0 deletions ndlib/models/epidemics/ICEPModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
from ndlib.models.DiffusionModel import DiffusionModel
import numpy as np
import future.utils

__author__ = 'Letizia Milli'
__license__ = "BSD-2-Clause"
__email__ = "milli@di.unipi.it"


class ICEPModel(DiffusionModel):
"""
Edge Parameters to be specified via ModelConfig
:param permeability: The degree of permeability of a community toward outgoing diffusion processes
"""

def __init__(self, graph):
"""
Model Constructor
:param graph: A networkx graph object
"""
super(self.__class__, self).__init__(graph)
self.available_statuses = {
"Susceptible": 0,
"Infected": 1,
"Removed": 2
}

self.parameters = {
"model": {
"permeability":{
"descr": "Community permeability",
"range": [0,1],
"optional": False,
"default": 0.5
}
},
"nodes": {},
"edges": {},
}

self.name = "Community Permeability"

def iteration(self, node_status=True):
"""
Execute a single model iteration
:return: Iteration_id, Incremental node status (dictionary node->status)
"""
self.clean_initial_status(self.available_statuses.values())
actual_status = {node: nstatus for node, nstatus in future.utils.iteritems(self.status)}

if self.actual_iteration == 0:
self.actual_iteration += 1
delta, node_count, status_delta = self.status_delta(actual_status)
if node_status:
return {"iteration": 0, "status": actual_status.copy(),
"node_count": node_count.copy(), "status_delta": status_delta.copy()}
else:
return {"iteration": 0, "status": {},
"node_count": node_count.copy(), "status_delta": status_delta.copy()}

for u in self.graph.nodes:
if self.status[u] != 1:
continue

neighbors = list(self.graph.neighbors(u)) # neighbors and successors (in DiGraph) produce the same result
same_community_neighbors = [n for n in neighbors if
self.params['nodes']['com'][u] == self.params['nodes']['com'][n]]

# Standard threshold
if len(neighbors) > 0:
threshold = 1.0/len(neighbors)

for v in neighbors:
if actual_status[v] == 0:
key = (u, v)

if self.params['nodes']['com'][u] == self.params['nodes']['com'][v]: # within same community
threshold = float(len(same_community_neighbors))/len(neighbors) # Embedness

else: # across communities
p = self.params['model']['permeability']
if 'threshold' in self.params['edges']:
if key in self.params['edges']['threshold']:
threshold = self.params['edges']['threshold'][key] * p
elif (v, u) in self.params['edges']['threshold'] and not self.graph.directed:
threshold = self.params['edges']['threshold'][(v, u)] * p

flip = np.random.random_sample()
if flip <= threshold:
actual_status[v] = 1

actual_status[u] = 2

delta, node_count, status_delta = self.status_delta(actual_status)
self.status = actual_status
self.actual_iteration += 1

if node_status:
return {"iteration": self.actual_iteration - 1, "status": delta.copy(),
"node_count": node_count.copy(), "status_delta": status_delta.copy()}
else:
return {"iteration": self.actual_iteration - 1, "status": {},
"node_count": node_count.copy(), "status_delta": status_delta.copy()}
4 changes: 3 additions & 1 deletion ndlib/models/epidemics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .ThresholdModel import ThresholdModel
from .ICEModel import ICEModel
from .ICPModel import ICPModel
from .ICEPModel import ICEPModel
from .GeneralThresholdModel import GeneralThresholdModel
from .UTLDRModel import UTLDRModel

Expand All @@ -35,5 +36,6 @@
'ICEModel',
'ICPModel',
'GeneralThresholdModel',
'UTLDRModel'
'UTLDRModel',
'ICEPModel'
]
26 changes: 26 additions & 0 deletions ndlib/test/test_ndlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,32 @@ def test_ICP(self):
iterations = model.iteration_bunch(10, node_status=False)
self.assertEqual(len(iterations), 10)


def test_ICEP(self):


for g in get_graph(True):
model = epd.ICPModel(g)
config = mc.Configuration()
config.add_model_parameter('percentage_infected', 0.1)
if isinstance(g, nx.Graph):
node_to_com = {n: random.choice([0, 1])for n in g.nodes()}
for i in g.nodes():
config.add_node_configuration("com", i, node_to_com[i])
else:
node_to_com = {n: random.choice([0, 1]) for n in g.vs['name']}
for i in g.vs['name']:
config.add_node_configuration("com", i, node_to_com[i])


config.add_model_parameter('permeability', 0.1)

model.set_initial_status(config)
iterations = model.iteration_bunch(10)
self.assertEqual(len(iterations), 10)
iterations = model.iteration_bunch(10, node_status=False)
self.assertEqual(len(iterations), 10)

def test_kertesz_model_predefined_blocked(self):
for g in get_graph(True):
model = epd.KerteszThresholdModel(g)
Expand Down

0 comments on commit 898f764

Please sign in to comment.