Mesa 3.1.2__tar.gz → 3.1.3__tar.gz
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-3.1.2 → mesa-3.1.3}/.pre-commit-config.yaml +2 -2
- {mesa-3.1.2 → mesa-3.1.3}/CONTRIBUTING.md +2 -0
- {mesa-3.1.2 → mesa-3.1.3}/HISTORY.md +54 -0
- {mesa-3.1.2 → mesa-3.1.3}/PKG-INFO +2 -1
- {mesa-3.1.2 → mesa-3.1.3}/benchmarks/configurations.py +7 -2
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/experimental.md +12 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/__init__.py +1 -1
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/agents.py +26 -38
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/app.py +6 -1
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/model.py +30 -37
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/__init__.py +2 -2
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/voronoi.py +1 -4
- mesa-3.1.3/mesa/experimental/continuous_space/__init__.py +8 -0
- mesa-3.1.3/mesa/experimental/continuous_space/continuous_space.py +273 -0
- mesa-3.1.3/mesa/experimental/continuous_space/continuous_space_agents.py +101 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/model.py +1 -1
- {mesa-3.1.2 → mesa-3.1.3}/mesa/space.py +7 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/mpl_space_drawing.py +22 -12
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/solara_viz.py +30 -7
- {mesa-3.1.2 → mesa-3.1.3}/pyproject.toml +1 -0
- mesa-3.1.3/tests/test_continuous_space.py +432 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_model.py +12 -0
- {mesa-3.1.2 → mesa-3.1.3}/.codespellignore +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.coveragerc +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/PULL_REQUEST_TEMPLATE/bug.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/dependabot.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/pull_request_template.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/release.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/workflows/benchmarks.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/workflows/build_lint.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.github/workflows/release.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.gitignore +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/.readthedocs.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/CITATION.bib +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/CODE_OF_CONDUCT.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/Dockerfile +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/LICENSE +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/NOTICE +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/README.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/benchmarks/compare_timings.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/benchmarks/global_benchmark.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/binder/environment.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/codecov.yaml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docker-compose.yml +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/Makefile +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/README.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/_static/switcher.json +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/agent.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/api_main.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/batchrunner.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/datacollection.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/mesa_logging.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/model.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/space.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/apis/visualization.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/best-practices.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/conf.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/example_template.txt +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/examples_overview_template.txt +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/getting_started.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/mesa_logo.ico +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/mesa_logo.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/br_ginis.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/dc_endwealth.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/dc_gini.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/dc_oneagent.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/first_hist.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/multirun_hist.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/numpy_grid.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_chart.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_empty.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_greycircles.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_histogram.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/tutorial/viz_redcircles.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/images/wolf_sheep.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/index.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/make.bat +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/mesa.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/migration_guide.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/MoneyModel.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_chart.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_empty.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_greycircles.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_histogram.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_redcircles.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/files/viz_slider.png +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/intro_tutorial.ipynb +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/docs/tutorials/visualization_tutorial.ipynb +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/maintenance/fetch_unlabeled_prs.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/agent.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/batchrunner.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/datacollection.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/README.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/Epstein Civil Violence.ipynb +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/epstein_civil_violence/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/analysis.ipynb +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/pd_grid/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/sugar-map.txt +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/sugarscape_g1mt/tests.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/advanced/wolf_sheep/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boid_flockers/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/boltzmann_wealth_model/st_app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/conways_game_of_life/st_app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/analysis.ipynb +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/schelling/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/Readme.md +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/agents.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/app.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/examples/basic/virus_on_network/model.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/cell.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/cell_agent.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/cell_collection.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/discrete_space.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/grid.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/network.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/cell_space/property_layer.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/devs/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/devs/eventlist.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/devs/simulator.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/mesa_signal.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/observable_collections.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/experimental/mesa_signals/signals_util.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/mesa_logging.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/components/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/components/altair_components.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/components/matplotlib_components.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/user_param.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mesa/visualization/utils.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/mypy.ini +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/__init__.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/read_requirements.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_agent.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_batch_run.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_cell_space.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_components_matplotlib.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_datacollector.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_devs.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_end_to_end_viz.sh +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_examples.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_grid.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_import_namespace.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_lifespan.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_mesa_logging.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_mesa_signals.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_solara_viz.py +0 -0
- {mesa-3.1.2 → mesa-3.1.3}/tests/test_space.py +0 -0
|
@@ -4,7 +4,7 @@ ci:
|
|
|
4
4
|
repos:
|
|
5
5
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
6
6
|
# Ruff version.
|
|
7
|
-
rev: v0.8.
|
|
7
|
+
rev: v0.8.6
|
|
8
8
|
hooks:
|
|
9
9
|
# Run the linter.
|
|
10
10
|
- id: ruff
|
|
@@ -14,7 +14,7 @@ repos:
|
|
|
14
14
|
- id: ruff-format
|
|
15
15
|
types_or: [ python, pyi, jupyter ]
|
|
16
16
|
- repo: https://github.com/asottile/pyupgrade
|
|
17
|
-
rev: v3.19.
|
|
17
|
+
rev: v3.19.1
|
|
18
18
|
hooks:
|
|
19
19
|
- id: pyupgrade
|
|
20
20
|
args: [--py311-plus]
|
|
@@ -137,6 +137,8 @@ To create a new release, follow these steps:
|
|
|
137
137
|
9. The [`release.yml`](https://github.com/projectmesa/mesa/blob/main/.github/workflows/release.yml) CI workflow should automatically create and upload the package to PyPI. Verify this on [PyPI.org](https://pypi.org/project/mesa/).
|
|
138
138
|
10. Finally, after release, open a new PR to update the version number in [`mesa/__init__.py`](https://github.com/projectmesa/mesa/blob/main/mesa/__init__.py) for the next release (e.g., `"3.1.0.dev"`).
|
|
139
139
|
|
|
140
|
+
A recorded video of this process is [available here](https://youtu.be/JE44jkegmns).
|
|
141
|
+
|
|
140
142
|
## Special Thanks
|
|
141
143
|
|
|
142
144
|
A special thanks to the following projects who offered inspiration for this contributing file.
|
|
@@ -1,6 +1,60 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Release History
|
|
3
3
|
---
|
|
4
|
+
# 3.1.3 (2025-01-11)
|
|
5
|
+
## Highlights
|
|
6
|
+
Mesa 3.1.3 introduces a major experimental reimplementation of Mesa's continuous space, providing an intuitive agent-centric API and significant performance improvements. The new implementation supports n-dimensional spaces and offers streamlined methods for agent movement and neighbor calculations.
|
|
7
|
+
|
|
8
|
+
### New Continuous Space Features
|
|
9
|
+
- Agent-centric movement API similar to cell spaces
|
|
10
|
+
- Efficient neighbor calculations and position updates
|
|
11
|
+
- Support for n-dimensional spaces
|
|
12
|
+
- Improved memory management with dynamic array resizing
|
|
13
|
+
|
|
14
|
+
Here's a quick look at the new API:
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
# Create a 2D continuous space
|
|
18
|
+
space = ContinuousSpace(
|
|
19
|
+
dimensions=[[0, 1], [0, 1]],
|
|
20
|
+
torus=True,
|
|
21
|
+
random=model.random
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Create and position an agent
|
|
25
|
+
agent = ContinuousSpaceAgent(space, model)
|
|
26
|
+
agent.position = [0.5, 0.5]
|
|
27
|
+
|
|
28
|
+
# Move agent using vector arithmetic
|
|
29
|
+
agent.position += [0.1, 0.1]
|
|
30
|
+
|
|
31
|
+
# Get neighbors within radius
|
|
32
|
+
neighbors, distances = agent.get_neighbors_in_radius(radius=0.2)
|
|
33
|
+
|
|
34
|
+
# Find k nearest neighbors
|
|
35
|
+
nearest, distances = agent.get_nearest_neighbors(k=5)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The new implementation particularly benefits models requiring frequent position updates and neighbor queries, such as flocking simulations or particle systems. See [#2584](https://github.com/projectmesa/mesa/pull/2584) for more details. We would love to get feedback on the new Continuous Space in [#2611](https://github.com/projectmesa/mesa/discussions/2611).
|
|
39
|
+
|
|
40
|
+
Other improvements in this release include consistent visualization behavior across space types with the reimplementation of `draw_voronoi` [#2608](https://github.com/projectmesa/mesa/pull/2608), and a new render interval slider for controlling visualization update frequency in SolaraViz, which helps improve performance when working with complex visualizations [#2596](https://github.com/projectmesa/mesa/pull/2596). We've also fixed a bug affecting random number generation determinism when using `Model(seed=something)`, ensuring both `model.random` and `model.rng` now behave consistently when seeded with the same initial value [#2598](https://github.com/projectmesa/mesa/pull/2598).
|
|
41
|
+
|
|
42
|
+
## What's Changed
|
|
43
|
+
### 🧪 Experimental features
|
|
44
|
+
* Reimplementation of Continuous Space by @quaquel in https://github.com/projectmesa/mesa/pull/2584
|
|
45
|
+
### 🛠 Enhancements made
|
|
46
|
+
* reimplementation of draw_voroinoi by @quaquel in https://github.com/projectmesa/mesa/pull/2608
|
|
47
|
+
* Add render interval slider to control visualization update frequency by @HMNS19 in https://github.com/projectmesa/mesa/pull/2596
|
|
48
|
+
### 🐛 Bugs fixed
|
|
49
|
+
* Bugfix for non deterministic rng behavior by @quaquel in https://github.com/projectmesa/mesa/pull/2598
|
|
50
|
+
### 🔍 Examples updated
|
|
51
|
+
* Clarify ContinuousSpace.get_neighbors behavior with multiple agents at same position by @quaquel in https://github.com/projectmesa/mesa/pull/2599
|
|
52
|
+
|
|
53
|
+
## New Contributors
|
|
54
|
+
* @HMNS19 made their first contribution in https://github.com/projectmesa/mesa/pull/2596
|
|
55
|
+
|
|
56
|
+
**Full Changelog**: https://github.com/projectmesa/mesa/compare/v3.1.2...v3.1.3
|
|
57
|
+
|
|
4
58
|
# 3.1.2 (2025-01-04)
|
|
5
59
|
## Highlights
|
|
6
60
|
Mesa v3.1.2 is a patch release containing updates to our wolf-sheep, shelling and prisoner's dilemma example models and improving documentation in the tutorials and visualisation docstring. No functional changes to the core library were made.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Mesa
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.3
|
|
4
4
|
Summary: Agent-based modeling (ABM) in Python
|
|
5
5
|
Project-URL: homepage, https://github.com/projectmesa/mesa
|
|
6
6
|
Project-URL: repository, https://github.com/projectmesa/mesa
|
|
@@ -24,6 +24,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Life
|
|
|
24
24
|
Requires-Python: >=3.11
|
|
25
25
|
Requires-Dist: numpy
|
|
26
26
|
Requires-Dist: pandas
|
|
27
|
+
Requires-Dist: scipy
|
|
27
28
|
Requires-Dist: tqdm
|
|
28
29
|
Provides-Extra: all
|
|
29
30
|
Requires-Dist: ipython; extra == 'all'
|
|
@@ -90,14 +90,19 @@ configurations = {
|
|
|
90
90
|
"seeds": 25,
|
|
91
91
|
"replications": 3,
|
|
92
92
|
"steps": 20,
|
|
93
|
-
"parameters": {
|
|
93
|
+
"parameters": {
|
|
94
|
+
"population_size": 200,
|
|
95
|
+
"width": 100,
|
|
96
|
+
"height": 100,
|
|
97
|
+
"vision": 5,
|
|
98
|
+
},
|
|
94
99
|
},
|
|
95
100
|
"large": {
|
|
96
101
|
"seeds": 10,
|
|
97
102
|
"replications": 3,
|
|
98
103
|
"steps": 10,
|
|
99
104
|
"parameters": {
|
|
100
|
-
"
|
|
105
|
+
"population_size": 400,
|
|
101
106
|
"width": 150,
|
|
102
107
|
"height": 150,
|
|
103
108
|
"vision": 15,
|
|
@@ -54,3 +54,15 @@ This namespace contains experimental features. These are under development, and
|
|
|
54
54
|
.. automodule:: experimental.devs.simulator
|
|
55
55
|
:members:
|
|
56
56
|
```
|
|
57
|
+
|
|
58
|
+
## Continuous Space
|
|
59
|
+
|
|
60
|
+
```{eval-rst}
|
|
61
|
+
.. automodule:: experimental.continuous_space.continuous_space
|
|
62
|
+
:members:
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```{eval-rst}
|
|
66
|
+
.. automodule:: experimental.continuous_space.continuous_space_agents
|
|
67
|
+
:members:
|
|
68
|
+
```
|
|
@@ -6,10 +6,10 @@ of flocking behavior.
|
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
9
|
-
from mesa import
|
|
9
|
+
from mesa.experimental.continuous_space import ContinuousSpaceAgent
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class Boid(
|
|
12
|
+
class Boid(ContinuousSpaceAgent):
|
|
13
13
|
"""A Boid-style flocker agent.
|
|
14
14
|
|
|
15
15
|
The agent follows three behaviors to flock:
|
|
@@ -26,10 +26,12 @@ class Boid(Agent):
|
|
|
26
26
|
def __init__(
|
|
27
27
|
self,
|
|
28
28
|
model,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
space,
|
|
30
|
+
position=(0, 0),
|
|
31
|
+
speed=1,
|
|
32
|
+
direction=(1, 1),
|
|
33
|
+
vision=1,
|
|
34
|
+
separation=1,
|
|
33
35
|
cohere=0.03,
|
|
34
36
|
separate=0.015,
|
|
35
37
|
match=0.05,
|
|
@@ -46,7 +48,8 @@ class Boid(Agent):
|
|
|
46
48
|
separate: Relative importance of avoiding close neighbors (default: 0.015)
|
|
47
49
|
match: Relative importance of matching neighbors' directions (default: 0.05)
|
|
48
50
|
"""
|
|
49
|
-
super().__init__(model)
|
|
51
|
+
super().__init__(space, model)
|
|
52
|
+
self.position = position
|
|
50
53
|
self.speed = speed
|
|
51
54
|
self.direction = direction
|
|
52
55
|
self.vision = vision
|
|
@@ -58,46 +61,31 @@ class Boid(Agent):
|
|
|
58
61
|
|
|
59
62
|
def step(self):
|
|
60
63
|
"""Get the Boid's neighbors, compute the new vector, and move accordingly."""
|
|
61
|
-
|
|
64
|
+
neighbors, distances = self.get_neighbors_in_radius(radius=self.vision)
|
|
65
|
+
self.neighbors = [n for n in neighbors if n is not self]
|
|
62
66
|
|
|
63
67
|
# If no neighbors, maintain current direction
|
|
64
|
-
if not
|
|
65
|
-
|
|
66
|
-
self.model.space.move_agent(self, new_pos)
|
|
68
|
+
if not neighbors:
|
|
69
|
+
self.position += self.direction * self.speed
|
|
67
70
|
return
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
cohere = np.zeros(2) # Cohesion vector
|
|
71
|
-
match_vector = np.zeros(2) # Alignment vector
|
|
72
|
-
separation_vector = np.zeros(2) # Separation vector
|
|
72
|
+
delta = self.space.calculate_difference_vector(self.position, agents=neighbors)
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# Separation - avoid getting too close
|
|
83
|
-
if distance < self.separation:
|
|
84
|
-
separation_vector -= heading
|
|
85
|
-
|
|
86
|
-
# Alignment - match neighbors' flying direction
|
|
87
|
-
match_vector += neighbor.direction
|
|
88
|
-
|
|
89
|
-
# Weight each behavior by its factor and normalize by number of neighbors
|
|
90
|
-
n = len(self.neighbors)
|
|
91
|
-
cohere = cohere * self.cohere_factor
|
|
92
|
-
separation_vector = separation_vector * self.separate_factor
|
|
93
|
-
match_vector = match_vector * self.match_factor
|
|
74
|
+
cohere_vector = delta.sum(axis=0) * self.cohere_factor
|
|
75
|
+
separation_vector = (
|
|
76
|
+
-1 * delta[distances < self.separation].sum(axis=0) * self.separate_factor
|
|
77
|
+
)
|
|
78
|
+
match_vector = (
|
|
79
|
+
np.asarray([n.direction for n in neighbors]).sum(axis=0) * self.match_factor
|
|
80
|
+
)
|
|
94
81
|
|
|
95
82
|
# Update direction based on the three behaviors
|
|
96
|
-
self.direction += (
|
|
83
|
+
self.direction += (cohere_vector + separation_vector + match_vector) / len(
|
|
84
|
+
neighbors
|
|
85
|
+
)
|
|
97
86
|
|
|
98
87
|
# Normalize direction vector
|
|
99
88
|
self.direction /= np.linalg.norm(self.direction)
|
|
100
89
|
|
|
101
90
|
# Move boid
|
|
102
|
-
|
|
103
|
-
self.model.space.move_agent(self, new_pos)
|
|
91
|
+
self.position += self.direction * self.speed
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
sys.path.insert(0, os.path.abspath("../../../.."))
|
|
5
|
+
|
|
1
6
|
from mesa.examples.basic.boid_flockers.model import BoidFlockers
|
|
2
7
|
from mesa.visualization import Slider, SolaraViz, make_space_component
|
|
3
8
|
|
|
@@ -17,7 +22,7 @@ model_params = {
|
|
|
17
22
|
"value": 42,
|
|
18
23
|
"label": "Random Seed",
|
|
19
24
|
},
|
|
20
|
-
"
|
|
25
|
+
"population_size": Slider(
|
|
21
26
|
label="Number of boids",
|
|
22
27
|
value=100,
|
|
23
28
|
min=10,
|
|
@@ -5,11 +5,17 @@ A Mesa implementation of Craig Reynolds's Boids flocker model.
|
|
|
5
5
|
Uses numpy arrays to represent vectors.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, os.path.abspath("../../../.."))
|
|
12
|
+
|
|
13
|
+
|
|
8
14
|
import numpy as np
|
|
9
15
|
|
|
10
16
|
from mesa import Model
|
|
11
17
|
from mesa.examples.basic.boid_flockers.agents import Boid
|
|
12
|
-
from mesa.
|
|
18
|
+
from mesa.experimental.continuous_space import ContinuousSpace
|
|
13
19
|
|
|
14
20
|
|
|
15
21
|
class BoidFlockers(Model):
|
|
@@ -17,7 +23,7 @@ class BoidFlockers(Model):
|
|
|
17
23
|
|
|
18
24
|
def __init__(
|
|
19
25
|
self,
|
|
20
|
-
|
|
26
|
+
population_size=100,
|
|
21
27
|
width=100,
|
|
22
28
|
height=100,
|
|
23
29
|
speed=1,
|
|
@@ -31,7 +37,7 @@ class BoidFlockers(Model):
|
|
|
31
37
|
"""Create a new Boids Flocking model.
|
|
32
38
|
|
|
33
39
|
Args:
|
|
34
|
-
|
|
40
|
+
population_size: Number of Boids in the simulation (default: 100)
|
|
35
41
|
width: Width of the space (default: 100)
|
|
36
42
|
height: Height of the space (default: 100)
|
|
37
43
|
speed: How fast the Boids move (default: 1)
|
|
@@ -44,48 +50,35 @@ class BoidFlockers(Model):
|
|
|
44
50
|
"""
|
|
45
51
|
super().__init__(seed=seed)
|
|
46
52
|
|
|
47
|
-
# Model Parameters
|
|
48
|
-
self.population = population
|
|
49
|
-
self.vision = vision
|
|
50
|
-
self.speed = speed
|
|
51
|
-
self.separation = separation
|
|
52
|
-
|
|
53
53
|
# Set up the space
|
|
54
|
-
self.space = ContinuousSpace(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
self.space = ContinuousSpace(
|
|
55
|
+
[[0, width], [0, height]],
|
|
56
|
+
torus=True,
|
|
57
|
+
random=self.random,
|
|
58
|
+
n_agents=population_size,
|
|
59
|
+
)
|
|
58
60
|
|
|
59
61
|
# Create and place the Boid agents
|
|
60
|
-
self.
|
|
62
|
+
positions = self.rng.random(size=(population_size, 2)) * self.space.size
|
|
63
|
+
directions = self.rng.uniform(-1, 1, size=(population_size, 2))
|
|
64
|
+
Boid.create_agents(
|
|
65
|
+
self,
|
|
66
|
+
population_size,
|
|
67
|
+
self.space,
|
|
68
|
+
position=positions,
|
|
69
|
+
direction=directions,
|
|
70
|
+
cohere=cohere,
|
|
71
|
+
separate=separate,
|
|
72
|
+
match=match,
|
|
73
|
+
speed=speed,
|
|
74
|
+
vision=vision,
|
|
75
|
+
separation=separation,
|
|
76
|
+
)
|
|
61
77
|
|
|
62
78
|
# For tracking statistics
|
|
63
79
|
self.average_heading = None
|
|
64
80
|
self.update_average_heading()
|
|
65
81
|
|
|
66
|
-
def make_agents(self):
|
|
67
|
-
"""Create and place all Boid agents randomly in the space."""
|
|
68
|
-
for _ in range(self.population):
|
|
69
|
-
# Random position
|
|
70
|
-
x = self.random.random() * self.space.x_max
|
|
71
|
-
y = self.random.random() * self.space.y_max
|
|
72
|
-
pos = np.array((x, y))
|
|
73
|
-
|
|
74
|
-
# Random initial direction
|
|
75
|
-
direction = np.random.random(2) * 2 - 1 # Random vector between -1 and 1
|
|
76
|
-
direction /= np.linalg.norm(direction) # Normalize
|
|
77
|
-
|
|
78
|
-
# Create and place the Boid
|
|
79
|
-
boid = Boid(
|
|
80
|
-
model=self,
|
|
81
|
-
speed=self.speed,
|
|
82
|
-
direction=direction,
|
|
83
|
-
vision=self.vision,
|
|
84
|
-
separation=self.separation,
|
|
85
|
-
**self.factors,
|
|
86
|
-
)
|
|
87
|
-
self.space.place_agent(boid, pos)
|
|
88
|
-
|
|
89
82
|
def update_average_heading(self):
|
|
90
83
|
"""Calculate the average heading (direction) of all Boids."""
|
|
91
84
|
if not self.agents:
|
|
@@ -15,6 +15,6 @@ Notes:
|
|
|
15
15
|
- Features graduate from experimental status once their APIs are stabilized
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
from mesa.experimental import cell_space, devs, mesa_signals
|
|
18
|
+
from mesa.experimental import cell_space, continuous_space, devs, mesa_signals
|
|
19
19
|
|
|
20
|
-
__all__ = ["cell_space", "devs", "mesa_signals"]
|
|
20
|
+
__all__ = ["cell_space", "continuous_space", "devs", "mesa_signals"]
|
|
@@ -186,7 +186,6 @@ class VoronoiGrid(DiscreteSpace):
|
|
|
186
186
|
random: Random | None = None,
|
|
187
187
|
cell_klass: type[Cell] = Cell,
|
|
188
188
|
capacity_function: callable = round_float,
|
|
189
|
-
cell_coloring_property: str | None = None,
|
|
190
189
|
) -> None:
|
|
191
190
|
"""A Voronoi Tessellation Grid.
|
|
192
191
|
|
|
@@ -200,7 +199,7 @@ class VoronoiGrid(DiscreteSpace):
|
|
|
200
199
|
random (Random): random number generator
|
|
201
200
|
cell_klass (type[Cell]): type of cell class
|
|
202
201
|
capacity_function (Callable): function to compute (int) capacity according to (float) area
|
|
203
|
-
|
|
202
|
+
|
|
204
203
|
"""
|
|
205
204
|
super().__init__(capacity=capacity, random=random, cell_klass=cell_klass)
|
|
206
205
|
self.centroids_coordinates = centroids_coordinates
|
|
@@ -215,7 +214,6 @@ class VoronoiGrid(DiscreteSpace):
|
|
|
215
214
|
self.triangulation = None
|
|
216
215
|
self.voronoi_coordinates = None
|
|
217
216
|
self.capacity_function = capacity_function
|
|
218
|
-
self.cell_coloring_property = cell_coloring_property
|
|
219
217
|
|
|
220
218
|
self._connect_cells()
|
|
221
219
|
self._build_cell_polygons()
|
|
@@ -266,4 +264,3 @@ class VoronoiGrid(DiscreteSpace):
|
|
|
266
264
|
polygon_area = self._compute_polygon_area(polygon)
|
|
267
265
|
self._cells[region].properties["area"] = polygon_area
|
|
268
266
|
self._cells[region].capacity = self.capacity_function(polygon_area)
|
|
269
|
-
self._cells[region].properties[self.cell_coloring_property] = 0
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Continuous space support."""
|
|
2
|
+
|
|
3
|
+
from mesa.experimental.continuous_space.continuous_space import ContinuousSpace
|
|
4
|
+
from mesa.experimental.continuous_space.continuous_space_agents import (
|
|
5
|
+
ContinuousSpaceAgent,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
__all__ = ["ContinuousSpace", "ContinuousSpaceAgent"]
|