mirror of
https://github.com/gsi-upm/soil
synced 2025-08-23 19:52:19 +00:00
Clean-up
* Removed old/unnecessary models * Added a `simulation.{iter_}from_py` method to load simulations from python files * Changed tests of examples to run programmatic simulations * Fixed programmatic examples
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from soil.agents import FSM, state, default_state
|
||||
from soil.time import Delta
|
||||
|
||||
|
||||
class Fibonacci(FSM):
|
||||
@@ -11,7 +12,7 @@ class Fibonacci(FSM):
|
||||
def counting(self):
|
||||
self.log("Stopping at {}".format(self.now))
|
||||
prev, self["prev"] = self["prev"], max([self.now, self["prev"]])
|
||||
return None, self.env.timeout(prev)
|
||||
return None, Delta(prev)
|
||||
|
||||
|
||||
class Odds(FSM):
|
||||
@@ -21,18 +22,26 @@ class Odds(FSM):
|
||||
@state
|
||||
def odds(self):
|
||||
self.log("Stopping at {}".format(self.now))
|
||||
return None, self.env.timeout(1 + self.now % 2)
|
||||
return None, Delta(1 + self.now % 2)
|
||||
|
||||
|
||||
from soil import Simulation
|
||||
|
||||
simulation = Simulation(
|
||||
model_params={
|
||||
'agents':[
|
||||
{'agent_class': Fibonacci, 'node_id': 0},
|
||||
{'agent_class': Odds, 'node_id': 1}
|
||||
],
|
||||
'topology': {
|
||||
'params': {
|
||||
'generator': 'complete_graph',
|
||||
'n': 2
|
||||
}
|
||||
},
|
||||
},
|
||||
max_time=100,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
from soil import Simulation
|
||||
|
||||
s = Simulation(
|
||||
network_agents=[
|
||||
{"ids": [0], "agent_class": Fibonacci},
|
||||
{"ids": [1], "agent_class": Odds},
|
||||
],
|
||||
network_params={"generator": "complete_graph", "n": 2},
|
||||
max_time=100,
|
||||
)
|
||||
s.run(dry_run=True)
|
||||
simulation.run(dry_run=True)
|
||||
|
@@ -18,6 +18,7 @@ An example scenario could play like the following:
|
||||
- If there are no more passengers available in the simulation, Drivers die
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from typing import Optional
|
||||
from soil import *
|
||||
from soil import events
|
||||
from mesa.space import MultiGrid
|
||||
@@ -39,7 +40,7 @@ class Journey:
|
||||
tip: float
|
||||
|
||||
passenger: Passenger
|
||||
driver: Driver = None
|
||||
driver: Optional[Driver] = None
|
||||
|
||||
|
||||
class City(EventedEnvironment):
|
||||
@@ -239,5 +240,4 @@ simulation = Simulation(
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
with easy(simulation) as s:
|
||||
s.run()
|
||||
simulation.run()
|
@@ -111,4 +111,5 @@ server = ModularServer(
|
||||
)
|
||||
server.port = 8521
|
||||
|
||||
server.launch(open_browser=False)
|
||||
if __name__ == '__main__':
|
||||
server.launch(open_browser=False)
|
||||
|
@@ -28,7 +28,7 @@ class MoneyAgent(MesaAgent):
|
||||
It will only share wealth with neighbors based on grid proximity
|
||||
"""
|
||||
|
||||
def __init__(self, unique_id, model, wealth=1):
|
||||
def __init__(self, unique_id, model, wealth=1, **kwargs):
|
||||
super().__init__(unique_id=unique_id, model=model)
|
||||
self.wealth = wealth
|
||||
|
||||
|
@@ -10,32 +10,48 @@ def mygenerator():
|
||||
# Add only a node
|
||||
G = Graph()
|
||||
G.add_node(1)
|
||||
G.add_node(2)
|
||||
return G
|
||||
|
||||
|
||||
class MyAgent(agents.FSM):
|
||||
times_run = 0
|
||||
@agents.default_state
|
||||
@agents.state
|
||||
def neutral(self):
|
||||
self.debug("I am running")
|
||||
if agents.prob(0.2):
|
||||
if self.prob(0.2):
|
||||
self.times_run += 1
|
||||
self.info("This runs 2/10 times on average")
|
||||
|
||||
|
||||
s = Simulation(
|
||||
simulation = Simulation(
|
||||
name="Programmatic",
|
||||
network_params={"generator": mygenerator},
|
||||
model_params={
|
||||
'topology': {
|
||||
'params': {
|
||||
'generator': mygenerator
|
||||
},
|
||||
},
|
||||
'agents': {
|
||||
'distribution': [{
|
||||
'agent_class': MyAgent,
|
||||
'topology': True,
|
||||
}]
|
||||
}
|
||||
},
|
||||
seed='Program',
|
||||
agent_reporters={'times_run': 'times_run'},
|
||||
num_trials=1,
|
||||
max_time=100,
|
||||
agent_class=MyAgent,
|
||||
dry_run=True,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# By default, logging will only print WARNING logs (and above).
|
||||
# You need to choose a lower logging level to get INFO/DEBUG traces
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
envs = simulation.run()
|
||||
|
||||
# By default, logging will only print WARNING logs (and above).
|
||||
# You need to choose a lower logging level to get INFO/DEBUG traces
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
envs = s.run()
|
||||
|
||||
# Uncomment this to output the simulation to a YAML file
|
||||
# s.dump_yaml('simulation.yaml')
|
||||
for agent in envs[0].agents:
|
||||
print(agent.times_run)
|
||||
|
@@ -170,6 +170,6 @@ class Police(FSM):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from soil import simulation
|
||||
from soil import run_from_config
|
||||
|
||||
simulation.run_from_config("pubcrawl.yml", dry_run=True, dump=None, parallel=False)
|
||||
run_from_config("pubcrawl.yml", dry_run=True, dump=None, parallel=False)
|
||||
|
@@ -5,6 +5,8 @@ import math
|
||||
|
||||
|
||||
class RabbitEnv(Environment):
|
||||
prob_death = 1e-100
|
||||
|
||||
@property
|
||||
def num_rabbits(self):
|
||||
return self.count_agents(agent_class=Rabbit)
|
||||
@@ -129,7 +131,7 @@ class RandomAccident(BaseAgent):
|
||||
if not rabbits_alive:
|
||||
return self.die()
|
||||
|
||||
prob_death = self.model.get("prob_death", 1e-100) * math.floor(
|
||||
prob_death = self.model.prob_death * math.floor(
|
||||
math.log10(max(1, rabbits_alive))
|
||||
)
|
||||
self.debug("Killing some rabbits with prob={}!".format(prob_death))
|
||||
|
@@ -31,11 +31,11 @@ class MyAgent(agents.FSM):
|
||||
|
||||
s = Simulation(
|
||||
name="Programmatic",
|
||||
network_agents=[{"agent_class": MyAgent, "id": 0}],
|
||||
topology={"nodes": [{"id": 0}], "links": []},
|
||||
model_params={
|
||||
'agents': [{'agent_class': MyAgent}],
|
||||
},
|
||||
num_trials=1,
|
||||
max_time=100,
|
||||
agent_class=MyAgent,
|
||||
dry_run=True,
|
||||
)
|
||||
|
||||
|
@@ -108,14 +108,14 @@ class TerroristSpreadModel(FSM, Geo):
|
||||
return
|
||||
return self.leader
|
||||
|
||||
def ego_search(self, steps=1, center=False, node=None, **kwargs):
|
||||
def ego_search(self, steps=1, center=False, agent=None, **kwargs):
|
||||
"""Get a list of nodes in the ego network of *node* of radius *steps*"""
|
||||
node = as_node(node if node is not None else self)
|
||||
node = agent.node
|
||||
G = self.subgraph(**kwargs)
|
||||
return nx.ego_graph(G, node, center=center, radius=steps).nodes()
|
||||
|
||||
def degree(self, node, force=False):
|
||||
node = as_node(node)
|
||||
def degree(self, agent, force=False):
|
||||
node = agent.node
|
||||
if (
|
||||
force
|
||||
or (not hasattr(self.model, "_degree"))
|
||||
@@ -125,8 +125,8 @@ class TerroristSpreadModel(FSM, Geo):
|
||||
self.model._last_step = self.now
|
||||
return self.model._degree[node]
|
||||
|
||||
def betweenness(self, node, force=False):
|
||||
node = as_node(node)
|
||||
def betweenness(self, agent, force=False):
|
||||
node = agent.node
|
||||
if (
|
||||
force
|
||||
or (not hasattr(self.model, "_betweenness"))
|
||||
|
@@ -216,13 +216,13 @@
|
||||
" @soil.agents.state\n",
|
||||
" def neutral(self):\n",
|
||||
" r = random.random()\n",
|
||||
" if self['has_tv'] and r < self.env['prob_tv_spread']:\n",
|
||||
" if self['has_tv'] and r < self.model['prob_tv_spread']:\n",
|
||||
" return self.infected\n",
|
||||
" return\n",
|
||||
" \n",
|
||||
" @soil.agents.state\n",
|
||||
" def infected(self):\n",
|
||||
" prob_infect = self.env['prob_neighbor_spread']\n",
|
||||
" prob_infect = self.model['prob_neighbor_spread']\n",
|
||||
" for neighbor in self.get_neighboring_agents(state_id=self.neutral.id):\n",
|
||||
" r = random.random()\n",
|
||||
" if r < prob_infect:\n",
|
||||
@@ -271,11 +271,11 @@
|
||||
"class NewsEnvironmentAgent(soil.agents.NetworkAgent):\n",
|
||||
" def step(self):\n",
|
||||
" if self.now == self['event_time']:\n",
|
||||
" self.env['prob_tv_spread'] = 1\n",
|
||||
" self.env['prob_neighbor_spread'] = 1\n",
|
||||
" self.model['prob_tv_spread'] = 1\n",
|
||||
" self.model['prob_neighbor_spread'] = 1\n",
|
||||
" elif self.now > self['event_time']:\n",
|
||||
" self.env['prob_tv_spread'] = self.env['prob_tv_spread'] * TV_FACTOR\n",
|
||||
" self.env['prob_neighbor_spread'] = self.env['prob_neighbor_spread'] * NEIGHBOR_FACTOR"
|
||||
" self.model['prob_tv_spread'] = self.model['prob_tv_spread'] * TV_FACTOR\n",
|
||||
" self.model['prob_neighbor_spread'] = self.model['prob_neighbor_spread'] * NEIGHBOR_FACTOR"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
Reference in New Issue
Block a user