Mesa 3.1.5__py3-none-any.whl → 3.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. mesa/__init__.py +3 -1
  2. mesa/agent.py +26 -9
  3. mesa/discrete_space/__init__.py +50 -0
  4. mesa/{experimental/cell_space → discrete_space}/cell.py +29 -10
  5. mesa/{experimental/cell_space → discrete_space}/cell_agent.py +1 -1
  6. mesa/{experimental/cell_space → discrete_space}/cell_collection.py +3 -3
  7. mesa/{experimental/cell_space → discrete_space}/discrete_space.py +65 -3
  8. mesa/{experimental/cell_space → discrete_space}/grid.py +2 -2
  9. mesa/{experimental/cell_space → discrete_space}/network.py +22 -2
  10. mesa/{experimental/cell_space → discrete_space}/property_layer.py +1 -10
  11. mesa/{experimental/cell_space → discrete_space}/voronoi.py +2 -2
  12. mesa/examples/README.md +1 -1
  13. mesa/examples/__init__.py +2 -0
  14. mesa/examples/advanced/alliance_formation/Readme.md +50 -0
  15. mesa/examples/advanced/alliance_formation/__init__ .py +0 -0
  16. mesa/examples/advanced/alliance_formation/agents.py +20 -0
  17. mesa/examples/advanced/alliance_formation/app.py +71 -0
  18. mesa/examples/advanced/alliance_formation/model.py +184 -0
  19. mesa/examples/advanced/epstein_civil_violence/agents.py +1 -1
  20. mesa/examples/advanced/epstein_civil_violence/model.py +1 -1
  21. mesa/examples/advanced/pd_grid/Readme.md +4 -6
  22. mesa/examples/advanced/pd_grid/agents.py +1 -1
  23. mesa/examples/advanced/pd_grid/model.py +1 -1
  24. mesa/examples/advanced/sugarscape_g1mt/Readme.md +4 -5
  25. mesa/examples/advanced/sugarscape_g1mt/agents.py +1 -1
  26. mesa/examples/advanced/sugarscape_g1mt/model.py +2 -2
  27. mesa/examples/advanced/wolf_sheep/Readme.md +2 -17
  28. mesa/examples/advanced/wolf_sheep/agents.py +1 -1
  29. mesa/examples/advanced/wolf_sheep/app.py +2 -1
  30. mesa/examples/advanced/wolf_sheep/model.py +1 -1
  31. mesa/examples/basic/boid_flockers/Readme.md +6 -1
  32. mesa/examples/basic/boid_flockers/agents.py +1 -0
  33. mesa/examples/basic/boid_flockers/app.py +17 -2
  34. mesa/examples/basic/boid_flockers/model.py +12 -0
  35. mesa/examples/basic/boltzmann_wealth_model/Readme.md +2 -12
  36. mesa/examples/basic/boltzmann_wealth_model/agents.py +6 -11
  37. mesa/examples/basic/boltzmann_wealth_model/app.py +2 -2
  38. mesa/examples/basic/boltzmann_wealth_model/model.py +7 -11
  39. mesa/examples/basic/conways_game_of_life/Readme.md +1 -9
  40. mesa/examples/basic/conways_game_of_life/agents.py +13 -5
  41. mesa/examples/basic/conways_game_of_life/model.py +10 -7
  42. mesa/examples/basic/schelling/Readme.md +0 -8
  43. mesa/examples/basic/schelling/agents.py +13 -8
  44. mesa/examples/basic/schelling/model.py +6 -9
  45. mesa/examples/basic/virus_on_network/Readme.md +0 -4
  46. mesa/examples/basic/virus_on_network/agents.py +13 -17
  47. mesa/examples/basic/virus_on_network/model.py +20 -24
  48. mesa/experimental/__init__.py +2 -2
  49. mesa/experimental/cell_space/__init__.py +18 -8
  50. mesa/experimental/meta_agents/__init__.py +25 -0
  51. mesa/experimental/meta_agents/meta_agent.py +387 -0
  52. mesa/model.py +3 -3
  53. mesa/space.py +1 -12
  54. mesa/visualization/__init__.py +2 -0
  55. mesa/visualization/command_console.py +482 -0
  56. mesa/visualization/components/altair_components.py +276 -16
  57. mesa/visualization/mpl_space_drawing.py +17 -9
  58. mesa/visualization/solara_viz.py +150 -21
  59. {mesa-3.1.5.dist-info → mesa-3.2.0.dist-info}/METADATA +12 -8
  60. mesa-3.2.0.dist-info/RECORD +105 -0
  61. mesa-3.1.5.dist-info/RECORD +0 -96
  62. {mesa-3.1.5.dist-info → mesa-3.2.0.dist-info}/WHEEL +0 -0
  63. {mesa-3.1.5.dist-info → mesa-3.2.0.dist-info}/licenses/LICENSE +0 -0
  64. {mesa-3.1.5.dist-info → mesa-3.2.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,6 +1,6 @@
1
1
  from mesa import Model
2
+ from mesa.discrete_space import OrthogonalMooreGrid
2
3
  from mesa.examples.basic.conways_game_of_life.agents import Cell
3
- from mesa.space import SingleGrid
4
4
 
5
5
 
6
6
  class ConwaysGameOfLife(Model):
@@ -10,15 +10,18 @@ class ConwaysGameOfLife(Model):
10
10
  """Create a new playing area of (width, height) cells."""
11
11
  super().__init__(seed=seed)
12
12
  # Use a simple grid, where edges wrap around.
13
- self.grid = SingleGrid(width, height, torus=True)
13
+ self.grid = OrthogonalMooreGrid((width, height), capacity=1, torus=True)
14
14
 
15
15
  # Place a cell at each location, with some initialized to
16
16
  # ALIVE and some to DEAD.
17
- for _contents, (x, y) in self.grid.coord_iter():
18
- cell = Cell((x, y), self)
19
- if self.random.random() < initial_fraction_alive:
20
- cell.state = cell.ALIVE
21
- self.grid.place_agent(cell, (x, y))
17
+ for cell in self.grid.all_cells:
18
+ Cell(
19
+ self,
20
+ cell,
21
+ init_state=Cell.ALIVE
22
+ if self.random.random() < initial_fraction_alive
23
+ else Cell.DEAD,
24
+ )
22
25
 
23
26
  self.running = True
24
27
 
@@ -14,14 +14,6 @@ To run the model interactively, in this directory, run the following command
14
14
  $ solara run app.py
15
15
  ```
16
16
 
17
- Then open your browser to [http://127.0.0.1:8765/](http://127.0.0.1:8765/) and click the Play button.
18
-
19
- To view and run some example model analyses, launch the IPython Notebook and open ``analysis.ipynb``. Visualizing the analysis also requires [matplotlib](http://matplotlib.org/).
20
-
21
- ## How to Run without the GUI
22
-
23
- To run the model with the grid displayed as an ASCII text, run `python run_ascii.py` in this directory.
24
-
25
17
  ## Files
26
18
 
27
19
  * ``model.py``: Contains the Schelling model class
@@ -1,23 +1,28 @@
1
- from mesa import Agent
1
+ from mesa.discrete_space import CellAgent
2
2
 
3
3
 
4
- class SchellingAgent(Agent):
4
+ class SchellingAgent(CellAgent):
5
5
  """Schelling segregation agent."""
6
6
 
7
- def __init__(self, model, agent_type: int) -> None:
7
+ def __init__(
8
+ self, model, cell, agent_type: int, homophily: float = 0.4, radius: int = 1
9
+ ) -> None:
8
10
  """Create a new Schelling agent.
9
11
  Args:
10
12
  model: The model instance the agent belongs to
11
13
  agent_type: Indicator for the agent's type (minority=1, majority=0)
14
+ homophily: Minimum number of similar neighbors needed for happiness
15
+ radius: Search radius for checking neighbor similarity
12
16
  """
13
17
  super().__init__(model)
18
+ self.cell = cell
14
19
  self.type = agent_type
20
+ self.homophily = homophily
21
+ self.radius = radius
15
22
 
16
23
  def step(self) -> None:
17
24
  """Determine if agent is happy and move if necessary."""
18
- neighbors = self.model.grid.get_neighbors(
19
- self.pos, moore=True, radius=self.model.radius
20
- )
25
+ neighbors = list(self.cell.get_neighborhood(radius=self.radius).agents)
21
26
 
22
27
  # Count similar neighbors
23
28
  similar_neighbors = len([n for n in neighbors if n.type == self.type])
@@ -30,7 +35,7 @@ class SchellingAgent(Agent):
30
35
  similarity_fraction = 0.0
31
36
 
32
37
  # Move if unhappy
33
- if similarity_fraction < self.model.homophily:
34
- self.model.grid.move_to_empty(self)
38
+ if similarity_fraction < self.homophily:
39
+ self.cell = self.model.grid.select_random_empty_cell()
35
40
  else:
36
41
  self.model.happy += 1
@@ -1,7 +1,7 @@
1
1
  from mesa import Model
2
2
  from mesa.datacollection import DataCollector
3
+ from mesa.discrete_space import OrthogonalMooreGrid
3
4
  from mesa.examples.basic.schelling.agents import SchellingAgent
4
- from mesa.space import SingleGrid
5
5
 
6
6
 
7
7
  class Schelling(Model):
@@ -31,15 +31,11 @@ class Schelling(Model):
31
31
  super().__init__(seed=seed)
32
32
 
33
33
  # Model parameters
34
- self.height = height
35
- self.width = width
36
34
  self.density = density
37
35
  self.minority_pc = minority_pc
38
- self.homophily = homophily
39
- self.radius = radius
40
36
 
41
37
  # Initialize grid
42
- self.grid = SingleGrid(width, height, torus=True)
38
+ self.grid = OrthogonalMooreGrid((width, height), random=self.random, capacity=1)
43
39
 
44
40
  # Track happiness
45
41
  self.happy = 0
@@ -64,11 +60,12 @@ class Schelling(Model):
64
60
  )
65
61
 
66
62
  # Create agents and place them on the grid
67
- for _, pos in self.grid.coord_iter():
63
+ for cell in self.grid.all_cells:
68
64
  if self.random.random() < self.density:
69
65
  agent_type = 1 if self.random.random() < minority_pc else 0
70
- agent = SchellingAgent(self, agent_type)
71
- self.grid.place_agent(agent, pos)
66
+ SchellingAgent(
67
+ self, cell, agent_type, homophily=homophily, radius=radius
68
+ )
72
69
 
73
70
  # Collect initial state
74
71
  self.datacollector.collect(self)
@@ -38,10 +38,6 @@ To run the model interactively, in this directory, run the following command
38
38
 
39
39
  ## Further Reading
40
40
 
41
- The full tutorial describing how the model is built can be found at:
42
- https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html
43
-
44
-
45
41
  [Stonedahl, F. and Wilensky, U. (2008). NetLogo Virus on a Network model](http://ccl.northwestern.edu/netlogo/models/VirusonaNetwork).
46
42
  Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL.
47
43
 
@@ -1,6 +1,6 @@
1
1
  from enum import Enum
2
2
 
3
- from mesa import Agent
3
+ from mesa.discrete_space import FixedAgent
4
4
 
5
5
 
6
6
  class State(Enum):
@@ -9,7 +9,7 @@ class State(Enum):
9
9
  RESISTANT = 2
10
10
 
11
11
 
12
- class VirusAgent(Agent):
12
+ class VirusAgent(FixedAgent):
13
13
  """Individual Agent definition and its properties/interaction methods."""
14
14
 
15
15
  def __init__(
@@ -20,6 +20,7 @@ class VirusAgent(Agent):
20
20
  virus_check_frequency,
21
21
  recovery_chance,
22
22
  gain_resistance_chance,
23
+ cell,
23
24
  ):
24
25
  super().__init__(model)
25
26
 
@@ -29,19 +30,14 @@ class VirusAgent(Agent):
29
30
  self.virus_check_frequency = virus_check_frequency
30
31
  self.recovery_chance = recovery_chance
31
32
  self.gain_resistance_chance = gain_resistance_chance
33
+ self.cell = cell
32
34
 
33
35
  def try_to_infect_neighbors(self):
34
- neighbors_nodes = self.model.grid.get_neighborhood(
35
- self.pos, include_center=False
36
- )
37
- susceptible_neighbors = [
38
- agent
39
- for agent in self.model.grid.get_cell_list_contents(neighbors_nodes)
40
- if agent.state is State.SUSCEPTIBLE
41
- ]
42
- for a in susceptible_neighbors:
43
- if self.random.random() < self.virus_spread_chance:
44
- a.state = State.INFECTED
36
+ for agent in self.cell.neighborhood.agents:
37
+ if (agent.state is State.SUSCEPTIBLE) and (
38
+ self.random.random() < self.virus_spread_chance
39
+ ):
40
+ agent.state = State.INFECTED
45
41
 
46
42
  def try_gain_resistance(self):
47
43
  if self.random.random() < self.gain_resistance_chance:
@@ -57,13 +53,13 @@ class VirusAgent(Agent):
57
53
  # Failed
58
54
  self.state = State.INFECTED
59
55
 
60
- def try_check_situation(self):
61
- if (self.random.random() < self.virus_check_frequency) and (
62
- self.state is State.INFECTED
56
+ def check_situation(self):
57
+ if (self.state is State.INFECTED) and (
58
+ self.random.random() < self.virus_check_frequency
63
59
  ):
64
60
  self.try_remove_infection()
65
61
 
66
62
  def step(self):
67
63
  if self.state is State.INFECTED:
68
64
  self.try_to_infect_neighbors()
69
- self.try_check_situation()
65
+ self.check_situation()
@@ -4,11 +4,12 @@ import networkx as nx
4
4
 
5
5
  import mesa
6
6
  from mesa import Model
7
+ from mesa.discrete_space import CellCollection, Network
7
8
  from mesa.examples.basic.virus_on_network.agents import State, VirusAgent
8
9
 
9
10
 
10
11
  def number_state(model, state):
11
- return sum(1 for a in model.grid.get_all_cell_contents() if a.state is state)
12
+ return sum(1 for a in model.grid.all_cells.agents if a.state is state)
12
13
 
13
14
 
14
15
  def number_infected(model):
@@ -38,18 +39,13 @@ class VirusOnNetwork(Model):
38
39
  seed=None,
39
40
  ):
40
41
  super().__init__(seed=seed)
41
- self.num_nodes = num_nodes
42
- prob = avg_node_degree / self.num_nodes
43
- self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=prob)
44
- self.grid = mesa.space.NetworkGrid(self.G)
42
+ prob = avg_node_degree / num_nodes
43
+ graph = nx.erdos_renyi_graph(n=num_nodes, p=prob)
44
+ self.grid = Network(graph, capacity=1, random=self.random)
45
45
 
46
46
  self.initial_outbreak_size = (
47
47
  initial_outbreak_size if initial_outbreak_size <= num_nodes else num_nodes
48
48
  )
49
- self.virus_spread_chance = virus_spread_chance
50
- self.virus_check_frequency = virus_check_frequency
51
- self.recovery_chance = recovery_chance
52
- self.gain_resistance_chance = gain_resistance_chance
53
49
 
54
50
  self.datacollector = mesa.DataCollector(
55
51
  {
@@ -60,23 +56,23 @@ class VirusOnNetwork(Model):
60
56
  }
61
57
  )
62
58
 
63
- # Create agents
64
- for node in self.G.nodes():
65
- a = VirusAgent(
66
- self,
67
- State.SUSCEPTIBLE,
68
- self.virus_spread_chance,
69
- self.virus_check_frequency,
70
- self.recovery_chance,
71
- self.gain_resistance_chance,
72
- )
73
-
74
- # Add the agent to the node
75
- self.grid.place_agent(a, node)
59
+ VirusAgent.create_agents(
60
+ self,
61
+ num_nodes,
62
+ State.SUSCEPTIBLE,
63
+ virus_spread_chance,
64
+ virus_check_frequency,
65
+ recovery_chance,
66
+ gain_resistance_chance,
67
+ list(self.grid.all_cells),
68
+ )
76
69
 
77
70
  # Infect some nodes
78
- infected_nodes = self.random.sample(list(self.G), self.initial_outbreak_size)
79
- for a in self.grid.get_cell_list_contents(infected_nodes):
71
+ infected_nodes = CellCollection(
72
+ self.random.sample(list(self.grid.all_cells), self.initial_outbreak_size),
73
+ random=self.random,
74
+ )
75
+ for a in infected_nodes.agents:
80
76
  a.state = State.INFECTED
81
77
 
82
78
  self.running = True
@@ -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, continuous_space, devs, mesa_signals
18
+ from mesa.experimental import continuous_space, devs, mesa_signals, meta_agents
19
19
 
20
- __all__ = ["cell_space", "continuous_space", "devs", "mesa_signals"]
20
+ __all__ = ["continuous_space", "devs", "mesa_signals", "meta_agents"]
@@ -15,23 +15,25 @@ like resource growth, pollution diffusion, or infrastructure networks. The cell
15
15
  space system is experimental and under active development.
16
16
  """
17
17
 
18
- from mesa.experimental.cell_space.cell import Cell
19
- from mesa.experimental.cell_space.cell_agent import (
18
+ import warnings
19
+
20
+ from mesa.discrete_space.cell import Cell
21
+ from mesa.discrete_space.cell_agent import (
20
22
  CellAgent,
21
23
  FixedAgent,
22
24
  Grid2DMovingAgent,
23
25
  )
24
- from mesa.experimental.cell_space.cell_collection import CellCollection
25
- from mesa.experimental.cell_space.discrete_space import DiscreteSpace
26
- from mesa.experimental.cell_space.grid import (
26
+ from mesa.discrete_space.cell_collection import CellCollection
27
+ from mesa.discrete_space.discrete_space import DiscreteSpace
28
+ from mesa.discrete_space.grid import (
27
29
  Grid,
28
30
  HexGrid,
29
31
  OrthogonalMooreGrid,
30
32
  OrthogonalVonNeumannGrid,
31
33
  )
32
- from mesa.experimental.cell_space.network import Network
33
- from mesa.experimental.cell_space.property_layer import PropertyLayer
34
- from mesa.experimental.cell_space.voronoi import VoronoiGrid
34
+ from mesa.discrete_space.network import Network
35
+ from mesa.discrete_space.property_layer import PropertyLayer
36
+ from mesa.discrete_space.voronoi import VoronoiGrid
35
37
 
36
38
  __all__ = [
37
39
  "Cell",
@@ -48,3 +50,11 @@ __all__ = [
48
50
  "PropertyLayer",
49
51
  "VoronoiGrid",
50
52
  ]
53
+
54
+
55
+ warnings.warn(
56
+ "you are importing from mesa.experimental.cell_space, "
57
+ "all cell spaces have been moved to mesa.discrete_space",
58
+ DeprecationWarning,
59
+ stacklevel=2,
60
+ )
@@ -0,0 +1,25 @@
1
+ """This method is for dynamically creating new agents (meta-agents).
2
+
3
+ Meta-agents are defined as agents composed of existing agents.
4
+
5
+ Meta-agents are created dynamically with a pointer to the model, name of the meta-agent,,
6
+ iterable of agents to belong to the new meta-agents, any new functions for the meta-agent,
7
+ any new attributes for the meta-agent, whether to retain sub-agent functions,
8
+ whether to retain sub-agent attributes.
9
+
10
+ Examples of meta-agents:
11
+ - An autonomous car where the subagents are the wheels, sensors,
12
+ battery, computer etc. and the meta-agent is the car itself.
13
+ - A company where the subagents are employees, departments, buildings, etc.
14
+ - A city where the subagents are people, buildings, streets, etc.
15
+
16
+ Currently meta-agents are restricted to one parent agent for each subagent/
17
+ one meta-agent per subagent.
18
+
19
+ Goal is to assess usage and expand functionality.
20
+
21
+ """
22
+
23
+ from .meta_agent import MetaAgent
24
+
25
+ __all__ = ["MetaAgent"]