Mesa 3.0.0a3__py3-none-any.whl → 3.0.0a5__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 +2 -3
- mesa/agent.py +193 -75
- mesa/batchrunner.py +18 -23
- mesa/cookiecutter-mesa/hooks/post_gen_project.py +2 -0
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py +1 -0
- mesa/datacollection.py +138 -27
- mesa/experimental/UserParam.py +67 -0
- mesa/experimental/__init__.py +5 -1
- mesa/experimental/cell_space/__init__.py +7 -0
- mesa/experimental/cell_space/cell.py +61 -20
- mesa/experimental/cell_space/cell_agent.py +12 -7
- mesa/experimental/cell_space/cell_collection.py +54 -17
- mesa/experimental/cell_space/discrete_space.py +16 -5
- mesa/experimental/cell_space/grid.py +19 -8
- mesa/experimental/cell_space/network.py +9 -7
- mesa/experimental/cell_space/voronoi.py +26 -33
- mesa/experimental/components/altair.py +81 -0
- mesa/experimental/components/matplotlib.py +242 -0
- mesa/experimental/devs/__init__.py +2 -0
- mesa/experimental/devs/eventlist.py +36 -15
- mesa/experimental/devs/examples/epstein_civil_violence.py +71 -39
- mesa/experimental/devs/examples/wolf_sheep.py +43 -44
- mesa/experimental/devs/simulator.py +55 -15
- mesa/experimental/solara_viz.py +453 -0
- mesa/main.py +6 -4
- mesa/model.py +64 -61
- mesa/space.py +154 -123
- mesa/time.py +57 -67
- mesa/visualization/UserParam.py +19 -6
- mesa/visualization/__init__.py +14 -2
- mesa/visualization/components/altair.py +18 -1
- mesa/visualization/components/matplotlib.py +26 -2
- mesa/visualization/solara_viz.py +231 -225
- mesa/visualization/utils.py +9 -0
- {mesa-3.0.0a3.dist-info → mesa-3.0.0a5.dist-info}/METADATA +2 -1
- mesa-3.0.0a5.dist-info/RECORD +44 -0
- mesa-3.0.0a3.dist-info/RECORD +0 -39
- {mesa-3.0.0a3.dist-info → mesa-3.0.0a5.dist-info}/WHEEL +0 -0
- {mesa-3.0.0a3.dist-info → mesa-3.0.0a5.dist-info}/entry_points.txt +0 -0
- {mesa-3.0.0a3.dist-info → mesa-3.0.0a5.dist-info}/licenses/LICENSE +0 -0
mesa/model.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
The model class for Mesa framework.
|
|
1
|
+
"""The model class for Mesa framework.
|
|
3
2
|
|
|
4
3
|
Core Objects: Model
|
|
5
4
|
"""
|
|
@@ -28,23 +27,8 @@ class Model:
|
|
|
28
27
|
Attributes:
|
|
29
28
|
running: A boolean indicating if the model should continue running.
|
|
30
29
|
schedule: An object to manage the order and execution of agent steps.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Properties:
|
|
34
|
-
agents: An AgentSet containing all agents in the model
|
|
35
|
-
agent_types: A list of different agent types present in the model.
|
|
36
|
-
steps: An integer representing the number of steps the model has taken.
|
|
37
|
-
It increases automatically at the start of each step() call.
|
|
38
|
-
|
|
39
|
-
Methods:
|
|
40
|
-
get_agents_of_type: Returns an AgentSet of agents of the specified type.
|
|
41
|
-
run_model: Runs the model's simulation until a defined end condition is reached.
|
|
42
|
-
step: Executes a single step of the model's simulation process.
|
|
43
|
-
next_id: Generates and returns the next unique identifier for an agent.
|
|
44
|
-
reset_randomizer: Resets the model's random number generator with a new or existing seed.
|
|
45
|
-
initialize_data_collector: Sets up the data collector for the model, requiring an initialized scheduler and agents.
|
|
46
|
-
register_agent : register an agent with the model
|
|
47
|
-
deregister_agent : remove an agent from the model
|
|
30
|
+
steps: the number of times `model.step()` has been called.
|
|
31
|
+
random: a seeded random number generator.
|
|
48
32
|
|
|
49
33
|
Notes:
|
|
50
34
|
Model.agents returns the AgentSet containing all agents registered with the model. Changing
|
|
@@ -53,30 +37,30 @@ class Model:
|
|
|
53
37
|
|
|
54
38
|
"""
|
|
55
39
|
|
|
56
|
-
def
|
|
57
|
-
"""Create a new model
|
|
58
|
-
obj = object.__new__(cls)
|
|
59
|
-
obj._seed = kwargs.get("seed")
|
|
60
|
-
if obj._seed is None:
|
|
61
|
-
# We explicitly specify the seed here so that we know its value in
|
|
62
|
-
# advance.
|
|
63
|
-
obj._seed = random.random()
|
|
64
|
-
obj.random = random.Random(obj._seed)
|
|
65
|
-
return obj
|
|
66
|
-
|
|
67
|
-
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
68
|
-
"""Create a new model. Overload this method with the actual code to
|
|
69
|
-
start the model. Always start with super().__init__() to initialize the
|
|
70
|
-
model object properly.
|
|
71
|
-
"""
|
|
40
|
+
def __init__(self, *args: Any, seed: float | None = None, **kwargs: Any) -> None:
|
|
41
|
+
"""Create a new model.
|
|
72
42
|
|
|
43
|
+
Overload this method with the actual code to initialize the model. Always start with super().__init__()
|
|
44
|
+
to initialize the model object properly.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
args: arguments to pass onto super
|
|
48
|
+
seed: the seed for the random number generator
|
|
49
|
+
kwargs: keyword arguments to pass onto super
|
|
50
|
+
"""
|
|
73
51
|
self.running = True
|
|
74
52
|
self.schedule = None
|
|
75
|
-
self.current_id = 0
|
|
76
53
|
self.steps: int = 0
|
|
77
54
|
|
|
78
55
|
self._setup_agent_registration()
|
|
79
56
|
|
|
57
|
+
self._seed = seed
|
|
58
|
+
if self._seed is None:
|
|
59
|
+
# We explicitly specify the seed here so that we know its value in
|
|
60
|
+
# advance.
|
|
61
|
+
self._seed = random.random()
|
|
62
|
+
self.random = random.Random(self._seed)
|
|
63
|
+
|
|
80
64
|
# Wrap the user-defined step method
|
|
81
65
|
self._user_step = self.step
|
|
82
66
|
self.step = self._wrapped_step
|
|
@@ -88,6 +72,14 @@ class Model:
|
|
|
88
72
|
# Call the original user-defined step method
|
|
89
73
|
self._user_step(*args, **kwargs)
|
|
90
74
|
|
|
75
|
+
def next_id(self) -> int: # noqa: D102
|
|
76
|
+
warnings.warn(
|
|
77
|
+
"using model.next_id() is deprecated. Agents track their unique ID automatically",
|
|
78
|
+
DeprecationWarning,
|
|
79
|
+
stacklevel=2,
|
|
80
|
+
)
|
|
81
|
+
return 0
|
|
82
|
+
|
|
91
83
|
@property
|
|
92
84
|
def agents(self) -> AgentSet:
|
|
93
85
|
"""Provides an AgentSet of all agents in the model, combining agents from all types."""
|
|
@@ -106,29 +98,31 @@ class Model:
|
|
|
106
98
|
"""Return a list of all unique agent types registered with the model."""
|
|
107
99
|
return list(self._agents_by_type.keys())
|
|
108
100
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
agenttype: The type of agent to retrieve.
|
|
114
|
-
|
|
115
|
-
Raises:
|
|
116
|
-
KeyError: If agenttype does not exist
|
|
117
|
-
|
|
101
|
+
@property
|
|
102
|
+
def agents_by_type(self) -> dict[type[Agent], AgentSet]:
|
|
103
|
+
"""A dictionary where the keys are agent types and the values are the corresponding AgentSets."""
|
|
104
|
+
return self._agents_by_type
|
|
118
105
|
|
|
119
|
-
|
|
120
|
-
|
|
106
|
+
def get_agents_of_type(self, agenttype: type[Agent]) -> AgentSet:
|
|
107
|
+
"""Deprecated: Retrieves an AgentSet containing all agents of the specified type."""
|
|
108
|
+
warnings.warn(
|
|
109
|
+
f"Model.get_agents_of_type() is deprecated, please replace get_agents_of_type({agenttype})"
|
|
110
|
+
f"with the property agents_by_type[{agenttype}].",
|
|
111
|
+
DeprecationWarning,
|
|
112
|
+
stacklevel=2,
|
|
113
|
+
)
|
|
114
|
+
return self.agents_by_type[agenttype]
|
|
121
115
|
|
|
122
116
|
def _setup_agent_registration(self):
|
|
123
|
-
"""
|
|
117
|
+
"""Helper method to initialize the agent registration datastructures."""
|
|
124
118
|
self._agents = {} # the hard references to all agents in the model
|
|
125
119
|
self._agents_by_type: dict[
|
|
126
|
-
type, AgentSet
|
|
120
|
+
type[Agent], AgentSet
|
|
127
121
|
] = {} # a dict with an agentset for each class of agents
|
|
128
122
|
self._all_agents = AgentSet([], self) # an agenset with all agents
|
|
129
123
|
|
|
130
124
|
def register_agent(self, agent):
|
|
131
|
-
"""Register the agent with the model
|
|
125
|
+
"""Register the agent with the model.
|
|
132
126
|
|
|
133
127
|
Args:
|
|
134
128
|
agent: The agent to register.
|
|
@@ -165,10 +159,13 @@ class Model:
|
|
|
165
159
|
self._all_agents.add(agent)
|
|
166
160
|
|
|
167
161
|
def deregister_agent(self, agent):
|
|
168
|
-
"""Deregister the agent with the model
|
|
162
|
+
"""Deregister the agent with the model.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
agent: The agent to deregister.
|
|
169
166
|
|
|
170
|
-
Notes
|
|
171
|
-
|
|
167
|
+
Notes:
|
|
168
|
+
This method is called automatically by ``Agent.remove``
|
|
172
169
|
|
|
173
170
|
"""
|
|
174
171
|
del self._agents[agent]
|
|
@@ -176,8 +173,9 @@ class Model:
|
|
|
176
173
|
self._all_agents.remove(agent)
|
|
177
174
|
|
|
178
175
|
def run_model(self) -> None:
|
|
179
|
-
"""Run the model until the end condition is reached.
|
|
180
|
-
|
|
176
|
+
"""Run the model until the end condition is reached.
|
|
177
|
+
|
|
178
|
+
Overload as needed.
|
|
181
179
|
"""
|
|
182
180
|
while self.running:
|
|
183
181
|
self.step()
|
|
@@ -185,18 +183,12 @@ class Model:
|
|
|
185
183
|
def step(self) -> None:
|
|
186
184
|
"""A single step. Fill in here."""
|
|
187
185
|
|
|
188
|
-
def next_id(self) -> int:
|
|
189
|
-
"""Return the next unique ID for agents, increment current_id"""
|
|
190
|
-
self.current_id += 1
|
|
191
|
-
return self.current_id
|
|
192
|
-
|
|
193
186
|
def reset_randomizer(self, seed: int | None = None) -> None:
|
|
194
187
|
"""Reset the model random number generator.
|
|
195
188
|
|
|
196
189
|
Args:
|
|
197
190
|
seed: A new seed for the RNG; if None, reset using the current seed
|
|
198
191
|
"""
|
|
199
|
-
|
|
200
192
|
if seed is None:
|
|
201
193
|
seed = self._seed
|
|
202
194
|
self.random.seed(seed)
|
|
@@ -206,8 +198,18 @@ class Model:
|
|
|
206
198
|
self,
|
|
207
199
|
model_reporters=None,
|
|
208
200
|
agent_reporters=None,
|
|
201
|
+
agenttype_reporters=None,
|
|
209
202
|
tables=None,
|
|
210
203
|
) -> None:
|
|
204
|
+
"""Initialize the data collector for the model.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
model_reporters: model reporters to collect
|
|
208
|
+
agent_reporters: agent reporters to collect
|
|
209
|
+
agenttype_reporters: agent type reporters to collect
|
|
210
|
+
tables: tables to collect
|
|
211
|
+
|
|
212
|
+
"""
|
|
211
213
|
if not hasattr(self, "schedule") or self.schedule is None:
|
|
212
214
|
raise RuntimeError(
|
|
213
215
|
"You must initialize the scheduler (self.schedule) before initializing the data collector."
|
|
@@ -219,6 +221,7 @@ class Model:
|
|
|
219
221
|
self.datacollector = DataCollector(
|
|
220
222
|
model_reporters=model_reporters,
|
|
221
223
|
agent_reporters=agent_reporters,
|
|
224
|
+
agenttype_reporters=agenttype_reporters,
|
|
222
225
|
tables=tables,
|
|
223
226
|
)
|
|
224
227
|
# Collect data for the first time during initialization.
|