Skip to content

first proposal for a memory module in mesa #2735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions mesa/experimental/devs/memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""An entry-recording functionality designed to be used as the memory of an agent.

This module provides the foundational class needed for storing information in the memory of an agent.
Then objective is to implement a very simple and efficient system that can be used for any agent and
for any kind of information (an entry). The user defines the capacity of the memory chooses the format
of the entries, which allows for a greater flexibility. Key features:

- Capacity-based memory, with a FIFO system
- Efficient storage and retrieval of entries
- Support for different entry_types of entries
- Possibility to send entries to other agents

For now, the module contains only one main component:
- Memory: A class representing the memory of an agent

"""

# from experimental.devs.eventlist import EventList, SimulationEvent
import copy
import itertools
from collections import OrderedDict
from typing import Any

Check warning on line 22 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L19-L22

Added lines #L19 - L22 were not covered by tests

from mesa.model import Model

Check warning on line 24 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L24

Added line #L24 was not covered by tests


class Memory:

Check warning on line 27 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L27

Added line #L27 was not covered by tests
"""The memory of an Agent : it can store any kind of information based on a unique id of the form (agent_id, entry_id) to ensure the uniqueness of the entry.

Attributes:
model (Model): The used model
agent_id (int): The id of the agent
capacity (int): The capacity of the memory

Structure of one entry (example):
"entry_id" : {
"external_agent_id" : external_agent_id, # Not mandatory : represents the agent that sent the entry (if memory was received)
"entry_step" : 1,
"entry_type" : "position",
"entry_content" : [1,2]
},

"""

def __init__(self, model: Model, agent_id: int, capacity: int):

Check warning on line 45 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L45

Added line #L45 was not covered by tests
"""Initializes the agent memory."""
self.model = model
self.capacity = capacity
self.agent_id = agent_id
self._ids = itertools.count()

Check warning on line 50 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L47-L50

Added lines #L47 - L50 were not covered by tests

self.memory_storage = OrderedDict()

Check warning on line 52 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L52

Added line #L52 was not covered by tests

def remember(

Check warning on line 54 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L54

Added line #L54 was not covered by tests
self, entry_content: Any, entry_type: Any, external_agent_id=None
) -> tuple:
"""Store an entry in the memory."""
entry_id = (self.agent_id, next(self._ids))

Check warning on line 58 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L58

Added line #L58 was not covered by tests

# creation of a new entry in the memory
if entry_id not in self.memory_storage:
self.memory_storage[entry_id] = OrderedDict()

Check warning on line 62 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L62

Added line #L62 was not covered by tests

self.memory_storage[entry_id]["entry_content"] = entry_content
self.memory_storage[entry_id]["entry_type"] = entry_type
self.memory_storage[entry_id]["entry_step"] = self.model.steps

Check warning on line 66 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L64-L66

Added lines #L64 - L66 were not covered by tests

if external_agent_id is not None:
self.memory_storage[entry_id]["external_agent_id"] = external_agent_id

Check warning on line 69 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L69

Added line #L69 was not covered by tests

# if the memory is longer than the capacity, we remove the oldest entry
if len(self.memory_storage) > self.capacity:
self.memory_storage.popitem(last=False)

Check warning on line 73 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L73

Added line #L73 was not covered by tests

return entry_id

Check warning on line 75 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L75

Added line #L75 was not covered by tests

def recall(self, entry_id):

Check warning on line 77 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L77

Added line #L77 was not covered by tests
"""Recall a specific entry."""
# Verification of the existence of the entry
if entry_id not in self.memory_storage:
return None
return self.memory_storage[entry_id]

Check warning on line 82 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L81-L82

Added lines #L81 - L82 were not covered by tests

def get_by_type(self, entry_type: str) -> list:

Check warning on line 84 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L84

Added line #L84 was not covered by tests
"""Returns all the ids of the entries of a specific entry_type."""
entry_list = [

Check warning on line 86 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L86

Added line #L86 was not covered by tests
entry_id
for entry_id, entry in self.memory_storage.items()
if entry["entry_type"] == entry_type
]
return entry_list

Check warning on line 91 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L91

Added line #L91 was not covered by tests

def forget(self, entry_id):

Check warning on line 93 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L93

Added line #L93 was not covered by tests
"""Forget a specific entry."""
if entry_id in self.memory_storage:
self.memory_storage.pop(entry_id)

Check warning on line 96 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L96

Added line #L96 was not covered by tests

def tell_to(self, entry_id, external_agent):

Check warning on line 98 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L98

Added line #L98 was not covered by tests
"""Send a precise memory to another agent by making a deep copy of the entry."""
entry_copy = copy.deepcopy(self.memory_storage[entry_id])
new_entry_id = external_agent.memory.remember(

Check warning on line 101 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L100-L101

Added lines #L100 - L101 were not covered by tests
entry_copy["entry_content"],
entry_copy["entry_type"],
external_agent_id=self.agent_id,
)

return new_entry_id

Check warning on line 107 in mesa/experimental/devs/memory.py

View check run for this annotation

Codecov / codecov/patch

mesa/experimental/devs/memory.py#L107

Added line #L107 was not covered by tests
Loading