Skip to content

Commit

Permalink
model.agents: Store agents in nested dict keys
Browse files Browse the repository at this point in the history
This commit introduces dics nested into a single defaultdict for agent storage, using agent instances as inner keys and None as inner values. The decision is based on:

1. Determinism: A dictionary ensures deterministic behavior for reproducible research outcomes.
2. Performance: Benchmarks showed that dictionaries offer a good balance between performance and functionality, especially in models with frequent agent updates.
3. Usability and Explicitness: While the use of None values is unconventional, this approach is practical and avoids the complexity of nested structures or external dependencies. It aligns with clear and explicit coding practices, making the framework more accessible and maintainable.

The choice of a defaultdict with None values addresses the need for deterministic behavior, performance efficiency, and clarity in implementation. Additional utility functions like `select_agents()` will be added to enhance usability.

Discussion for historical reference: projectmesa#1894 (comment)
  • Loading branch information
EwoutH authored and tpike3 committed Dec 18, 2023
1 parent 09b3357 commit 9495a5a
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 4 deletions.
4 changes: 2 additions & 2 deletions mesa/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ def __init__(self, unique_id: int, model: Model) -> None:
self.pos: Position | None = None

# Register the agent with the model using defaultdict
self.model.agents[type(self)].append(self)
self.model.agents[type(self)][self] = None

def remove(self) -> None:
"""Remove and delete the agent from the model."""
self.model.agents[type(self)].remove(self)
self.model.agents[type(self)].pop(self)

def step(self) -> None:
"""A single step of the agent."""
Expand Down
5 changes: 3 additions & 2 deletions mesa/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class Model:
running: A boolean indicating if the model should continue running.
schedule: An object to manage the order and execution of agent steps.
current_id: A counter for assigning unique IDs to agents.
agents: A defaultdict mapping each agent type to a list of its instances.
agents: A defaultdict mapping each agent type to a dict of its instances.
Agent instances are saved in the nested dict keys, with the values being None.
"""

def __new__(cls, *args: Any, **kwargs: Any) -> Any:
Expand All @@ -50,7 +51,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
self.running = True
self.schedule = None
self.current_id = 0
self.agents: defaultdict[type, list] = defaultdict(list)
self.agents: defaultdict[type, dict] = defaultdict(dict)

@property
def agent_types(self) -> list:
Expand Down

0 comments on commit 9495a5a

Please sign in to comment.