Mesa 2.3.4__py3-none-any.whl → 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of Mesa might be problematic. Click here for more details.
- mesa/__init__.py +3 -5
- mesa/agent.py +393 -116
- mesa/batchrunner.py +58 -31
- mesa/datacollection.py +141 -30
- mesa/examples/README.md +37 -0
- mesa/examples/__init__.py +21 -0
- mesa/examples/advanced/epstein_civil_violence/Epstein Civil Violence.ipynb +116 -0
- mesa/examples/advanced/epstein_civil_violence/Readme.md +34 -0
- mesa/examples/advanced/epstein_civil_violence/__init__.py +0 -0
- mesa/examples/advanced/epstein_civil_violence/agents.py +164 -0
- mesa/examples/advanced/epstein_civil_violence/app.py +73 -0
- mesa/examples/advanced/epstein_civil_violence/model.py +114 -0
- mesa/examples/advanced/pd_grid/Readme.md +43 -0
- mesa/examples/advanced/pd_grid/__init__.py +0 -0
- mesa/examples/advanced/pd_grid/agents.py +50 -0
- mesa/examples/advanced/pd_grid/analysis.ipynb +228 -0
- mesa/examples/advanced/pd_grid/app.py +54 -0
- mesa/examples/advanced/pd_grid/model.py +71 -0
- mesa/examples/advanced/sugarscape_g1mt/Readme.md +64 -0
- mesa/examples/advanced/sugarscape_g1mt/__init__.py +0 -0
- mesa/examples/advanced/sugarscape_g1mt/agents.py +344 -0
- mesa/examples/advanced/sugarscape_g1mt/app.py +62 -0
- mesa/examples/advanced/sugarscape_g1mt/model.py +180 -0
- mesa/examples/advanced/sugarscape_g1mt/sugar-map.txt +50 -0
- mesa/examples/advanced/sugarscape_g1mt/tests.py +69 -0
- mesa/examples/advanced/wolf_sheep/Readme.md +57 -0
- mesa/examples/advanced/wolf_sheep/__init__.py +0 -0
- mesa/examples/advanced/wolf_sheep/agents.py +102 -0
- mesa/examples/advanced/wolf_sheep/app.py +84 -0
- mesa/examples/advanced/wolf_sheep/model.py +137 -0
- mesa/examples/basic/__init__.py +0 -0
- mesa/examples/basic/boid_flockers/Readme.md +22 -0
- mesa/examples/basic/boid_flockers/__init__.py +0 -0
- mesa/examples/basic/boid_flockers/agents.py +71 -0
- mesa/examples/basic/boid_flockers/app.py +58 -0
- mesa/examples/basic/boid_flockers/model.py +69 -0
- mesa/examples/basic/boltzmann_wealth_model/Readme.md +56 -0
- mesa/examples/basic/boltzmann_wealth_model/__init__.py +0 -0
- mesa/examples/basic/boltzmann_wealth_model/agents.py +31 -0
- mesa/examples/basic/boltzmann_wealth_model/app.py +74 -0
- mesa/examples/basic/boltzmann_wealth_model/model.py +43 -0
- mesa/examples/basic/boltzmann_wealth_model/st_app.py +115 -0
- mesa/examples/basic/conways_game_of_life/Readme.md +39 -0
- mesa/examples/basic/conways_game_of_life/__init__.py +0 -0
- mesa/examples/basic/conways_game_of_life/agents.py +47 -0
- mesa/examples/basic/conways_game_of_life/app.py +51 -0
- mesa/examples/basic/conways_game_of_life/model.py +31 -0
- mesa/examples/basic/conways_game_of_life/st_app.py +72 -0
- mesa/examples/basic/schelling/Readme.md +40 -0
- mesa/examples/basic/schelling/__init__.py +0 -0
- mesa/examples/basic/schelling/agents.py +26 -0
- mesa/examples/basic/schelling/analysis.ipynb +205 -0
- mesa/examples/basic/schelling/app.py +42 -0
- mesa/examples/basic/schelling/model.py +59 -0
- mesa/examples/basic/virus_on_network/Readme.md +61 -0
- mesa/examples/basic/virus_on_network/__init__.py +0 -0
- mesa/examples/basic/virus_on_network/agents.py +69 -0
- mesa/examples/basic/virus_on_network/app.py +114 -0
- mesa/examples/basic/virus_on_network/model.py +96 -0
- mesa/experimental/UserParam.py +18 -7
- mesa/experimental/__init__.py +10 -2
- mesa/experimental/cell_space/__init__.py +16 -1
- mesa/experimental/cell_space/cell.py +93 -23
- mesa/experimental/cell_space/cell_agent.py +117 -21
- mesa/experimental/cell_space/cell_collection.py +56 -19
- mesa/experimental/cell_space/discrete_space.py +92 -8
- mesa/experimental/cell_space/grid.py +33 -9
- mesa/experimental/cell_space/network.py +15 -10
- mesa/experimental/cell_space/voronoi.py +257 -0
- mesa/experimental/components/altair.py +11 -2
- mesa/experimental/components/matplotlib.py +132 -26
- mesa/experimental/devs/__init__.py +2 -0
- mesa/experimental/devs/eventlist.py +54 -15
- mesa/experimental/devs/examples/epstein_civil_violence.py +71 -39
- mesa/experimental/devs/examples/wolf_sheep.py +45 -45
- mesa/experimental/devs/simulator.py +57 -16
- mesa/experimental/{jupyter_viz.py → solara_viz.py} +151 -98
- mesa/model.py +212 -84
- mesa/space.py +217 -151
- mesa/time.py +63 -80
- mesa/visualization/__init__.py +25 -6
- mesa/visualization/components/__init__.py +83 -0
- mesa/visualization/components/altair_components.py +188 -0
- mesa/visualization/components/matplotlib_components.py +175 -0
- mesa/visualization/mpl_space_drawing.py +593 -0
- mesa/visualization/solara_viz.py +458 -0
- mesa/visualization/user_param.py +69 -0
- mesa/visualization/utils.py +9 -0
- {mesa-2.3.4.dist-info → mesa-3.0.0.dist-info}/METADATA +65 -19
- mesa-3.0.0.dist-info/RECORD +95 -0
- mesa-3.0.0.dist-info/licenses/LICENSE +202 -0
- mesa-2.3.4.dist-info/licenses/LICENSE → mesa-3.0.0.dist-info/licenses/NOTICE +2 -2
- mesa/cookiecutter-mesa/cookiecutter.json +0 -8
- mesa/cookiecutter-mesa/hooks/post_gen_project.py +0 -11
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md +0 -4
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/run.pytemplate +0 -3
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate +0 -11
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate +0 -60
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/server.pytemplate +0 -36
- mesa/flat/__init__.py +0 -6
- mesa/flat/visualization.py +0 -5
- mesa/main.py +0 -63
- mesa/visualization/ModularVisualization.py +0 -1
- mesa/visualization/TextVisualization.py +0 -1
- mesa/visualization/UserParam.py +0 -1
- mesa/visualization/modules.py +0 -1
- mesa-2.3.4.dist-info/RECORD +0 -45
- /mesa/{cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}} → examples/advanced}/__init__.py +0 -0
- {mesa-2.3.4.dist-info → mesa-3.0.0.dist-info}/WHEEL +0 -0
- {mesa-2.3.4.dist-info → mesa-3.0.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,36 +1,40 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Wolf-Sheep Predation Model
|
|
3
|
-
================================
|
|
4
|
-
|
|
5
|
-
Replication of the model found in NetLogo:
|
|
6
|
-
Wilensky, U. (1997). NetLogo Wolf Sheep Predation model.
|
|
7
|
-
http://ccl.northwestern.edu/netlogo/models/WolfSheepPredation.
|
|
8
|
-
Center for Connected Learning and Computer-Based Modeling,
|
|
9
|
-
Northwestern University, Evanston, IL.
|
|
10
|
-
"""
|
|
1
|
+
"""Example of using ABM simulator for Wolf-Sheep Predation Model."""
|
|
11
2
|
|
|
12
3
|
import mesa
|
|
4
|
+
from mesa.experimental.cell_space import FixedAgent
|
|
13
5
|
from mesa.experimental.devs.simulator import ABMSimulator
|
|
14
6
|
|
|
15
7
|
|
|
16
8
|
class Animal(mesa.Agent):
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
"""Base Animal class."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, model, moore, energy, p_reproduce, energy_from_food):
|
|
12
|
+
"""Initialize Animal instance.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
model: a model instance
|
|
16
|
+
moore: using moore grid or not
|
|
17
|
+
energy: initial energy
|
|
18
|
+
p_reproduce: probability of reproduction
|
|
19
|
+
energy_from_food: energy gained from 1 unit of food
|
|
20
|
+
"""
|
|
21
|
+
super().__init__(model)
|
|
19
22
|
self.energy = energy
|
|
20
23
|
self.p_reproduce = p_reproduce
|
|
21
24
|
self.energy_from_food = energy_from_food
|
|
22
25
|
self.moore = moore
|
|
23
26
|
|
|
24
27
|
def random_move(self):
|
|
28
|
+
"""Move to random neighboring cell."""
|
|
25
29
|
next_moves = self.model.grid.get_neighborhood(self.pos, self.moore, True)
|
|
26
30
|
next_move = self.random.choice(next_moves)
|
|
27
31
|
# Now move:
|
|
28
32
|
self.model.grid.move_agent(self, next_move)
|
|
29
33
|
|
|
30
34
|
def spawn_offspring(self):
|
|
35
|
+
"""Create offspring."""
|
|
31
36
|
self.energy /= 2
|
|
32
37
|
offspring = self.__class__(
|
|
33
|
-
self.model.next_id(),
|
|
34
38
|
self.model,
|
|
35
39
|
self.moore,
|
|
36
40
|
self.energy,
|
|
@@ -39,13 +43,15 @@ class Animal(mesa.Agent):
|
|
|
39
43
|
)
|
|
40
44
|
self.model.grid.place_agent(offspring, self.pos)
|
|
41
45
|
|
|
42
|
-
def feed(self): ...
|
|
46
|
+
def feed(self): ... # noqa: D102
|
|
43
47
|
|
|
44
48
|
def die(self):
|
|
49
|
+
"""Die."""
|
|
45
50
|
self.model.grid.remove_agent(self)
|
|
46
51
|
self.remove()
|
|
47
52
|
|
|
48
53
|
def step(self):
|
|
54
|
+
"""Execute one step of the agent."""
|
|
49
55
|
self.random_move()
|
|
50
56
|
self.energy -= 1
|
|
51
57
|
|
|
@@ -58,13 +64,10 @@ class Animal(mesa.Agent):
|
|
|
58
64
|
|
|
59
65
|
|
|
60
66
|
class Sheep(Animal):
|
|
61
|
-
"""
|
|
62
|
-
A sheep that walks around, reproduces (asexually) and gets eaten.
|
|
63
|
-
|
|
64
|
-
The init is the same as the RandomWalker.
|
|
65
|
-
"""
|
|
67
|
+
"""A sheep that walks around, reproduces (asexually) and gets eaten."""
|
|
66
68
|
|
|
67
69
|
def feed(self):
|
|
70
|
+
"""Eat grass and gain energy."""
|
|
68
71
|
# If there is grass available, eat it
|
|
69
72
|
agents = self.model.grid.get_cell_list_contents(self.pos)
|
|
70
73
|
grass_patch = next(obj for obj in agents if isinstance(obj, GrassPatch))
|
|
@@ -74,11 +77,10 @@ class Sheep(Animal):
|
|
|
74
77
|
|
|
75
78
|
|
|
76
79
|
class Wolf(Animal):
|
|
77
|
-
"""
|
|
78
|
-
A wolf that walks around, reproduces (asexually) and eats sheep.
|
|
79
|
-
"""
|
|
80
|
+
"""A wolf that walks around, reproduces (asexually) and eats sheep."""
|
|
80
81
|
|
|
81
82
|
def feed(self):
|
|
83
|
+
"""Eat wolf and gain energy."""
|
|
82
84
|
agents = self.model.grid.get_cell_list_contents(self.pos)
|
|
83
85
|
sheep = [obj for obj in agents if isinstance(obj, Sheep)]
|
|
84
86
|
if len(sheep) > 0:
|
|
@@ -89,13 +91,11 @@ class Wolf(Animal):
|
|
|
89
91
|
sheep_to_eat.die()
|
|
90
92
|
|
|
91
93
|
|
|
92
|
-
class GrassPatch(
|
|
93
|
-
"""
|
|
94
|
-
A patch of grass that grows at a fixed rate and it is eaten by sheep
|
|
95
|
-
"""
|
|
94
|
+
class GrassPatch(FixedAgent):
|
|
95
|
+
"""A patch of grass that grows at a fixed rate and it is eaten by sheep."""
|
|
96
96
|
|
|
97
97
|
@property
|
|
98
|
-
def fully_grown(self) -> bool:
|
|
98
|
+
def fully_grown(self) -> bool: # noqa: D102
|
|
99
99
|
return self._fully_grown
|
|
100
100
|
|
|
101
101
|
@fully_grown.setter
|
|
@@ -109,15 +109,16 @@ class GrassPatch(mesa.Agent):
|
|
|
109
109
|
function_args=[self, "fully_grown", True],
|
|
110
110
|
)
|
|
111
111
|
|
|
112
|
-
def __init__(self,
|
|
113
|
-
"""
|
|
114
|
-
Creates a new patch of grass
|
|
112
|
+
def __init__(self, model, fully_grown, countdown, grass_regrowth_time):
|
|
113
|
+
"""Creates a new patch of grass.
|
|
115
114
|
|
|
116
115
|
Args:
|
|
117
|
-
|
|
116
|
+
model: a model instance
|
|
117
|
+
fully_grown: (boolean) Whether the patch of grass is fully grown or not
|
|
118
118
|
countdown: Time for the patch of grass to be fully grown again
|
|
119
|
+
grass_regrowth_time: regrowth time for the grass
|
|
119
120
|
"""
|
|
120
|
-
super().__init__(
|
|
121
|
+
super().__init__(model)
|
|
121
122
|
self._fully_grown = fully_grown
|
|
122
123
|
self.grass_regrowth_time = grass_regrowth_time
|
|
123
124
|
|
|
@@ -126,13 +127,12 @@ class GrassPatch(mesa.Agent):
|
|
|
126
127
|
setattr, countdown, function_args=[self, "fully_grown", True]
|
|
127
128
|
)
|
|
128
129
|
|
|
129
|
-
def set_fully_grown(self):
|
|
130
|
+
def set_fully_grown(self): # noqa
|
|
130
131
|
self.fully_grown = True
|
|
131
132
|
|
|
132
133
|
|
|
133
134
|
class WolfSheep(mesa.Model):
|
|
134
|
-
"""
|
|
135
|
-
Wolf-Sheep Predation Model
|
|
135
|
+
"""Wolf-Sheep Predation Model.
|
|
136
136
|
|
|
137
137
|
A model for simulating wolf and sheep (predator-prey) ecosystem modelling.
|
|
138
138
|
"""
|
|
@@ -152,10 +152,11 @@ class WolfSheep(mesa.Model):
|
|
|
152
152
|
simulator=None,
|
|
153
153
|
seed=None,
|
|
154
154
|
):
|
|
155
|
-
"""
|
|
156
|
-
Create a new Wolf-Sheep model with the given parameters.
|
|
155
|
+
"""Create a new Wolf-Sheep model with the given parameters.
|
|
157
156
|
|
|
158
157
|
Args:
|
|
158
|
+
height: height of the grid
|
|
159
|
+
width: width of the grid
|
|
159
160
|
initial_sheep: Number of sheep to start with
|
|
160
161
|
initial_wolves: Number of wolves to start with
|
|
161
162
|
sheep_reproduce: Probability of each sheep reproducing each step
|
|
@@ -165,7 +166,9 @@ class WolfSheep(mesa.Model):
|
|
|
165
166
|
grass_regrowth_time: How long it takes for a grass patch to regrow
|
|
166
167
|
once it is eaten
|
|
167
168
|
sheep_gain_from_food: Energy sheep gain from grass, if enabled.
|
|
168
|
-
moore:
|
|
169
|
+
moore: whether to use moore or von Neumann grid
|
|
170
|
+
simulator: Simulator to use for simulating wolf and sheep
|
|
171
|
+
seed: Random seed
|
|
169
172
|
"""
|
|
170
173
|
super().__init__(seed=seed)
|
|
171
174
|
# Set parameters
|
|
@@ -191,7 +194,6 @@ class WolfSheep(mesa.Model):
|
|
|
191
194
|
)
|
|
192
195
|
energy = self.random.randrange(2 * sheep_gain_from_food)
|
|
193
196
|
sheep = Sheep(
|
|
194
|
-
self.next_id(),
|
|
195
197
|
self,
|
|
196
198
|
moore,
|
|
197
199
|
energy,
|
|
@@ -208,7 +210,6 @@ class WolfSheep(mesa.Model):
|
|
|
208
210
|
)
|
|
209
211
|
energy = self.random.randrange(2 * wolf_gain_from_food)
|
|
210
212
|
wolf = Wolf(
|
|
211
|
-
self.next_id(),
|
|
212
213
|
self,
|
|
213
214
|
moore,
|
|
214
215
|
energy,
|
|
@@ -225,14 +226,13 @@ class WolfSheep(mesa.Model):
|
|
|
225
226
|
countdown = grass_regrowth_time
|
|
226
227
|
else:
|
|
227
228
|
countdown = self.random.randrange(grass_regrowth_time)
|
|
228
|
-
patch = GrassPatch(
|
|
229
|
-
self.next_id(), self, fully_grown, countdown, grass_regrowth_time
|
|
230
|
-
)
|
|
229
|
+
patch = GrassPatch(self, fully_grown, countdown, grass_regrowth_time)
|
|
231
230
|
self.grid.place_agent(patch, pos)
|
|
232
231
|
|
|
233
232
|
def step(self):
|
|
234
|
-
|
|
235
|
-
self.
|
|
233
|
+
"""Perform one step of the model."""
|
|
234
|
+
self.agents_by_type[Sheep].shuffle_do("step")
|
|
235
|
+
self.agents_by_type[Wolf].shuffle_do("step")
|
|
236
236
|
|
|
237
237
|
|
|
238
238
|
if __name__ == "__main__":
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
"""Provides several simulator classes.
|
|
2
|
+
|
|
3
|
+
A Simulator is responsible for executing a simulation model. It controls time advancement and enables event scheduling.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
1
8
|
from __future__ import annotations
|
|
2
9
|
|
|
3
10
|
import numbers
|
|
4
|
-
from
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from typing import Any
|
|
5
13
|
|
|
6
14
|
from mesa import Model
|
|
7
15
|
|
|
@@ -26,6 +34,12 @@ class Simulator:
|
|
|
26
34
|
# TODO: add experimentation support
|
|
27
35
|
|
|
28
36
|
def __init__(self, time_unit: type, start_time: int | float):
|
|
37
|
+
"""Initialize a Simulator instance.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
time_unit: type of the smulaiton time
|
|
41
|
+
start_time: the starttime of the simulator
|
|
42
|
+
"""
|
|
29
43
|
# should model run in a separate thread,
|
|
30
44
|
# and we can then interact with start, stop, run_until, and step?
|
|
31
45
|
self.event_list = EventList()
|
|
@@ -35,10 +49,10 @@ class Simulator:
|
|
|
35
49
|
self.time = self.start_time
|
|
36
50
|
self.model = None
|
|
37
51
|
|
|
38
|
-
def check_time_unit(self, time: int | float) -> bool: ...
|
|
52
|
+
def check_time_unit(self, time: int | float) -> bool: ... # noqa: D102
|
|
39
53
|
|
|
40
54
|
def setup(self, model: Model) -> None:
|
|
41
|
-
"""Set up the simulator with the model to simulate
|
|
55
|
+
"""Set up the simulator with the model to simulate.
|
|
42
56
|
|
|
43
57
|
Args:
|
|
44
58
|
model (Model): The model to simulate
|
|
@@ -48,12 +62,13 @@ class Simulator:
|
|
|
48
62
|
self.model = model
|
|
49
63
|
|
|
50
64
|
def reset(self):
|
|
51
|
-
"""Reset the simulator by clearing the event list and removing the model to simulate"""
|
|
65
|
+
"""Reset the simulator by clearing the event list and removing the model to simulate."""
|
|
52
66
|
self.event_list.clear()
|
|
53
67
|
self.model = None
|
|
54
68
|
self.time = self.start_time
|
|
55
69
|
|
|
56
70
|
def run_until(self, end_time: int | float) -> None:
|
|
71
|
+
"""Run the simulator until the end time."""
|
|
57
72
|
while True:
|
|
58
73
|
try:
|
|
59
74
|
event = self.event_list.pop_event()
|
|
@@ -70,7 +85,7 @@ class Simulator:
|
|
|
70
85
|
break
|
|
71
86
|
|
|
72
87
|
def run_for(self, time_delta: int | float):
|
|
73
|
-
"""
|
|
88
|
+
"""Run the simulator for the specified time delta.
|
|
74
89
|
|
|
75
90
|
Args:
|
|
76
91
|
time_delta (float| int): The time delta. The simulator is run from the current time to the current time
|
|
@@ -87,7 +102,7 @@ class Simulator:
|
|
|
87
102
|
function_args: list[Any] | None = None,
|
|
88
103
|
function_kwargs: dict[str, Any] | None = None,
|
|
89
104
|
) -> SimulationEvent:
|
|
90
|
-
"""Schedule event for the current time instant
|
|
105
|
+
"""Schedule event for the current time instant.
|
|
91
106
|
|
|
92
107
|
Args:
|
|
93
108
|
function (Callable): The callable to execute for this event
|
|
@@ -115,7 +130,7 @@ class Simulator:
|
|
|
115
130
|
function_args: list[Any] | None = None,
|
|
116
131
|
function_kwargs: dict[str, Any] | None = None,
|
|
117
132
|
) -> SimulationEvent:
|
|
118
|
-
"""Schedule event for the specified time instant
|
|
133
|
+
"""Schedule event for the specified time instant.
|
|
119
134
|
|
|
120
135
|
Args:
|
|
121
136
|
function (Callable): The callable to execute for this event
|
|
@@ -149,7 +164,7 @@ class Simulator:
|
|
|
149
164
|
function_args: list[Any] | None = None,
|
|
150
165
|
function_kwargs: dict[str, Any] | None = None,
|
|
151
166
|
) -> SimulationEvent:
|
|
152
|
-
"""Schedule event for the current time plus the time delta
|
|
167
|
+
"""Schedule event for the current time plus the time delta.
|
|
153
168
|
|
|
154
169
|
Args:
|
|
155
170
|
function (Callable): The callable to execute for this event
|
|
@@ -173,13 +188,12 @@ class Simulator:
|
|
|
173
188
|
return event
|
|
174
189
|
|
|
175
190
|
def cancel_event(self, event: SimulationEvent) -> None:
|
|
176
|
-
"""
|
|
191
|
+
"""Remove the event from the event list.
|
|
177
192
|
|
|
178
193
|
Args:
|
|
179
194
|
event (SimulationEvent): The simulation event to remove
|
|
180
195
|
|
|
181
196
|
"""
|
|
182
|
-
|
|
183
197
|
self.event_list.remove(event)
|
|
184
198
|
|
|
185
199
|
def _schedule_event(self, event: SimulationEvent):
|
|
@@ -203,13 +217,29 @@ class ABMSimulator(Simulator):
|
|
|
203
217
|
"""
|
|
204
218
|
|
|
205
219
|
def __init__(self):
|
|
220
|
+
"""Initialize a ABM simulator."""
|
|
206
221
|
super().__init__(int, 0)
|
|
207
222
|
|
|
208
223
|
def setup(self, model):
|
|
224
|
+
"""Set up the simulator with the model to simulate.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
model (Model): The model to simulate
|
|
228
|
+
|
|
229
|
+
"""
|
|
209
230
|
super().setup(model)
|
|
210
231
|
self.schedule_event_now(self.model.step, priority=Priority.HIGH)
|
|
211
232
|
|
|
212
233
|
def check_time_unit(self, time) -> bool:
|
|
234
|
+
"""Check whether the time is of the correct unit.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
time (int | float): the time
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
bool: whether the time is of the correct unit
|
|
241
|
+
|
|
242
|
+
"""
|
|
213
243
|
if isinstance(time, int):
|
|
214
244
|
return True
|
|
215
245
|
if isinstance(time, float):
|
|
@@ -224,9 +254,9 @@ class ABMSimulator(Simulator):
|
|
|
224
254
|
function_args: list[Any] | None = None,
|
|
225
255
|
function_kwargs: dict[str, Any] | None = None,
|
|
226
256
|
) -> SimulationEvent:
|
|
227
|
-
"""Schedule a SimulationEvent for the next tick
|
|
257
|
+
"""Schedule a SimulationEvent for the next tick.
|
|
228
258
|
|
|
229
|
-
Args
|
|
259
|
+
Args:
|
|
230
260
|
function (Callable): the callable to execute
|
|
231
261
|
priority (Priority): the priority of the event
|
|
232
262
|
function_args (List[Any]): List of arguments to pass to the callable
|
|
@@ -242,7 +272,7 @@ class ABMSimulator(Simulator):
|
|
|
242
272
|
)
|
|
243
273
|
|
|
244
274
|
def run_until(self, end_time: int) -> None:
|
|
245
|
-
"""
|
|
275
|
+
"""Run the simulator up to and included the specified end time.
|
|
246
276
|
|
|
247
277
|
Args:
|
|
248
278
|
end_time (float| int): The end_time delta. The simulator is until the specified end time
|
|
@@ -269,7 +299,7 @@ class ABMSimulator(Simulator):
|
|
|
269
299
|
break
|
|
270
300
|
|
|
271
301
|
def run_for(self, time_delta: int):
|
|
272
|
-
"""
|
|
302
|
+
"""Run the simulator for the specified time delta.
|
|
273
303
|
|
|
274
304
|
Args:
|
|
275
305
|
time_delta (float| int): The time delta. The simulator is run from the current time to the current time
|
|
@@ -281,13 +311,24 @@ class ABMSimulator(Simulator):
|
|
|
281
311
|
|
|
282
312
|
|
|
283
313
|
class DEVSimulator(Simulator):
|
|
284
|
-
"""A simulator where the unit of time is a float.
|
|
285
|
-
|
|
314
|
+
"""A simulator where the unit of time is a float.
|
|
315
|
+
|
|
316
|
+
Can be used for full-blown discrete event simulating using event scheduling.
|
|
286
317
|
|
|
287
318
|
"""
|
|
288
319
|
|
|
289
320
|
def __init__(self):
|
|
321
|
+
"""Initialize a DEVS simulator."""
|
|
290
322
|
super().__init__(float, 0.0)
|
|
291
323
|
|
|
292
324
|
def check_time_unit(self, time) -> bool:
|
|
325
|
+
"""Check whether the time is of the correct unit.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
time (float): the time
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
bool: whether the time is of the correct unit
|
|
332
|
+
|
|
333
|
+
"""
|
|
293
334
|
return isinstance(time, numbers.Number)
|