Mesa 3.0.0b0__tar.gz → 3.0.0b1__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.0.0b0 → mesa-3.0.0b1}/.github/release.yml +3 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/workflows/benchmarks.yml +1 -1
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/workflows/build_lint.yml +7 -3
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/workflows/release.yml +2 -1
- {mesa-3.0.0b0 → mesa-3.0.0b1}/CONTRIBUTING.md +18 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/HISTORY.md +42 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/PKG-INFO +1 -1
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/BoltzmannWealth/boltzmann_wealth.py +1 -1
- {mesa-3.0.0b0 → mesa-3.0.0b1}/codecov.yaml +3 -2
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/migration_guide.md +4 -3
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/MoneyModel.py +2 -2
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/visualization_tutorial.ipynb +7 -4
- mesa-3.0.0b1/examples/README.md +37 -0
- mesa-3.0.0b1/examples/__init__.py +0 -0
- mesa-3.0.0b1/examples/advanced/__init__.py +0 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/Epstein Civil Violence.ipynb +116 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/Readme.md +33 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/epstein_civil_violence/__init__.py +0 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/epstein_civil_violence/agent.py +158 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/epstein_civil_violence/model.py +146 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/epstein_civil_violence/portrayal.py +33 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/epstein_civil_violence/server.py +81 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/requirements.txt +3 -0
- mesa-3.0.0b1/examples/advanced/epstein_civil_violence/run.py +3 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/analysis.ipynb +228 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/pd_grid/__init__.py +0 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/pd_grid/agent.py +50 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/pd_grid/model.py +72 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/pd_grid/portrayal.py +19 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/pd_grid/server.py +21 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/readme.md +42 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/requirements.txt +3 -0
- mesa-3.0.0b1/examples/advanced/pd_grid/run.py +3 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/Readme.md +87 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/app.py +61 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/requirements.txt +6 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/run.py +105 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/sugarscape_g1mt/__init__.py +0 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/sugarscape_g1mt/model.py +180 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/sugarscape_g1mt/resource_agents.py +26 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/sugarscape_g1mt/server.py +61 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/sugarscape_g1mt/sugar-map.txt +50 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/sugarscape_g1mt/trader_agents.py +321 -0
- mesa-3.0.0b1/examples/advanced/sugarscape_g1mt/tests.py +72 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/Readme.md +57 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/__init__.py +0 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/requirements.txt +1 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/run.py +3 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/wolf_sheep/__init__.py +0 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/wolf_sheep/agents.py +102 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/wolf_sheep/model.py +136 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/wolf_sheep/resources/sheep.png +0 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/wolf_sheep/resources/wolf.png +0 -0
- mesa-3.0.0b1/examples/advanced/wolf_sheep/wolf_sheep/server.py +78 -0
- mesa-3.0.0b1/examples/basic/__init__.py +13 -0
- mesa-3.0.0b1/examples/basic/boid_flockers/Readme.md +43 -0
- mesa-3.0.0b1/examples/basic/boid_flockers/agents.py +71 -0
- mesa-3.0.0b1/examples/basic/boid_flockers/app.py +59 -0
- mesa-3.0.0b1/examples/basic/boid_flockers/model.py +70 -0
- mesa-3.0.0b1/examples/basic/boltzmann_wealth_model/Readme.md +60 -0
- mesa-3.0.0b1/examples/basic/boltzmann_wealth_model/agents.py +31 -0
- mesa-3.0.0b1/examples/basic/boltzmann_wealth_model/app.py +66 -0
- mesa-3.0.0b1/examples/basic/boltzmann_wealth_model/model.py +44 -0
- mesa-3.0.0b1/examples/basic/boltzmann_wealth_model/st_app.py +115 -0
- mesa-3.0.0b1/examples/basic/conways_game_of_life/Readme.md +35 -0
- mesa-3.0.0b1/examples/basic/conways_game_of_life/agents.py +47 -0
- mesa-3.0.0b1/examples/basic/conways_game_of_life/model.py +32 -0
- mesa-3.0.0b1/examples/basic/conways_game_of_life/portrayal.py +18 -0
- mesa-3.0.0b1/examples/basic/conways_game_of_life/requirements.txt +1 -0
- mesa-3.0.0b1/examples/basic/conways_game_of_life/server.py +11 -0
- mesa-3.0.0b1/examples/basic/conways_game_of_life/st_app.py +71 -0
- mesa-3.0.0b1/examples/basic/schelling/README.md +47 -0
- mesa-3.0.0b1/examples/basic/schelling/agents.py +26 -0
- mesa-3.0.0b1/examples/basic/schelling/analysis.ipynb +205 -0
- mesa-3.0.0b1/examples/basic/schelling/app.py +43 -0
- mesa-3.0.0b1/examples/basic/schelling/model.py +60 -0
- mesa-3.0.0b1/examples/basic/virus_on_network/README.md +61 -0
- mesa-3.0.0b1/examples/basic/virus_on_network/agents.py +69 -0
- mesa-3.0.0b1/examples/basic/virus_on_network/app.py +133 -0
- mesa-3.0.0b1/examples/basic/virus_on_network/model.py +99 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/__init__.py +4 -1
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/agent.py +14 -19
- mesa-3.0.0b1/mesa/examples.py +3 -0
- mesa-3.0.0b1/mesa/experimental/__init__.py +13 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/cell.py +9 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/discrete_space.py +7 -1
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/grid.py +13 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/network.py +3 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/model.py +63 -12
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/time.py +5 -3
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/visualization/components/matplotlib.py +9 -4
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/visualization/solara_viz.py +13 -58
- {mesa-3.0.0b0 → mesa-3.0.0b1}/pyproject.toml +5 -2
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_agent.py +27 -27
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_cell_space.py +39 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_examples.py +17 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_model.py +17 -0
- mesa-3.0.0b1/tests/test_time.py +317 -0
- mesa-3.0.0b0/mesa/experimental/__init__.py +0 -7
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.codespellignore +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.coveragerc +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/PULL_REQUEST_TEMPLATE/bug.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.github/dependabot.yml +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.gitignore +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.pre-commit-config.yaml +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/.readthedocs.yml +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/CITATION.bib +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/CODE_OF_CONDUCT.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/Dockerfile +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/LICENSE +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/NOTICE +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/README.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/BoltzmannWealth/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/Flocking/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/Flocking/flocking.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/Schelling/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/Schelling/schelling.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/WolfSheep/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/WolfSheep/wolf_sheep.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/compare_timings.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/configurations.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/benchmarks/global_benchmark.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docker-compose.yml +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/Makefile +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/README.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/_static/switcher.json +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/agent.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/api_main.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/batchrunner.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/datacollection.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/experimental.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/model.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/space.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/time.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/apis/visualization.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/best-practices.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/conf.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/howto.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/Mesa_Screenshot.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/mesa_logo.ico +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/mesa_logo.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/br_ginis.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/dc_endwealth.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/dc_gini.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/dc_oneagent.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/first_hist.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/multirun_hist.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/numpy_grid.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/viz_chart.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/viz_empty.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/viz_greycircles.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/viz_histogram.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/images/tutorial/viz_redcircles.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/index.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/make.bat +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/mesa.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/overview.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/packages.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/files/viz_chart.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/files/viz_empty.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/files/viz_greycircles.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/files/viz_histogram.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/files/viz_redcircles.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/files/viz_slider.png +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/docs/tutorials/intro_tutorial.ipynb +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/maintenance/fetch_unlabeled_prs.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/batchrunner.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/cookiecutter-mesa/cookiecutter.json +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/cookiecutter-mesa/hooks/post_gen_project.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/datacollection.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/UserParam.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/cell_agent.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/cell_collection.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/cell_space/voronoi.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/components/altair.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/components/matplotlib.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/devs/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/devs/eventlist.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/devs/examples/epstein_civil_violence.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/devs/examples/wolf_sheep.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/devs/simulator.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/experimental/solara_viz.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/main.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/space.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/visualization/UserParam.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/visualization/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/visualization/components/altair.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mesa/visualization/utils.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/mypy.ini +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/__init__.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/read_requirements.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_batch_run.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_datacollector.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_devs.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_end_to_end_viz.sh +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_grid.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_import_namespace.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_lifespan.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_scaffold.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_solara_viz.py +0 -0
- {mesa-3.0.0b0 → mesa-3.0.0b1}/tests/test_space.py +0 -0
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
- name: Set up Python
|
|
26
26
|
uses: actions/setup-python@v5
|
|
27
27
|
with:
|
|
28
|
-
python-version: '3.
|
|
28
|
+
python-version: '3.13'
|
|
29
29
|
- name: Add project directory to PYTHONPATH
|
|
30
30
|
run: echo "PYTHONPATH=$PYTHONPATH:$(pwd)" >> $GITHUB_ENV
|
|
31
31
|
- name: Install dependencies
|
|
@@ -31,10 +31,10 @@ jobs:
|
|
|
31
31
|
fail-fast: False
|
|
32
32
|
matrix:
|
|
33
33
|
os: [windows, ubuntu, macos]
|
|
34
|
-
python-version: ["3.
|
|
34
|
+
python-version: ["3.13"]
|
|
35
35
|
include:
|
|
36
36
|
- os: ubuntu
|
|
37
|
-
python-version: "3.
|
|
37
|
+
python-version: "3.12"
|
|
38
38
|
- os: ubuntu
|
|
39
39
|
python-version: "3.11"
|
|
40
40
|
- os: ubuntu
|
|
@@ -60,6 +60,9 @@ jobs:
|
|
|
60
60
|
- if: matrix.os == 'ubuntu'
|
|
61
61
|
name: Codecov
|
|
62
62
|
uses: codecov/codecov-action@v4
|
|
63
|
+
with:
|
|
64
|
+
fail_ci_if_error: true
|
|
65
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
63
66
|
|
|
64
67
|
examples:
|
|
65
68
|
runs-on: ubuntu-latest
|
|
@@ -68,7 +71,8 @@ jobs:
|
|
|
68
71
|
- name: Set up Python
|
|
69
72
|
uses: actions/setup-python@v5
|
|
70
73
|
with:
|
|
71
|
-
python-version: "3.
|
|
74
|
+
python-version: "3.13"
|
|
75
|
+
allow-prereleases: true
|
|
72
76
|
cache: 'pip'
|
|
73
77
|
- name: Install uv
|
|
74
78
|
run: pip install uv
|
|
@@ -119,6 +119,24 @@ ruff .
|
|
|
119
119
|
|
|
120
120
|
The license of this project is located in [LICENSE]. By submitting a contribution to this project, you are agreeing that your contribution will be released under the terms of this license.
|
|
121
121
|
|
|
122
|
+
## Maintainers
|
|
123
|
+
Some notes useful for Mesa maintainers.
|
|
124
|
+
|
|
125
|
+
### Releases
|
|
126
|
+
To create a new release, follow these steps:
|
|
127
|
+
|
|
128
|
+
1. Ensure all pull requests (PRs) have a clear title and are labeled with at least one label. Check [this link](https://github.com/projectmesa/mesa/pulls?q=is%3Apr+is%3Amerged+no%3Alabel+merged%3A%3E%3D2024-03-01+) to see if all PRs are labeled. These labels will be used when drafting the changelog using the [`.github/release.yml`](https://github.com/projectmesa/mesa/blob/main/.github/release.yml) configuration.
|
|
129
|
+
2. Navigate to the [Releases](https://github.com/projectmesa/mesa/releases) section in the GitHub UI and click the _Draft a new release_ button.
|
|
130
|
+
3. Specify the upcoming tag in the _Choose a tag_ and _Release title_ fields (e.g., `v3.0.0`).
|
|
131
|
+
- For pre-releases, add a `a`, `b` or `rc` and a number behind the version tag (see [Versioning](https://packaging.python.org/en/latest/discussions/versioning/)), and check the box _Set as a pre-release_.
|
|
132
|
+
4. Use the _Generate release notes_ button to automatically create release notes. Review them carefully for accuracy, and update labels and edit PR titles if necessary (step 1).
|
|
133
|
+
5. Write a _Highlights_ section summarizing the most important features or changes in this release.
|
|
134
|
+
6. Copy the release notes and save them by clicking the grey _Save draft_ button.
|
|
135
|
+
7. Open a new PR to update the version number in [`mesa/__init__.py`](https://github.com/projectmesa/mesa/blob/main/mesa/__init__.py) and add the copied release notes to the [`HISTORY.md`](https://github.com/projectmesa/mesa/blob/main/HISTORY.md).
|
|
136
|
+
8. Once this PR is merged, return to the _Releases_ section and publish the draft release.
|
|
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
|
+
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
|
+
|
|
122
140
|
## Special Thanks
|
|
123
141
|
|
|
124
142
|
A special thanks to the following projects who offered inspiration for this contributing file.
|
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Release History
|
|
3
3
|
---
|
|
4
|
+
|
|
5
|
+
# 3.0.0b1 (2024-10-17)
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
Basic exmaples are now importable in Mesa, includes boid_flockers, boltzmann_wealth_model, conways_game_of_life, schelling, and virus_on_network models. With this change they are also integrated into the Mesa tutorial in the docs.
|
|
9
|
+
|
|
10
|
+
Also, in this release, visualizations are improved by making visualization elements scalable and more clearly labeling the plots.
|
|
11
|
+
|
|
12
|
+
<!-- Release notes generated using configuration in .github/release.yml at main -->
|
|
13
|
+
|
|
14
|
+
## What's Changed
|
|
15
|
+
### ⚠️ Breaking changes
|
|
16
|
+
* replace model with random in AgentSet init by @quaquel in https://github.com/projectmesa/mesa/pull/2350
|
|
17
|
+
### 🧪 Experimental features
|
|
18
|
+
* cell space: Add convenience properties for grid width and height by @quaquel in https://github.com/projectmesa/mesa/pull/2348
|
|
19
|
+
* Bugfix for deepcopy / pickling discrete spaces by @quaquel in https://github.com/projectmesa/mesa/pull/2378
|
|
20
|
+
### 🎉 New features added
|
|
21
|
+
* Move core example models back (v2) by @EwoutH in https://github.com/projectmesa/mesa/pull/2358
|
|
22
|
+
* Add Model.rng for SPEC-7 compliant numpy random number generation by @quaquel in https://github.com/projectmesa/mesa/pull/2352
|
|
23
|
+
### 🛠 Enhancements made
|
|
24
|
+
* use GridDraggable instead of Column in SolaraViz by @wang-boyu in https://github.com/projectmesa/mesa/pull/2344
|
|
25
|
+
* update legend, xlabel & format of matplotlib plots by @wang-boyu in https://github.com/projectmesa/mesa/pull/2346
|
|
26
|
+
* __init__.py: Import mesa.experimental by @EwoutH in https://github.com/projectmesa/mesa/pull/2374
|
|
27
|
+
* Importable examples by @Corvince in https://github.com/projectmesa/mesa/pull/2381
|
|
28
|
+
### 🐛 Bugs fixed
|
|
29
|
+
* experimental init: Fix Solara import by making it lazy by @EwoutH in https://github.com/projectmesa/mesa/pull/2357
|
|
30
|
+
* fix: pass `model.random` to schedulers by @quaquel in https://github.com/projectmesa/mesa/pull/2359
|
|
31
|
+
* fix: register agent after creating unique_id and pos attributes by @wang-boyu in https://github.com/projectmesa/mesa/pull/2368
|
|
32
|
+
* solara: viz tutorial: fix histogram code by @Corvince in https://github.com/projectmesa/mesa/pull/2379
|
|
33
|
+
### 🔍 Examples updated
|
|
34
|
+
* Cleanup and restructure basic example models by @EwoutH in https://github.com/projectmesa/mesa/pull/2365
|
|
35
|
+
* Ruff basic examples by @EwoutH in https://github.com/projectmesa/mesa/pull/2370
|
|
36
|
+
### 📜 Documentation improvements
|
|
37
|
+
* Update migration_guide.md by @quaquel in https://github.com/projectmesa/mesa/pull/2347
|
|
38
|
+
### 🔧 Maintenance
|
|
39
|
+
* Code coverage: ignore experimental and visualization by @Corvince in https://github.com/projectmesa/mesa/pull/2361
|
|
40
|
+
* add codecov token, fixes #2363 by @Corvince in https://github.com/projectmesa/mesa/pull/2366
|
|
41
|
+
* add test_time back by @quaquel in https://github.com/projectmesa/mesa/pull/2367
|
|
42
|
+
* Release notes: Add example category by @EwoutH in https://github.com/projectmesa/mesa/pull/2369
|
|
43
|
+
|
|
44
|
+
**Full Changelog**: https://github.com/projectmesa/mesa/compare/v3.0.0b0...v3.0.0b1
|
|
45
|
+
|
|
4
46
|
# 3.0.0b0 (2024-10-04)
|
|
5
47
|
## Highlights
|
|
6
48
|
We're proud to release the first Mesa 3.0 beta! This pre-release announces that we're ready for Mesa 3.0 to be tested by all our regular users. We try to not making breaking changes anymore, but focus on resolving bugs and imperfections.
|
|
@@ -42,15 +42,16 @@ The `mesa.flat` namespace is removed. Use the full namespace for your imports.
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
### Mandatory Model initialization with `super().__init__()`
|
|
45
|
-
In Mesa 3.0, it is now mandatory to call `super().__init__()` when initializing your model class. This ensures that all necessary Mesa model variables are correctly set up and agents are properly added to the model.
|
|
45
|
+
In Mesa 3.0, it is now mandatory to call `super().__init__()` when initializing your model class. This ensures that all necessary Mesa model variables are correctly set up and agents are properly added to the model. If you want to control the seed of the random number generator, you have to pass this as a keyword argument to super as shown below.
|
|
46
46
|
|
|
47
47
|
Make sure all your model classes explicitly call `super().__init__()` in their `__init__` method:
|
|
48
48
|
|
|
49
49
|
```python
|
|
50
50
|
class MyModel(mesa.Model):
|
|
51
|
-
def __init__(self,
|
|
52
|
-
super().__init__() #
|
|
51
|
+
def __init__(self, some_arg_I_need, seed=None, some_kwarg_I_need=True):
|
|
52
|
+
super().__init__(seed=seed) # Calling super is now required, passing seed is highly recommended
|
|
53
53
|
# Your model initialization code here
|
|
54
|
+
# this code uses some_arg_I_need and my_init_kwarg
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
This change ensures that all Mesa models are properly initialized, which is crucial for:
|
|
@@ -49,7 +49,7 @@ class MoneyAgent(mesa.Agent):
|
|
|
49
49
|
class MoneyModel(mesa.Model):
|
|
50
50
|
"""A model with some number of agents."""
|
|
51
51
|
|
|
52
|
-
def __init__(self, N, width, height):
|
|
52
|
+
def __init__(self, N, width, height, seed=None):
|
|
53
53
|
"""Initialize a MoneyModel instance.
|
|
54
54
|
|
|
55
55
|
Args:
|
|
@@ -57,7 +57,7 @@ class MoneyModel(mesa.Model):
|
|
|
57
57
|
width: width of the grid.
|
|
58
58
|
height: Height of the grid.
|
|
59
59
|
"""
|
|
60
|
-
super().__init__()
|
|
60
|
+
super().__init__(seed=seed)
|
|
61
61
|
self.num_agents = N
|
|
62
62
|
self.grid = mesa.space.MultiGrid(width, height, True)
|
|
63
63
|
self.schedule = mesa.time.RandomActivation(self)
|
|
@@ -46,10 +46,9 @@
|
|
|
46
46
|
"import mesa\n",
|
|
47
47
|
"print(f\"Mesa version: {mesa.__version__}\")\n",
|
|
48
48
|
"\n",
|
|
49
|
-
"# You can either define the BoltzmannWealthModel (aka MoneyModel) or install
|
|
50
|
-
"%pip install --quiet -U git+https://github.com/projectmesa/mesa-examples#egg=mesa-models\n",
|
|
49
|
+
"# You can either define the BoltzmannWealthModel (aka MoneyModel) or install it\n",
|
|
51
50
|
"\n",
|
|
52
|
-
"from
|
|
51
|
+
"from mesa.examples.basic import BoltzmannWealthModel"
|
|
53
52
|
]
|
|
54
53
|
},
|
|
55
54
|
{
|
|
@@ -194,7 +193,9 @@
|
|
|
194
193
|
"\n",
|
|
195
194
|
"If the visualization elements provided by Mesa aren't enough for you, you can build your own and plug them into the model server.\n",
|
|
196
195
|
"\n",
|
|
197
|
-
"For this example, let's build a simple histogram visualization, which can count the number of agents with each value of wealth
|
|
196
|
+
"For this example, let's build a simple histogram visualization, which can count the number of agents with each value of wealth.\n",
|
|
197
|
+
"\n",
|
|
198
|
+
"**Note:** Due to the way solara works we need to trigger an update whenever the underlying model changes. For this you need to register an update counter with every component."
|
|
198
199
|
]
|
|
199
200
|
},
|
|
200
201
|
{
|
|
@@ -205,9 +206,11 @@
|
|
|
205
206
|
"source": [
|
|
206
207
|
"import solara\n",
|
|
207
208
|
"from matplotlib.figure import Figure\n",
|
|
209
|
+
"from mesa.visualization.utils import update_counter\n",
|
|
208
210
|
"\n",
|
|
209
211
|
"@solara.component\n",
|
|
210
212
|
"def Histogram(model):\n",
|
|
213
|
+
" update_counter.get() # This is required to update the counter\n",
|
|
211
214
|
" # Note: you must initialize a figure using this method instead of\n",
|
|
212
215
|
" # plt.figure(), for thread safety purpose\n",
|
|
213
216
|
" fig = Figure()\n",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Mesa core examples
|
|
2
|
+
This folder contains a collection of example models built using Mesa. These core models are maintained by the Mesa team and are intended to demonstrate the capabilities of Mesa.
|
|
3
|
+
|
|
4
|
+
More user examples and showcases can be found in the [mesa-examples](https://github.com/projectmesa/mesa-examples) repository.
|
|
5
|
+
|
|
6
|
+
## Basic Examples
|
|
7
|
+
The basic examples are relatively simple and only use stable Mesa features. They are good starting points for learning how to use Mesa.
|
|
8
|
+
|
|
9
|
+
### [Boltzmann Wealth Model](basic/boltzmann_wealth_model)
|
|
10
|
+
Completed code to go along with the [tutorial](https://mesa.readthedocs.io/latest/tutorials/intro_tutorial.html) on making a simple model of how a highly-skewed wealth distribution can emerge from simple rules.
|
|
11
|
+
|
|
12
|
+
### [Boids Flockers Model](basic/boid_flockers)
|
|
13
|
+
[Boids](https://en.wikipedia.org/wiki/Boids)-style flocking model, demonstrating the use of agents moving through a continuous space following direction vectors.
|
|
14
|
+
|
|
15
|
+
### [Conway's Game of Life](basic/conways_game_of_life)
|
|
16
|
+
Implementation of [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life), a cellular automata where simple rules can give rise to complex patterns.
|
|
17
|
+
|
|
18
|
+
### [Schelling Segregation Model](basic/schelling)
|
|
19
|
+
Mesa implementation of the classic [Schelling segregation](http://nifty.stanford.edu/2014/mccown-schelling-model-segregation/) model.
|
|
20
|
+
|
|
21
|
+
### [Virus on a Network Model](basic/virus_on_network)
|
|
22
|
+
This model is based on the NetLogo [Virus on a Network](https://ccl.northwestern.edu/netlogo/models/VirusonaNetwork) model.
|
|
23
|
+
|
|
24
|
+
## Advanced Examples
|
|
25
|
+
The advanced examples are more complex and may use experimental Mesa features. They are good starting points for learning how to build more complex models.
|
|
26
|
+
|
|
27
|
+
### [Epstein Civil Violence Model](advanced/epstein_civil_violence)
|
|
28
|
+
Joshua Epstein's [model](http://www.uvm.edu/~pdodds/files/papers/others/2002/epstein2002a.pdf) of how a decentralized uprising can be suppressed or reach a critical mass of support.
|
|
29
|
+
|
|
30
|
+
### [Demographic Prisoner's Dilemma on a Grid](advanced/pd_grid)
|
|
31
|
+
Grid-based demographic prisoner's dilemma model, demonstrating how simple rules can lead to the emergence of widespread cooperation -- and how a model activation regime can change its outcome.
|
|
32
|
+
|
|
33
|
+
### [Sugarscape Model with Traders](advanced/sugarscape_g1mt)
|
|
34
|
+
This is Epstein & Axtell's Sugarscape model with Traders, a detailed description is in Chapter four of *Growing Artificial Societies: Social Science from the Bottom Up (1996)*. The model shows how emergent price equilibrium can happen via decentralized dynamics.
|
|
35
|
+
|
|
36
|
+
### [Wolf-Sheep Predation Model](advanced/wolf_sheep)
|
|
37
|
+
Implementation of an ecological model of predation and reproduction, based on the NetLogo [Wolf Sheep Predation](http://ccl.northwestern.edu/netlogo/models/WolfSheepPredation) model.
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"This example implements the first model from \"Modeling civil violence: An agent-based computational approach,\" by Joshua Epstein. The paper (pdf) can be found [here](http://www.uvm.edu/~pdodds/files/papers/others/2002/epstein2002a.pdf).\n",
|
|
8
|
+
"\n",
|
|
9
|
+
"The model consists of two types of agents: \"Citizens\" (called \"Agents\" in the paper) and \"Cops.\" Agents decide whether or not to rebel by weighing their unhappiness ('grievance') against the risk of rebelling, which they estimate by comparing the local ratio of rebels to cops. \n",
|
|
10
|
+
"\n",
|
|
11
|
+
"\n"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"cell_type": "code",
|
|
16
|
+
"execution_count": 5,
|
|
17
|
+
"metadata": {},
|
|
18
|
+
"outputs": [],
|
|
19
|
+
"source": [
|
|
20
|
+
"%matplotlib inline\n",
|
|
21
|
+
"\n",
|
|
22
|
+
"from epstein_civil_violence.model import EpsteinCivilViolence"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"cell_type": "code",
|
|
27
|
+
"execution_count": 6,
|
|
28
|
+
"metadata": {},
|
|
29
|
+
"outputs": [],
|
|
30
|
+
"source": [
|
|
31
|
+
"model = EpsteinCivilViolence(\n",
|
|
32
|
+
" height=40,\n",
|
|
33
|
+
" width=40,\n",
|
|
34
|
+
" citizen_density=0.7,\n",
|
|
35
|
+
" cop_density=0.074,\n",
|
|
36
|
+
" citizen_vision=7,\n",
|
|
37
|
+
" cop_vision=7,\n",
|
|
38
|
+
" legitimacy=0.8,\n",
|
|
39
|
+
" max_jail_term=1000,\n",
|
|
40
|
+
" max_iters=1000,\n",
|
|
41
|
+
") # cap the number of steps the model takes\n",
|
|
42
|
+
"model.run_model()"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"cell_type": "markdown",
|
|
47
|
+
"metadata": {},
|
|
48
|
+
"source": [
|
|
49
|
+
"The model's data collector counts the number of citizens who are Active (in rebellion), Jailed, or Quiescent after each step."
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"cell_type": "code",
|
|
54
|
+
"execution_count": 7,
|
|
55
|
+
"metadata": {},
|
|
56
|
+
"outputs": [],
|
|
57
|
+
"source": [
|
|
58
|
+
"model_out = model.datacollector.get_model_vars_dataframe()"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"cell_type": "code",
|
|
63
|
+
"execution_count": 8,
|
|
64
|
+
"metadata": {},
|
|
65
|
+
"outputs": [
|
|
66
|
+
{
|
|
67
|
+
"data": {
|
|
68
|
+
"image/png": "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\n",
|
|
69
|
+
"text/plain": [
|
|
70
|
+
"<Figure size 432x288 with 1 Axes>"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
"metadata": {
|
|
74
|
+
"needs_background": "light"
|
|
75
|
+
},
|
|
76
|
+
"output_type": "display_data"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"source": [
|
|
80
|
+
"ax = model_out.plot()\n",
|
|
81
|
+
"ax.set_title(\"Citizen Condition Over Time\")\n",
|
|
82
|
+
"ax.set_xlabel(\"Step\")\n",
|
|
83
|
+
"ax.set_ylabel(\"Number of Citizens\")\n",
|
|
84
|
+
"_ = ax.legend(bbox_to_anchor=(1.35, 1.025))"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"cell_type": "code",
|
|
89
|
+
"execution_count": null,
|
|
90
|
+
"metadata": {},
|
|
91
|
+
"outputs": [],
|
|
92
|
+
"source": []
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"metadata": {
|
|
96
|
+
"kernelspec": {
|
|
97
|
+
"display_name": "Python 3",
|
|
98
|
+
"language": "python",
|
|
99
|
+
"name": "python3"
|
|
100
|
+
},
|
|
101
|
+
"language_info": {
|
|
102
|
+
"codemirror_mode": {
|
|
103
|
+
"name": "ipython",
|
|
104
|
+
"version": 3
|
|
105
|
+
},
|
|
106
|
+
"file_extension": ".py",
|
|
107
|
+
"mimetype": "text/x-python",
|
|
108
|
+
"name": "python",
|
|
109
|
+
"nbconvert_exporter": "python",
|
|
110
|
+
"pygments_lexer": "ipython3",
|
|
111
|
+
"version": "3.7.3"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"nbformat": 4,
|
|
115
|
+
"nbformat_minor": 1
|
|
116
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Epstein Civil Violence Model
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
This model is based on Joshua Epstein's simulation of how civil unrest grows and is suppressed. Citizen agents wander the grid randomly, and are endowed with individual risk aversion and hardship levels; there is also a universal regime legitimacy value. There are also Cop agents, who work on behalf of the regime. Cops arrest Citizens who are actively rebelling; Citizens decide whether to rebel based on their hardship and the regime legitimacy, and their perceived probability of arrest.
|
|
6
|
+
|
|
7
|
+
The model generates mass uprising as self-reinforcing processes: if enough agents are rebelling, the probability of any individual agent being arrested is reduced, making more agents more likely to join the uprising. However, the more rebelling Citizens the Cops arrest, the less likely additional agents become to join.
|
|
8
|
+
|
|
9
|
+
## How to Run
|
|
10
|
+
|
|
11
|
+
To run the model interactively, run ``EpsteinCivilViolenceServer.py`` in this directory. e.g.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
$ python EpsteinCivilViolenceServer.py
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run.
|
|
18
|
+
|
|
19
|
+
## Files
|
|
20
|
+
|
|
21
|
+
* ``EpsteinCivilViolence.py``: Core model and agent code.
|
|
22
|
+
* ``EpsteinCivilViolenceServer.py``: Sets up the interactive visualization.
|
|
23
|
+
* ``Epstein Civil Violence.ipynb``: Jupyter notebook conducting some preliminary analysis of the model.
|
|
24
|
+
|
|
25
|
+
## Further Reading
|
|
26
|
+
|
|
27
|
+
This model is based adapted from:
|
|
28
|
+
|
|
29
|
+
[Epstein, J. “Modeling civil violence: An agent-based computational approach”, Proceedings of the National Academy of Sciences, Vol. 99, Suppl. 3, May 14, 2002](http://www.pnas.org/content/99/suppl.3/7243.short)
|
|
30
|
+
|
|
31
|
+
A similar model is also included with NetLogo:
|
|
32
|
+
|
|
33
|
+
Wilensky, U. (2004). NetLogo Rebellion model. http://ccl.northwestern.edu/netlogo/models/Rebellion. Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL.
|
|
File without changes
|