mirror of
https://github.com/gsi-upm/soil
synced 2025-11-28 19:08:17 +00:00
Compare commits
3 Commits
6c4f44b4cb
...
0.20.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c02e6ea2e8 | ||
|
|
38f8a8d110 | ||
|
|
cb72aac980 |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -3,10 +3,13 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [0.20.1]
|
||||||
|
### Fixed
|
||||||
|
* Agents would run another step after dying.
|
||||||
|
## [0.20.0]
|
||||||
### Added
|
### Added
|
||||||
* Integration with MESA
|
* Integration with MESA
|
||||||
* `not_agent_ids` paramter to get sql in history
|
* `not_agent_ids` parameter to get sql in history
|
||||||
### Changed
|
### Changed
|
||||||
* `soil.Environment` now also inherits from `mesa.Model`
|
* `soil.Environment` now also inherits from `mesa.Model`
|
||||||
* `soil.Agent` now also inherits from `mesa.Agent`
|
* `soil.Agent` now also inherits from `mesa.Agent`
|
||||||
@@ -16,11 +19,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|||||||
### Removed
|
### Removed
|
||||||
* `simpy` dependency and compatibility. Each agent used to be a simpy generator, but that made debugging and error handling more complex. That has been replaced by a scheduler within the `soil.Environment` class, similar to how `mesa` does it.
|
* `simpy` dependency and compatibility. Each agent used to be a simpy generator, but that made debugging and error handling more complex. That has been replaced by a scheduler within the `soil.Environment` class, similar to how `mesa` does it.
|
||||||
* `soil.history` is now a separate package named `tsih`. The keys namedtuple uses `dict_id` instead of `agent_id`.
|
* `soil.history` is now a separate package named `tsih`. The keys namedtuple uses `dict_id` instead of `agent_id`.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* An option to choose whether a database should be used for history
|
* An option to choose whether a database should be used for history
|
||||||
|
|
||||||
|
|
||||||
## [0.15.2]
|
## [0.15.2]
|
||||||
### Fixed
|
### Fixed
|
||||||
* Pass the right known_modules and parameters to stats discovery in simulation
|
* Pass the right known_modules and parameters to stats discovery in simulation
|
||||||
|
|||||||
45
examples/random_delays/random_delays.py
Normal file
45
examples/random_delays/random_delays.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
'''
|
||||||
|
Example of setting a
|
||||||
|
Example of a fully programmatic simulation, without definition files.
|
||||||
|
'''
|
||||||
|
from soil import Simulation, agents
|
||||||
|
from soil.time import Delta
|
||||||
|
from random import expovariate
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MyAgent(agents.FSM):
|
||||||
|
'''
|
||||||
|
An agent that first does a ping
|
||||||
|
'''
|
||||||
|
|
||||||
|
defaults = {'pong_counts': 2}
|
||||||
|
|
||||||
|
@agents.default_state
|
||||||
|
@agents.state
|
||||||
|
def ping(self):
|
||||||
|
self.info('Ping')
|
||||||
|
return self.pong, Delta(expovariate(1/16))
|
||||||
|
|
||||||
|
@agents.state
|
||||||
|
def pong(self):
|
||||||
|
self.info('Pong')
|
||||||
|
self.pong_counts -= 1
|
||||||
|
self.info(str(self.pong_counts))
|
||||||
|
if self.pong_counts < 1:
|
||||||
|
return self.die()
|
||||||
|
return None, Delta(expovariate(1/16))
|
||||||
|
|
||||||
|
|
||||||
|
s = Simulation(name='Programmatic',
|
||||||
|
network_agents=[{'agent_type': MyAgent, 'id': 0}],
|
||||||
|
topology={'nodes': [{'id': 0}], 'links': []},
|
||||||
|
num_trials=1,
|
||||||
|
max_time=100,
|
||||||
|
agent_type=MyAgent,
|
||||||
|
dry_run=True)
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
envs = s.run()
|
||||||
@@ -1 +1 @@
|
|||||||
0.20.0
|
0.20.1
|
||||||
@@ -20,6 +20,10 @@ def as_node(agent):
|
|||||||
|
|
||||||
IGNORED_FIELDS = ('model', 'logger')
|
IGNORED_FIELDS = ('model', 'logger')
|
||||||
|
|
||||||
|
|
||||||
|
class DeadAgent(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
class BaseAgent(Agent):
|
class BaseAgent(Agent):
|
||||||
"""
|
"""
|
||||||
A special Agent that keeps track of its state history.
|
A special Agent that keeps track of its state history.
|
||||||
@@ -129,13 +133,14 @@ class BaseAgent(Agent):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def die(self, remove=False):
|
def die(self, remove=False):
|
||||||
|
self.info(f'agent {self.unique_id} is dying')
|
||||||
self.alive = False
|
self.alive = False
|
||||||
if remove:
|
if remove:
|
||||||
self.remove_node(self.id)
|
self.remove_node(self.id)
|
||||||
|
|
||||||
def step(self):
|
def step(self):
|
||||||
if not self.alive:
|
if not self.alive:
|
||||||
return time.When('inf')
|
raise DeadAgent(self.unique_id)
|
||||||
return super().step() or time.Delta(self.interval)
|
return super().step() or time.Delta(self.interval)
|
||||||
|
|
||||||
def log(self, message, *args, level=logging.INFO, **kwargs):
|
def log(self, message, *args, level=logging.INFO, **kwargs):
|
||||||
@@ -300,7 +305,10 @@ class FSM(NetworkAgent, metaclass=MetaFSM):
|
|||||||
|
|
||||||
def step(self):
|
def step(self):
|
||||||
self.debug(f'Agent {self.unique_id} @ state {self.state_id}')
|
self.debug(f'Agent {self.unique_id} @ state {self.state_id}')
|
||||||
interval = super().step()
|
try:
|
||||||
|
interval = super().step()
|
||||||
|
except DeadAgent:
|
||||||
|
return time.When('inf')
|
||||||
if 'id' not in self.state:
|
if 'id' not in self.state:
|
||||||
# if 'id' in self.state:
|
# if 'id' in self.state:
|
||||||
# self.set_state(self.state['id'])
|
# self.set_state(self.state['id'])
|
||||||
|
|||||||
Reference in New Issue
Block a user