1
0
mirror of https://github.com/gsi-upm/soil synced 2024-11-13 23:12:28 +00:00
soil/examples/newsspread/newsspread.py

87 lines
2.6 KiB
Python
Raw Normal View History

2022-09-16 16:13:39 +00:00
from soil.agents import FSM, NetworkAgent, state, default_state, prob
import logging
2022-09-16 16:13:39 +00:00
class DumbViewer(FSM, NetworkAgent):
'''
A viewer that gets infected via TV (if it has one) and tries to infect
its neighbors once it's infected.
'''
defaults = {
'prob_neighbor_spread': 0.5,
'prob_tv_spread': 0.1,
}
@default_state
@state
def neutral(self):
if self['has_tv']:
2022-10-13 20:43:16 +00:00
if self.prob(self.model['prob_tv_spread']):
2022-04-04 14:47:58 +00:00
return self.infected
@state
def infected(self):
for neighbor in self.get_neighboring_agents(state_id=self.neutral.id):
2022-10-13 20:43:16 +00:00
if self.prob(self.model['prob_neighbor_spread']):
neighbor.infect()
def infect(self):
2022-04-04 14:47:58 +00:00
'''
This is not a state. It is a function that other agents can use to try to
infect this agent. DumbViewer always gets infected, but other agents like
HerdViewer might not become infected right away
'''
self.set_state(self.infected)
class HerdViewer(DumbViewer):
'''
A viewer whose probability of infection depends on the state of its neighbors.
'''
def infect(self):
2022-04-04 14:47:58 +00:00
'''Notice again that this is NOT a state. See DumbViewer.infect for reference'''
infected = self.count_neighboring_agents(state_id=self.infected.id)
total = self.count_neighboring_agents()
2022-10-13 20:43:16 +00:00
prob_infect = self.model['prob_neighbor_spread'] * infected/total
self.debug('prob_infect', prob_infect)
2022-10-13 20:43:16 +00:00
if self.prob(prob_infect):
2022-04-04 14:47:58 +00:00
self.set_state(self.infected)
class WiseViewer(HerdViewer):
'''
A viewer that can change its mind.
'''
defaults = {
'prob_neighbor_spread': 0.5,
'prob_neighbor_cure': 0.25,
'prob_tv_spread': 0.1,
}
@state
def cured(self):
2022-10-13 20:43:16 +00:00
prob_cure = self.model['prob_neighbor_cure']
for neighbor in self.get_neighboring_agents(state_id=self.infected.id):
2022-10-13 20:43:16 +00:00
if self.prob(prob_cure):
try:
neighbor.cure()
except AttributeError:
self.debug('Viewer {} cannot be cured'.format(neighbor.id))
def cure(self):
self.set_state(self.cured.id)
@state
def infected(self):
cured = max(self.count_neighboring_agents(self.cured.id),
1.0)
infected = max(self.count_neighboring_agents(self.infected.id),
1.0)
2022-10-13 20:43:16 +00:00
prob_cure = self.model['prob_neighbor_cure'] * (cured/infected)
if self.prob(prob_cure):
2022-04-04 14:47:58 +00:00
return self.cured
return self.set_state(super().infected)