Mesa 3.0.0b1__py3-none-any.whl → 3.0.0rc0__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 +1 -3
- mesa/agent.py +23 -8
- mesa/batchrunner.py +26 -1
- {examples → mesa/examples}/README.md +11 -11
- mesa/examples/__init__.py +21 -0
- {examples → mesa/examples}/advanced/epstein_civil_violence/Readme.md +3 -2
- examples/advanced/epstein_civil_violence/epstein_civil_violence/agent.py → mesa/examples/advanced/epstein_civil_violence/agents.py +44 -38
- mesa/examples/advanced/epstein_civil_violence/app.py +73 -0
- mesa/examples/advanced/epstein_civil_violence/model.py +114 -0
- examples/advanced/pd_grid/readme.md → mesa/examples/advanced/pd_grid/Readme.md +4 -3
- mesa/examples/advanced/pd_grid/app.py +54 -0
- {examples/advanced/pd_grid → mesa/examples/advanced}/pd_grid/model.py +1 -2
- {examples → mesa/examples}/advanced/sugarscape_g1mt/Readme.md +6 -29
- examples/advanced/sugarscape_g1mt/sugarscape_g1mt/trader_agents.py → mesa/examples/advanced/sugarscape_g1mt/agents.py +26 -3
- {examples → mesa/examples}/advanced/sugarscape_g1mt/app.py +19 -18
- {examples/advanced/sugarscape_g1mt → mesa/examples/advanced}/sugarscape_g1mt/model.py +6 -6
- {examples → mesa/examples}/advanced/sugarscape_g1mt/tests.py +3 -6
- mesa/examples/advanced/wolf_sheep/app.py +84 -0
- {examples/advanced/wolf_sheep → mesa/examples/advanced}/wolf_sheep/model.py +9 -8
- mesa/examples/basic/boid_flockers/Readme.md +22 -0
- {examples → mesa/examples}/basic/boid_flockers/app.py +3 -4
- {examples → mesa/examples}/basic/boid_flockers/model.py +1 -2
- {examples → mesa/examples}/basic/boltzmann_wealth_model/Readme.md +1 -5
- mesa/examples/basic/boltzmann_wealth_model/__init__.py +0 -0
- {examples → mesa/examples}/basic/boltzmann_wealth_model/app.py +15 -12
- {examples → mesa/examples}/basic/boltzmann_wealth_model/model.py +3 -4
- {examples → mesa/examples}/basic/conways_game_of_life/Readme.md +11 -7
- mesa/examples/basic/conways_game_of_life/__init__.py +0 -0
- {examples → mesa/examples}/basic/conways_game_of_life/agents.py +8 -8
- mesa/examples/basic/conways_game_of_life/app.py +51 -0
- {examples → mesa/examples}/basic/conways_game_of_life/model.py +3 -4
- {examples → mesa/examples}/basic/conways_game_of_life/st_app.py +2 -1
- examples/basic/schelling/README.md → mesa/examples/basic/schelling/Readme.md +2 -9
- mesa/examples/basic/schelling/__init__.py +0 -0
- {examples → mesa/examples}/basic/schelling/app.py +6 -7
- {examples → mesa/examples}/basic/schelling/model.py +1 -2
- mesa/examples/basic/virus_on_network/__init__.py +0 -0
- mesa/examples/basic/virus_on_network/app.py +114 -0
- {examples → mesa/examples}/basic/virus_on_network/model.py +4 -7
- mesa/experimental/cell_space/discrete_space.py +6 -0
- mesa/experimental/devs/eventlist.py +6 -0
- mesa/model.py +13 -0
- mesa/space.py +70 -35
- mesa/visualization/__init__.py +16 -5
- mesa/visualization/components/__init__.py +83 -0
- mesa/visualization/components/altair_components.py +188 -0
- mesa/visualization/components/matplotlib_components.py +176 -0
- mesa/visualization/mpl_space_drawing.py +558 -0
- mesa/visualization/solara_viz.py +30 -20
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/METADATA +1 -3
- mesa-3.0.0rc0.dist-info/RECORD +95 -0
- examples/advanced/epstein_civil_violence/epstein_civil_violence/model.py +0 -146
- examples/advanced/epstein_civil_violence/epstein_civil_violence/portrayal.py +0 -33
- examples/advanced/epstein_civil_violence/epstein_civil_violence/server.py +0 -81
- examples/advanced/epstein_civil_violence/requirements.txt +0 -3
- examples/advanced/epstein_civil_violence/run.py +0 -3
- examples/advanced/pd_grid/pd_grid/portrayal.py +0 -19
- examples/advanced/pd_grid/pd_grid/server.py +0 -21
- examples/advanced/pd_grid/requirements.txt +0 -3
- examples/advanced/pd_grid/run.py +0 -3
- examples/advanced/sugarscape_g1mt/requirements.txt +0 -6
- examples/advanced/sugarscape_g1mt/run.py +0 -105
- examples/advanced/sugarscape_g1mt/sugarscape_g1mt/resource_agents.py +0 -26
- examples/advanced/sugarscape_g1mt/sugarscape_g1mt/server.py +0 -61
- examples/advanced/wolf_sheep/requirements.txt +0 -1
- examples/advanced/wolf_sheep/run.py +0 -3
- examples/advanced/wolf_sheep/wolf_sheep/resources/sheep.png +0 -0
- examples/advanced/wolf_sheep/wolf_sheep/resources/wolf.png +0 -0
- examples/advanced/wolf_sheep/wolf_sheep/server.py +0 -78
- examples/basic/__init__.py +0 -13
- examples/basic/boid_flockers/Readme.md +0 -43
- examples/basic/conways_game_of_life/portrayal.py +0 -18
- examples/basic/conways_game_of_life/requirements.txt +0 -1
- examples/basic/conways_game_of_life/server.py +0 -11
- examples/basic/virus_on_network/app.py +0 -133
- mesa/cookiecutter-mesa/cookiecutter.json +0 -8
- mesa/cookiecutter-mesa/hooks/post_gen_project.py +0 -13
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md +0 -4
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate +0 -27
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate +0 -11
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py +0 -1
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate +0 -60
- mesa/examples.py +0 -3
- mesa/main.py +0 -65
- mesa/visualization/components/altair.py +0 -88
- mesa/visualization/components/matplotlib.py +0 -342
- mesa-3.0.0b1.dist-info/RECORD +0 -114
- {examples → mesa/examples/advanced}/__init__.py +0 -0
- {examples → mesa/examples}/advanced/epstein_civil_violence/Epstein Civil Violence.ipynb +0 -0
- {examples/advanced → mesa/examples/advanced/epstein_civil_violence}/__init__.py +0 -0
- {examples/advanced/epstein_civil_violence/epstein_civil_violence → mesa/examples/advanced/pd_grid}/__init__.py +0 -0
- /examples/advanced/pd_grid/pd_grid/agent.py → /mesa/examples/advanced/pd_grid/agents.py +0 -0
- {examples → mesa/examples}/advanced/pd_grid/analysis.ipynb +0 -0
- {examples/advanced/pd_grid/pd_grid → mesa/examples/advanced/sugarscape_g1mt}/__init__.py +0 -0
- {examples/advanced/sugarscape_g1mt → mesa/examples/advanced}/sugarscape_g1mt/sugar-map.txt +0 -0
- {examples → mesa/examples}/advanced/wolf_sheep/Readme.md +0 -0
- {examples/advanced/sugarscape_g1mt/sugarscape_g1mt → mesa/examples/advanced/wolf_sheep}/__init__.py +0 -0
- {examples/advanced/wolf_sheep → mesa/examples/advanced}/wolf_sheep/agents.py +0 -0
- {examples/advanced/wolf_sheep → mesa/examples/basic}/__init__.py +0 -0
- {examples/advanced/wolf_sheep/wolf_sheep → mesa/examples/basic/boid_flockers}/__init__.py +0 -0
- {examples → mesa/examples}/basic/boid_flockers/agents.py +0 -0
- {examples → mesa/examples}/basic/boltzmann_wealth_model/agents.py +0 -0
- {examples → mesa/examples}/basic/boltzmann_wealth_model/st_app.py +0 -0
- {examples → mesa/examples}/basic/schelling/agents.py +0 -0
- {examples → mesa/examples}/basic/schelling/analysis.ipynb +0 -0
- /examples/basic/virus_on_network/README.md → /mesa/examples/basic/virus_on_network/Readme.md +0 -0
- {examples → mesa/examples}/basic/virus_on_network/agents.py +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/WHEEL +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/entry_points.txt +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/licenses/LICENSE +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/licenses/NOTICE +0 -0
|
@@ -34,51 +34,28 @@ cross over one another otherwise *end*.
|
|
|
34
34
|
(Epstein and Axtell, 1996, p. 105)
|
|
35
35
|
|
|
36
36
|
The model demonstrates several Mesa concepts and features:
|
|
37
|
-
-
|
|
37
|
+
- OrthogonalMooreGrid
|
|
38
38
|
- Multiple agent types (traders, sugar, spice)
|
|
39
39
|
- Dynamically removing agents from the grid and schedule when they die
|
|
40
40
|
- Data Collection at the model and agent level
|
|
41
|
-
-
|
|
41
|
+
- custom solara matplotlib space visualization
|
|
42
42
|
|
|
43
|
-
## Installation
|
|
44
|
-
|
|
45
|
-
To install the dependencies use pip and the requirements.txt in this directory. e.g.
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
$ pip install -r requirements.txt
|
|
49
|
-
```
|
|
50
43
|
|
|
51
44
|
## How to Run
|
|
52
|
-
|
|
53
|
-
To run the model a single instance of the model:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
$ python run.py -s
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
To run the model with BatchRunner:
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
$ python run.py -b
|
|
63
|
-
```
|
|
64
|
-
|
|
65
45
|
To run the model interactively:
|
|
66
46
|
|
|
67
47
|
```
|
|
68
|
-
$
|
|
48
|
+
$ solara run app.py
|
|
69
49
|
```
|
|
70
50
|
|
|
71
51
|
Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run.
|
|
72
52
|
|
|
73
53
|
## Files
|
|
74
54
|
|
|
75
|
-
* `
|
|
76
|
-
* `
|
|
77
|
-
* `sugarscape_g1mt/model.py`: Manages the Sugarscape Constant Growback with Traders model.
|
|
78
|
-
* `sugarscape_g1mt/sugar_map.txt`: Provides sugar and spice landscape in raster type format.
|
|
79
|
-
* `server.py`: Sets up an interactive visualization server.
|
|
80
|
-
* `run.py`: Runs Server, Single Run or Batch Run with data collection and basic analysis.
|
|
55
|
+
* `model.py`: The Sugarscape Constant Growback with Traders model.
|
|
56
|
+
* `agents.py`: Defines the Trader agent class and the Resource agent class which contains an amount of sugar and spice.
|
|
81
57
|
* `app.py`: Runs a visualization server via Solara (`solara run app.py`).
|
|
58
|
+
* `sugar_map.txt`: Provides sugar and spice landscape in raster type format.
|
|
82
59
|
* `tests.py`: Has tests to ensure that the model reproduces the results in shown in Growing Artificial Societies.
|
|
83
60
|
|
|
84
61
|
## Additional Resources
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import math
|
|
2
2
|
|
|
3
|
-
from mesa.experimental.cell_space import CellAgent
|
|
4
|
-
|
|
5
|
-
from .resource_agents import Resource
|
|
3
|
+
from mesa.experimental.cell_space import CellAgent, FixedAgent
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
# Helper function
|
|
@@ -20,6 +18,31 @@ def get_distance(cell_1, cell_2):
|
|
|
20
18
|
return math.sqrt(dx**2 + dy**2)
|
|
21
19
|
|
|
22
20
|
|
|
21
|
+
class Resource(FixedAgent):
|
|
22
|
+
"""
|
|
23
|
+
Resource:
|
|
24
|
+
- contains an amount of sugar and spice
|
|
25
|
+
- grows 1 amount of sugar at each turn
|
|
26
|
+
- grows 1 amount of spice at each turn
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, model, max_sugar, max_spice, cell):
|
|
30
|
+
super().__init__(model)
|
|
31
|
+
self.sugar_amount = max_sugar
|
|
32
|
+
self.max_sugar = max_sugar
|
|
33
|
+
self.spice_amount = max_spice
|
|
34
|
+
self.max_spice = max_spice
|
|
35
|
+
self.cell = cell
|
|
36
|
+
|
|
37
|
+
def step(self):
|
|
38
|
+
"""
|
|
39
|
+
Growth function, adds one unit of sugar and spice each step up to
|
|
40
|
+
max amount
|
|
41
|
+
"""
|
|
42
|
+
self.sugar_amount = min([self.max_sugar, self.sugar_amount + 1])
|
|
43
|
+
self.spice_amount = min([self.max_spice, self.spice_amount + 1])
|
|
44
|
+
|
|
45
|
+
|
|
23
46
|
class Trader(CellAgent):
|
|
24
47
|
"""
|
|
25
48
|
Trader:
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import solara
|
|
3
3
|
from matplotlib.figure import Figure
|
|
4
|
-
|
|
5
|
-
from sugarscape_g1mt.
|
|
6
|
-
from sugarscape_g1mt.
|
|
4
|
+
|
|
5
|
+
from mesa.examples.advanced.sugarscape_g1mt.agents import Trader
|
|
6
|
+
from mesa.examples.advanced.sugarscape_g1mt.model import SugarscapeG1mt
|
|
7
|
+
from mesa.visualization import SolaraViz, make_plot_component
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def SpaceDrawer(model):
|
|
@@ -14,19 +15,19 @@ def SpaceDrawer(model):
|
|
|
14
15
|
"trader": {"x": [], "y": [], "c": "tab:red", "marker": "o", "s": 10},
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
for
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
for agent in g.all_cells.agents:
|
|
19
|
+
i, j = agent.cell.coordinate
|
|
20
|
+
if isinstance(agent, Trader):
|
|
21
|
+
layers["trader"]["x"].append(i)
|
|
22
|
+
layers["trader"]["y"].append(j)
|
|
23
|
+
else:
|
|
24
|
+
# Don't visualize resource with value <= 1.
|
|
25
|
+
layers["sugar"][i][j] = (
|
|
26
|
+
agent.sugar_amount if agent.sugar_amount > 1 else np.nan
|
|
27
|
+
)
|
|
28
|
+
layers["spice"][i][j] = (
|
|
29
|
+
agent.spice_amount if agent.spice_amount > 1 else np.nan
|
|
30
|
+
)
|
|
30
31
|
return layers
|
|
31
32
|
|
|
32
33
|
fig = Figure()
|
|
@@ -54,8 +55,8 @@ model1 = SugarscapeG1mt(50, 50)
|
|
|
54
55
|
|
|
55
56
|
page = SolaraViz(
|
|
56
57
|
model1,
|
|
57
|
-
components=[SpaceDrawer,
|
|
58
|
+
components=[SpaceDrawer, make_plot_component(["Trader", "Price"])],
|
|
58
59
|
name="Sugarscape {G1, M, T}",
|
|
59
|
-
play_interval=
|
|
60
|
+
play_interval=150,
|
|
60
61
|
)
|
|
61
62
|
page # noqa
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
import mesa
|
|
4
3
|
import numpy as np
|
|
5
|
-
from mesa.experimental.cell_space import OrthogonalVonNeumannGrid
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
from .
|
|
5
|
+
import mesa
|
|
6
|
+
from mesa.examples.advanced.sugarscape_g1mt.agents import Resource, Trader
|
|
7
|
+
from mesa.experimental.cell_space import OrthogonalVonNeumannGrid
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
# Helper Functions
|
|
@@ -53,8 +52,9 @@ class SugarscapeG1mt(mesa.Model):
|
|
|
53
52
|
vision_min=1,
|
|
54
53
|
vision_max=5,
|
|
55
54
|
enable_trade=True,
|
|
55
|
+
seed=None,
|
|
56
56
|
):
|
|
57
|
-
super().__init__()
|
|
57
|
+
super().__init__(seed=seed)
|
|
58
58
|
# Initiate width and height of sugarscape
|
|
59
59
|
self.width = width
|
|
60
60
|
self.height = height
|
|
@@ -176,5 +176,5 @@ class SugarscapeG1mt(mesa.Model):
|
|
|
176
176
|
self.datacollector._agent_records[self.steps] = agent_trades
|
|
177
177
|
|
|
178
178
|
def run_model(self, step_count=1000):
|
|
179
|
-
for
|
|
179
|
+
for _ in range(step_count):
|
|
180
180
|
self.step()
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import random
|
|
2
|
-
|
|
3
1
|
import numpy as np
|
|
4
2
|
from scipy import stats
|
|
5
|
-
from sugarscape_g1mt.model import SugarscapeG1mt, flatten
|
|
6
|
-
from sugarscape_g1mt.trader_agents import Trader
|
|
7
3
|
|
|
8
|
-
|
|
4
|
+
from .agents import Trader
|
|
5
|
+
from .model import SugarscapeG1mt, flatten
|
|
9
6
|
|
|
10
7
|
|
|
11
8
|
def check_slope(y, increasing):
|
|
@@ -19,7 +16,7 @@ def check_slope(y, increasing):
|
|
|
19
16
|
def test_decreasing_price_variance():
|
|
20
17
|
# The variance of the average trade price should decrease over time (figure IV-3)
|
|
21
18
|
# See Growing Artificial Societies p. 109.
|
|
22
|
-
model = SugarscapeG1mt()
|
|
19
|
+
model = SugarscapeG1mt(42)
|
|
23
20
|
model.datacollector._new_model_reporter(
|
|
24
21
|
"price_variance",
|
|
25
22
|
lambda m: np.var(
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from mesa.examples.advanced.wolf_sheep.agents import GrassPatch, Sheep, Wolf
|
|
2
|
+
from mesa.examples.advanced.wolf_sheep.model import WolfSheep
|
|
3
|
+
from mesa.visualization import (
|
|
4
|
+
Slider,
|
|
5
|
+
SolaraViz,
|
|
6
|
+
make_plot_component,
|
|
7
|
+
make_space_component,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def wolf_sheep_portrayal(agent):
|
|
12
|
+
if agent is None:
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
portrayal = {
|
|
16
|
+
"size": 25,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if isinstance(agent, Wolf):
|
|
20
|
+
portrayal["color"] = "tab:red"
|
|
21
|
+
portrayal["marker"] = "o"
|
|
22
|
+
portrayal["zorder"] = 2
|
|
23
|
+
elif isinstance(agent, Sheep):
|
|
24
|
+
portrayal["color"] = "tab:cyan"
|
|
25
|
+
portrayal["marker"] = "o"
|
|
26
|
+
portrayal["zorder"] = 2
|
|
27
|
+
elif isinstance(agent, GrassPatch):
|
|
28
|
+
if agent.fully_grown:
|
|
29
|
+
portrayal["color"] = "tab:green"
|
|
30
|
+
else:
|
|
31
|
+
portrayal["color"] = "tab:brown"
|
|
32
|
+
portrayal["marker"] = "s"
|
|
33
|
+
portrayal["size"] = 75
|
|
34
|
+
|
|
35
|
+
return portrayal
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
model_params = {
|
|
39
|
+
# The following line is an example to showcase StaticText.
|
|
40
|
+
"grass": {
|
|
41
|
+
"type": "Select",
|
|
42
|
+
"value": True,
|
|
43
|
+
"values": [True, False],
|
|
44
|
+
"label": "grass regrowth enabled?",
|
|
45
|
+
},
|
|
46
|
+
"grass_regrowth_time": Slider("Grass Regrowth Time", 20, 1, 50),
|
|
47
|
+
"initial_sheep": Slider("Initial Sheep Population", 100, 10, 300),
|
|
48
|
+
"sheep_reproduce": Slider("Sheep Reproduction Rate", 0.04, 0.01, 1.0, 0.01),
|
|
49
|
+
"initial_wolves": Slider("Initial Wolf Population", 10, 5, 100),
|
|
50
|
+
"wolf_reproduce": Slider(
|
|
51
|
+
"Wolf Reproduction Rate",
|
|
52
|
+
0.05,
|
|
53
|
+
0.01,
|
|
54
|
+
1.0,
|
|
55
|
+
0.01,
|
|
56
|
+
),
|
|
57
|
+
"wolf_gain_from_food": Slider("Wolf Gain From Food Rate", 20, 1, 50),
|
|
58
|
+
"sheep_gain_from_food": Slider("Sheep Gain From Food", 4, 1, 10),
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def post_process(ax):
|
|
63
|
+
ax.set_aspect("equal")
|
|
64
|
+
ax.set_xticks([])
|
|
65
|
+
ax.set_yticks([])
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
space_component = make_space_component(
|
|
69
|
+
wolf_sheep_portrayal, draw_grid=False, post_process=post_process
|
|
70
|
+
)
|
|
71
|
+
lineplot_component = make_plot_component(
|
|
72
|
+
{"Wolves": "tab:orange", "Sheep": "tab:cyan", "Grass": "tab:green"}
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
model = WolfSheep(grass=True)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
page = SolaraViz(
|
|
79
|
+
model,
|
|
80
|
+
components=[space_component, lineplot_component],
|
|
81
|
+
model_params=model_params,
|
|
82
|
+
name="Wolf Sheep",
|
|
83
|
+
)
|
|
84
|
+
page # noqa
|
|
@@ -10,10 +10,9 @@ Replication of the model found in NetLogo:
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import mesa
|
|
13
|
+
from mesa.examples.advanced.wolf_sheep.agents import GrassPatch, Sheep, Wolf
|
|
13
14
|
from mesa.experimental.cell_space import OrthogonalMooreGrid
|
|
14
15
|
|
|
15
|
-
from .agents import GrassPatch, Sheep, Wolf
|
|
16
|
-
|
|
17
16
|
|
|
18
17
|
class WolfSheep(mesa.Model):
|
|
19
18
|
"""
|
|
@@ -67,7 +66,7 @@ class WolfSheep(mesa.Model):
|
|
|
67
66
|
once it is eaten
|
|
68
67
|
sheep_gain_from_food: Energy sheep gain from grass, if enabled.
|
|
69
68
|
"""
|
|
70
|
-
super().__init__(seed=
|
|
69
|
+
super().__init__(seed=seed)
|
|
71
70
|
# Set parameters
|
|
72
71
|
self.width = width
|
|
73
72
|
self.height = height
|
|
@@ -81,15 +80,17 @@ class WolfSheep(mesa.Model):
|
|
|
81
80
|
collectors = {
|
|
82
81
|
"Wolves": lambda m: len(m.agents_by_type[Wolf]),
|
|
83
82
|
"Sheep": lambda m: len(m.agents_by_type[Sheep]),
|
|
83
|
+
"Grass": lambda m: len(
|
|
84
|
+
m.agents_by_type[GrassPatch].select(lambda a: a.fully_grown)
|
|
85
|
+
)
|
|
86
|
+
if m.grass
|
|
87
|
+
else -1,
|
|
84
88
|
}
|
|
85
89
|
|
|
86
|
-
if grass:
|
|
87
|
-
collectors["Grass"] = lambda m: len(m.agents_by_type[GrassPatch])
|
|
88
|
-
|
|
89
90
|
self.datacollector = mesa.DataCollector(collectors)
|
|
90
91
|
|
|
91
92
|
# Create sheep:
|
|
92
|
-
for
|
|
93
|
+
for _ in range(self.initial_sheep):
|
|
93
94
|
x = self.random.randrange(self.width)
|
|
94
95
|
y = self.random.randrange(self.height)
|
|
95
96
|
energy = self.random.randrange(2 * self.sheep_gain_from_food)
|
|
@@ -132,5 +133,5 @@ class WolfSheep(mesa.Model):
|
|
|
132
133
|
self.datacollector.collect(self)
|
|
133
134
|
|
|
134
135
|
def run_model(self, step_count=200):
|
|
135
|
-
for
|
|
136
|
+
for _ in range(step_count):
|
|
136
137
|
self.step()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Boids Flockers
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
An implementation of Craig Reynolds's Boids flocker model. Agents (simulated birds) try to fly towards the average position of their neighbors and in the same direction as them, while maintaining a minimum distance. This produces flocking behavior.
|
|
6
|
+
|
|
7
|
+
This model tests Mesa's continuous space feature, and uses numpy arrays to represent vectors.
|
|
8
|
+
|
|
9
|
+
## How to Run
|
|
10
|
+
|
|
11
|
+
* To launch the visualization interactively, run ``solara run app.py`` in this directory.It will automatically open a browser page.
|
|
12
|
+
|
|
13
|
+
## Files
|
|
14
|
+
|
|
15
|
+
* [model.py](model.py): Ccntains the Boid Model
|
|
16
|
+
* [agents.py](agents.py): Contains the Boid agent
|
|
17
|
+
* [app.py](app.py): Solara based Visualization code.
|
|
18
|
+
|
|
19
|
+
## Further Reading
|
|
20
|
+
|
|
21
|
+
The following link can be visited for more information on the boid flockers model:
|
|
22
|
+
https://cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/modeling-natural-systems/boids.html
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
from mesa.
|
|
2
|
-
|
|
3
|
-
from .model import BoidFlockers
|
|
1
|
+
from mesa.examples.basic.boid_flockers.model import BoidFlockers
|
|
2
|
+
from mesa.visualization import Slider, SolaraViz, make_space_component
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
def boid_draw(agent):
|
|
@@ -52,7 +51,7 @@ model = BoidFlockers()
|
|
|
52
51
|
|
|
53
52
|
page = SolaraViz(
|
|
54
53
|
model,
|
|
55
|
-
[
|
|
54
|
+
[make_space_component(agent_portrayal=boid_draw, backend="matplotlib")],
|
|
56
55
|
model_params=model_params,
|
|
57
56
|
name="Boid Flocking Model",
|
|
58
57
|
)
|
|
@@ -12,11 +12,6 @@ As the model runs, the distribution of wealth among agents goes from being perfe
|
|
|
12
12
|
|
|
13
13
|
To follow the tutorial example, launch the Jupyter Notebook and run the code in ``Introduction to Mesa Tutorial Code.ipynb`` which you can find in the main mesa repo [here](https://github.com/projectmesa/mesa/blob/main/docs/tutorials/intro_tutorial.ipynb)
|
|
14
14
|
|
|
15
|
-
Make sure to install the requirements first:
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
$ pip install -r requirements.txt
|
|
19
|
-
```
|
|
20
15
|
|
|
21
16
|
To launch the interactive server, as described in the [last section of the tutorial](https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html#adding-visualization), run:
|
|
22
17
|
|
|
@@ -30,6 +25,7 @@ If your browser doesn't open automatically, point it to [http://127.0.0.1:8765/]
|
|
|
30
25
|
## Files
|
|
31
26
|
|
|
32
27
|
* ``model.py``: Final version of the model.
|
|
28
|
+
* ``agents.py``: Final version of the agent.
|
|
33
29
|
* ``app.py``: Code for the interactive visualization.
|
|
34
30
|
|
|
35
31
|
## Optional
|
|
File without changes
|
|
@@ -1,19 +1,14 @@
|
|
|
1
|
+
from mesa.examples.basic.boltzmann_wealth_model.model import BoltzmannWealthModel
|
|
1
2
|
from mesa.visualization import (
|
|
2
3
|
SolaraViz,
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
make_plot_component,
|
|
5
|
+
make_space_component,
|
|
5
6
|
)
|
|
6
7
|
|
|
7
|
-
from .model import BoltzmannWealthModel
|
|
8
|
-
|
|
9
8
|
|
|
10
9
|
def agent_portrayal(agent):
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if agent.wealth > 0:
|
|
14
|
-
size = 50
|
|
15
|
-
color = "tab:blue"
|
|
16
|
-
return {"size": size, "color": color}
|
|
10
|
+
color = agent.wealth # we are using a colormap to translate wealth to color
|
|
11
|
+
return {"color": color}
|
|
17
12
|
|
|
18
13
|
|
|
19
14
|
model_params = {
|
|
@@ -29,6 +24,11 @@ model_params = {
|
|
|
29
24
|
"height": 10,
|
|
30
25
|
}
|
|
31
26
|
|
|
27
|
+
|
|
28
|
+
def post_process(ax):
|
|
29
|
+
ax.get_figure().colorbar(ax.collections[0], label="wealth", ax=ax)
|
|
30
|
+
|
|
31
|
+
|
|
32
32
|
# Create initial model instance
|
|
33
33
|
model1 = BoltzmannWealthModel(50, 10, 10)
|
|
34
34
|
|
|
@@ -37,8 +37,11 @@ model1 = BoltzmannWealthModel(50, 10, 10)
|
|
|
37
37
|
# Under the hood these are just classes that receive the model instance.
|
|
38
38
|
# You can also author your own visualization elements, which can also be functions
|
|
39
39
|
# that receive the model instance and return a valid solara component.
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
|
|
41
|
+
SpaceGraph = make_space_component(
|
|
42
|
+
agent_portrayal, cmap="viridis", vmin=0, vmax=10, post_process=post_process
|
|
43
|
+
)
|
|
44
|
+
GiniPlot = make_plot_component("Gini")
|
|
42
45
|
|
|
43
46
|
# Create the SolaraViz page. This will automatically create a server and display the
|
|
44
47
|
# visualization elements in a web browser.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import mesa
|
|
2
|
-
|
|
3
|
-
from .agents import MoneyAgent
|
|
2
|
+
from mesa.examples.basic.boltzmann_wealth_model.agents import MoneyAgent
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
class BoltzmannWealthModel(mesa.Model):
|
|
@@ -11,8 +10,8 @@ class BoltzmannWealthModel(mesa.Model):
|
|
|
11
10
|
highly skewed distribution of wealth.
|
|
12
11
|
"""
|
|
13
12
|
|
|
14
|
-
def __init__(self, n=100, width=10, height=10):
|
|
15
|
-
super().__init__()
|
|
13
|
+
def __init__(self, n=100, width=10, height=10, seed=None):
|
|
14
|
+
super().__init__(seed=seed)
|
|
16
15
|
self.num_agents = n
|
|
17
16
|
self.grid = mesa.space.MultiGrid(width, height, True)
|
|
18
17
|
|
|
@@ -9,26 +9,30 @@ The "game" is a zero-player game, meaning that its evolution is determined by it
|
|
|
9
9
|
|
|
10
10
|
## How to Run
|
|
11
11
|
|
|
12
|
-
To run the model interactively
|
|
12
|
+
To run the model interactively you can use either the streamlit or solara version. For solara, you use
|
|
13
13
|
|
|
14
14
|
```
|
|
15
|
-
$
|
|
15
|
+
$ solara run app.py
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
For streamlit, you need
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
$ streamlit run st_app.py
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This will open your browser and show you the controls. You can start the model by hitting the run button.
|
|
19
25
|
|
|
20
26
|
## Files
|
|
21
27
|
|
|
22
28
|
* ``agents.py``: Defines the behavior of an individual cell, which can be in two states: DEAD or ALIVE.
|
|
23
29
|
* ``model.py``: Defines the model itself, initialized with a random configuration of alive and dead cells.
|
|
24
|
-
* ``
|
|
30
|
+
* ``app.py``: Defines an interactive visualization using solara.
|
|
25
31
|
* ``st_app.py``: Defines an interactive visualization using Streamlit.
|
|
26
32
|
|
|
27
33
|
## Optional
|
|
28
34
|
|
|
29
|
-
*
|
|
30
|
-
* For this some additional packages like ``streamlit`` and ``altair`` needs to be installed.
|
|
31
|
-
* Once installed, the app can be opened in the browser using : ``streamlit run st_app.py``
|
|
35
|
+
* For the streamlit version, you need to have streamlit installed (can be done via pip install streamlit)
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
## Further Reading
|
|
File without changes
|
|
@@ -12,10 +12,10 @@ class Cell(Agent):
|
|
|
12
12
|
super().__init__(model)
|
|
13
13
|
self.x, self.y = pos
|
|
14
14
|
self.state = init_state
|
|
15
|
-
self.
|
|
15
|
+
self._next_state = None
|
|
16
16
|
|
|
17
17
|
@property
|
|
18
|
-
def
|
|
18
|
+
def is_alive(self):
|
|
19
19
|
return self.state == self.ALIVE
|
|
20
20
|
|
|
21
21
|
@property
|
|
@@ -31,17 +31,17 @@ class Cell(Agent):
|
|
|
31
31
|
"""
|
|
32
32
|
# Get the neighbors and apply the rules on whether to be alive or dead
|
|
33
33
|
# at the next tick.
|
|
34
|
-
live_neighbors = sum(neighbor.
|
|
34
|
+
live_neighbors = sum(neighbor.is_alive for neighbor in self.neighbors)
|
|
35
35
|
|
|
36
36
|
# Assume nextState is unchanged, unless changed below.
|
|
37
|
-
self.
|
|
38
|
-
if self.
|
|
37
|
+
self._next_state = self.state
|
|
38
|
+
if self.is_alive:
|
|
39
39
|
if live_neighbors < 2 or live_neighbors > 3:
|
|
40
|
-
self.
|
|
40
|
+
self._next_state = self.DEAD
|
|
41
41
|
else:
|
|
42
42
|
if live_neighbors == 3:
|
|
43
|
-
self.
|
|
43
|
+
self._next_state = self.ALIVE
|
|
44
44
|
|
|
45
45
|
def assume_state(self):
|
|
46
46
|
"""Set the state to the new computed state -- computed in step()."""
|
|
47
|
-
self.state = self.
|
|
47
|
+
self.state = self._next_state
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from mesa.examples.basic.conways_game_of_life.model import ConwaysGameOfLife
|
|
2
|
+
from mesa.visualization import (
|
|
3
|
+
SolaraViz,
|
|
4
|
+
make_space_component,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def agent_portrayal(agent):
|
|
9
|
+
return {
|
|
10
|
+
"color": "white" if agent.state == 0 else "black",
|
|
11
|
+
"marker": "s",
|
|
12
|
+
"size": 25,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def post_process(ax):
|
|
17
|
+
ax.set_aspect("equal")
|
|
18
|
+
ax.set_xticks([])
|
|
19
|
+
ax.set_yticks([])
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
model_params = {
|
|
23
|
+
"width": 50,
|
|
24
|
+
"height": 50,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Create initial model instance
|
|
28
|
+
model1 = ConwaysGameOfLife(50, 50)
|
|
29
|
+
|
|
30
|
+
# Create visualization elements. The visualization elements are solara components
|
|
31
|
+
# that receive the model instance as a "prop" and display it in a certain way.
|
|
32
|
+
# Under the hood these are just classes that receive the model instance.
|
|
33
|
+
# You can also author your own visualization elements, which can also be functions
|
|
34
|
+
# that receive the model instance and return a valid solara component.
|
|
35
|
+
SpaceGraph = make_space_component(
|
|
36
|
+
agent_portrayal, post_process=post_process, draw_grid=False
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Create the SolaraViz page. This will automatically create a server and display the
|
|
41
|
+
# visualization elements in a web browser.
|
|
42
|
+
# Display it using the following command in the example directory:
|
|
43
|
+
# solara run app.py
|
|
44
|
+
# It will automatically update and display any changes made to this file
|
|
45
|
+
page = SolaraViz(
|
|
46
|
+
model1,
|
|
47
|
+
components=[SpaceGraph],
|
|
48
|
+
model_params=model_params,
|
|
49
|
+
name="Game of Life",
|
|
50
|
+
)
|
|
51
|
+
page # noqa
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
from mesa import Model
|
|
2
|
+
from mesa.examples.basic.conways_game_of_life.agents import Cell
|
|
2
3
|
from mesa.space import SingleGrid
|
|
3
4
|
|
|
4
|
-
from .agents import Cell
|
|
5
|
-
|
|
6
5
|
|
|
7
6
|
class ConwaysGameOfLife(Model):
|
|
8
7
|
"""Represents the 2-dimensional array of cells in Conway's Game of Life."""
|
|
9
8
|
|
|
10
|
-
def __init__(self, width=50, height=50):
|
|
9
|
+
def __init__(self, width=50, height=50, seed=None):
|
|
11
10
|
"""Create a new playing area of (width, height) cells."""
|
|
12
|
-
super().__init__()
|
|
11
|
+
super().__init__(seed=seed)
|
|
13
12
|
# Use a simple grid, where edges wrap around.
|
|
14
13
|
self.grid = SingleGrid(width, height, torus=True)
|
|
15
14
|
|
|
@@ -4,7 +4,8 @@ import altair as alt
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pandas as pd
|
|
6
6
|
import streamlit as st
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
from mesa.examples.basic.conways_game_of_life.model import ConwaysGameOfLife
|
|
8
9
|
|
|
9
10
|
model = st.title("Conway's Game of Life")
|
|
10
11
|
num_ticks = st.slider("Select number of Steps", min_value=1, max_value=100, value=50)
|