mirror of
https://github.com/gsi-upm/soil
synced 2025-08-24 03:52:20 +00:00
Merge branch 'mesa'
This commit is contained in:
@@ -80,11 +80,11 @@
|
||||
"max_time: 300\r\n",
|
||||
"name: Sim_all_dumb\r\n",
|
||||
"network_agents:\r\n",
|
||||
"- agent_type: DumbViewer\r\n",
|
||||
"- agent_class: DumbViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: false\r\n",
|
||||
" weight: 1\r\n",
|
||||
"- agent_type: DumbViewer\r\n",
|
||||
"- agent_class: DumbViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" weight: 1\r\n",
|
||||
@@ -104,19 +104,19 @@
|
||||
"max_time: 300\r\n",
|
||||
"name: Sim_half_herd\r\n",
|
||||
"network_agents:\r\n",
|
||||
"- agent_type: DumbViewer\r\n",
|
||||
"- agent_class: DumbViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: false\r\n",
|
||||
" weight: 1\r\n",
|
||||
"- agent_type: DumbViewer\r\n",
|
||||
"- agent_class: DumbViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" weight: 1\r\n",
|
||||
"- agent_type: HerdViewer\r\n",
|
||||
"- agent_class: HerdViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: false\r\n",
|
||||
" weight: 1\r\n",
|
||||
"- agent_type: HerdViewer\r\n",
|
||||
"- agent_class: HerdViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" weight: 1\r\n",
|
||||
@@ -136,12 +136,12 @@
|
||||
"max_time: 300\r\n",
|
||||
"name: Sim_all_herd\r\n",
|
||||
"network_agents:\r\n",
|
||||
"- agent_type: HerdViewer\r\n",
|
||||
"- agent_class: HerdViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" state_id: neutral\r\n",
|
||||
" weight: 1\r\n",
|
||||
"- agent_type: HerdViewer\r\n",
|
||||
"- agent_class: HerdViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" state_id: neutral\r\n",
|
||||
@@ -163,12 +163,12 @@
|
||||
"max_time: 300\r\n",
|
||||
"name: Sim_wise_herd\r\n",
|
||||
"network_agents:\r\n",
|
||||
"- agent_type: HerdViewer\r\n",
|
||||
"- agent_class: HerdViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" state_id: neutral\r\n",
|
||||
" weight: 1\r\n",
|
||||
"- agent_type: WiseViewer\r\n",
|
||||
"- agent_class: WiseViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" weight: 1\r\n",
|
||||
@@ -189,12 +189,12 @@
|
||||
"max_time: 300\r\n",
|
||||
"name: Sim_all_wise\r\n",
|
||||
"network_agents:\r\n",
|
||||
"- agent_type: WiseViewer\r\n",
|
||||
"- agent_class: WiseViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" state_id: neutral\r\n",
|
||||
" weight: 1\r\n",
|
||||
"- agent_type: WiseViewer\r\n",
|
||||
"- agent_class: WiseViewer\r\n",
|
||||
" state:\r\n",
|
||||
" has_tv: true\r\n",
|
||||
" weight: 1\r\n",
|
||||
|
@@ -1,138 +0,0 @@
|
||||
---
|
||||
default_state: {}
|
||||
load_module: newsspread
|
||||
environment_agents: []
|
||||
environment_params:
|
||||
prob_neighbor_spread: 0.0
|
||||
prob_tv_spread: 0.01
|
||||
interval: 1
|
||||
max_time: 300
|
||||
name: Sim_all_dumb
|
||||
network_agents:
|
||||
- agent_type: DumbViewer
|
||||
state:
|
||||
has_tv: false
|
||||
weight: 1
|
||||
- agent_type: DumbViewer
|
||||
state:
|
||||
has_tv: true
|
||||
weight: 1
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 500
|
||||
m: 5
|
||||
num_trials: 50
|
||||
---
|
||||
default_state: {}
|
||||
load_module: newsspread
|
||||
environment_agents: []
|
||||
environment_params:
|
||||
prob_neighbor_spread: 0.0
|
||||
prob_tv_spread: 0.01
|
||||
interval: 1
|
||||
max_time: 300
|
||||
name: Sim_half_herd
|
||||
network_agents:
|
||||
- agent_type: DumbViewer
|
||||
state:
|
||||
has_tv: false
|
||||
weight: 1
|
||||
- agent_type: DumbViewer
|
||||
state:
|
||||
has_tv: true
|
||||
weight: 1
|
||||
- agent_type: HerdViewer
|
||||
state:
|
||||
has_tv: false
|
||||
weight: 1
|
||||
- agent_type: HerdViewer
|
||||
state:
|
||||
has_tv: true
|
||||
weight: 1
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 500
|
||||
m: 5
|
||||
num_trials: 50
|
||||
---
|
||||
default_state: {}
|
||||
load_module: newsspread
|
||||
environment_agents: []
|
||||
environment_params:
|
||||
prob_neighbor_spread: 0.0
|
||||
prob_tv_spread: 0.01
|
||||
interval: 1
|
||||
max_time: 300
|
||||
name: Sim_all_herd
|
||||
network_agents:
|
||||
- agent_type: HerdViewer
|
||||
state:
|
||||
has_tv: true
|
||||
state_id: neutral
|
||||
weight: 1
|
||||
- agent_type: HerdViewer
|
||||
state:
|
||||
has_tv: true
|
||||
state_id: neutral
|
||||
weight: 1
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 500
|
||||
m: 5
|
||||
num_trials: 50
|
||||
---
|
||||
default_state: {}
|
||||
load_module: newsspread
|
||||
environment_agents: []
|
||||
environment_params:
|
||||
prob_neighbor_spread: 0.0
|
||||
prob_tv_spread: 0.01
|
||||
prob_neighbor_cure: 0.1
|
||||
interval: 1
|
||||
max_time: 300
|
||||
name: Sim_wise_herd
|
||||
network_agents:
|
||||
- agent_type: HerdViewer
|
||||
state:
|
||||
has_tv: true
|
||||
state_id: neutral
|
||||
weight: 1
|
||||
- agent_type: WiseViewer
|
||||
state:
|
||||
has_tv: true
|
||||
weight: 1
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 500
|
||||
m: 5
|
||||
num_trials: 50
|
||||
---
|
||||
default_state: {}
|
||||
load_module: newsspread
|
||||
environment_agents: []
|
||||
environment_params:
|
||||
prob_neighbor_spread: 0.0
|
||||
prob_tv_spread: 0.01
|
||||
prob_neighbor_cure: 0.1
|
||||
interval: 1
|
||||
max_time: 300
|
||||
name: Sim_all_wise
|
||||
network_agents:
|
||||
- agent_type: WiseViewer
|
||||
state:
|
||||
has_tv: true
|
||||
state_id: neutral
|
||||
weight: 1
|
||||
- agent_type: WiseViewer
|
||||
state:
|
||||
has_tv: true
|
||||
weight: 1
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 500
|
||||
m: 5
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 500
|
||||
m: 5
|
||||
num_trials: 50
|
@@ -1,86 +0,0 @@
|
||||
from soil.agents import FSM, state, default_state, prob
|
||||
import logging
|
||||
|
||||
|
||||
class DumbViewer(FSM):
|
||||
'''
|
||||
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']:
|
||||
if prob(self.env['prob_tv_spread']):
|
||||
return self.infected
|
||||
|
||||
@state
|
||||
def infected(self):
|
||||
for neighbor in self.get_neighboring_agents(state_id=self.neutral.id):
|
||||
if prob(self.env['prob_neighbor_spread']):
|
||||
neighbor.infect()
|
||||
|
||||
def infect(self):
|
||||
'''
|
||||
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):
|
||||
'''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()
|
||||
prob_infect = self.env['prob_neighbor_spread'] * infected/total
|
||||
self.debug('prob_infect', prob_infect)
|
||||
if prob(prob_infect):
|
||||
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):
|
||||
prob_cure = self.env['prob_neighbor_cure']
|
||||
for neighbor in self.get_neighboring_agents(state_id=self.infected.id):
|
||||
if 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)
|
||||
prob_cure = self.env['prob_neighbor_cure'] * (cured/infected)
|
||||
if prob(prob_cure):
|
||||
return self.cured
|
||||
return self.set_state(super().infected)
|
134
examples/newsspread/newsspread_sim.py
Normal file
134
examples/newsspread/newsspread_sim.py
Normal file
@@ -0,0 +1,134 @@
|
||||
from soil.agents import FSM, NetworkAgent, state, default_state, prob
|
||||
from soil.parameters import *
|
||||
import logging
|
||||
|
||||
from soil.environment import Environment
|
||||
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
has_been_infected: bool = False
|
||||
has_tv: bool = False
|
||||
|
||||
@default_state
|
||||
@state
|
||||
def neutral(self):
|
||||
if self.has_tv:
|
||||
if self.prob(self.get("prob_tv_spread")):
|
||||
return self.infected
|
||||
if self.has_been_infected:
|
||||
return self.infected
|
||||
|
||||
@state
|
||||
def infected(self):
|
||||
for neighbor in self.get_neighbors(state_id=self.neutral.id):
|
||||
if self.prob(self.get("prob_neighbor_spread")):
|
||||
neighbor.infect()
|
||||
|
||||
def infect(self):
|
||||
"""
|
||||
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.has_been_infected = True
|
||||
|
||||
|
||||
class HerdViewer(DumbViewer):
|
||||
"""
|
||||
A viewer whose probability of infection depends on the state of its neighbors.
|
||||
"""
|
||||
|
||||
def infect(self):
|
||||
"""Notice again that this is NOT a state. See DumbViewer.infect for reference"""
|
||||
infected = self.count_neighbors(state_id=self.infected.id)
|
||||
total = self.count_neighbors()
|
||||
prob_infect = self.get("prob_neighbor_spread") * infected / total
|
||||
self.debug("prob_infect", prob_infect)
|
||||
if self.prob(prob_infect):
|
||||
self.has_been_infected = True
|
||||
|
||||
|
||||
class WiseViewer(HerdViewer):
|
||||
"""
|
||||
A viewer that can change its mind.
|
||||
"""
|
||||
|
||||
@state
|
||||
def cured(self):
|
||||
prob_cure = self.get("prob_neighbor_cure")
|
||||
for neighbor in self.get_neighbors(state_id=self.infected.id):
|
||||
if self.prob(prob_cure):
|
||||
try:
|
||||
neighbor.cure()
|
||||
except AttributeError:
|
||||
self.debug("Viewer {} cannot be cured".format(neighbor.id))
|
||||
|
||||
def cure(self):
|
||||
self.has_been_cured = True
|
||||
|
||||
@state
|
||||
def infected(self):
|
||||
if self.has_been_cured:
|
||||
return self.cured
|
||||
cured = max(self.count_neighbors(self.cured.id), 1.0)
|
||||
infected = max(self.count_neighbors(self.infected.id), 1.0)
|
||||
prob_cure = self.get("prob_neighbor_cure") * (cured / infected)
|
||||
if self.prob(prob_cure):
|
||||
return self.cured
|
||||
|
||||
|
||||
class NewsSpread(Environment):
|
||||
ratio_dumb: probability = 1,
|
||||
ratio_herd: probability = 0,
|
||||
ratio_wise: probability = 0,
|
||||
prob_tv_spread: probability = 0.1,
|
||||
prob_neighbor_spread: probability = 0.1,
|
||||
prob_neighbor_cure: probability = 0.05,
|
||||
|
||||
def init(self):
|
||||
self.populate_network([DumbViewer, HerdViewer, WiseViewer],
|
||||
[self.ratio_dumb, self.ratio_herd, self.ratio_wise])
|
||||
|
||||
|
||||
from itertools import product
|
||||
from soil import Simulation
|
||||
|
||||
|
||||
# We want to investigate the effect of different agent distributions on the spread of news.
|
||||
# To do that, we will run different simulations, with a varying ratio of DumbViewers, HerdViewers, and WiseViewers
|
||||
# Because the effect of these agents might also depend on the network structure, we will run our simulations on two different networks:
|
||||
# one with a small-world structure and one with a connected structure.
|
||||
|
||||
counter = 0
|
||||
for [r1, r2] in product([0, 0.5, 1.0], repeat=2):
|
||||
for (generator, netparams) in {
|
||||
"barabasi_albert_graph": {"m": 5},
|
||||
"erdos_renyi_graph": {"p": 0.1},
|
||||
}.items():
|
||||
print(r1, r2, 1-r1-r2, generator)
|
||||
# Create new simulation
|
||||
netparams["n"] = 500
|
||||
Simulation(
|
||||
name='newspread_sim',
|
||||
model=NewsSpread,
|
||||
parameters=dict(
|
||||
ratio_dumb=r1,
|
||||
ratio_herd=r2,
|
||||
ratio_wise=1-r1-r2,
|
||||
network_generator=generator,
|
||||
network_params=netparams,
|
||||
prob_neighbor_spread=0,
|
||||
),
|
||||
iterations=5,
|
||||
max_steps=300,
|
||||
dump=False,
|
||||
).run()
|
||||
counter += 1
|
||||
# Run all the necessary instances
|
||||
|
||||
print(f"A total of {counter} simulations were run.")
|
Reference in New Issue
Block a user