diff --git a/mesa/agent.py b/mesa/agent.py index fcf643d3289..6155284ba42 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -54,6 +54,7 @@ def __init__(self, unique_id: int, model: Model) -> None: except AttributeError: # model super has not been called self.model.agents_ = defaultdict(dict) + self.model.agents_[type(self)][self] = None self.model.agentset_experimental_warning_given = False warnings.warn( diff --git a/mesa/time.py b/mesa/time.py index 87a68949cdd..7a253076614 100644 --- a/mesa/time.py +++ b/mesa/time.py @@ -143,8 +143,8 @@ def get_agent_keys(self, shuffle: bool = False) -> list[int]: def do_each(self, method, shuffle=False): if shuffle: - self.agents.shuffle(inplace=True) - self.agents.do(method) + self._agents.shuffle(inplace=True) + self._agents.do(method) class RandomActivation(BaseScheduler): diff --git a/tests/test_agent.py b/tests/test_agent.py index 5861038d793..60a0eec15fa 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -251,3 +251,16 @@ def test_agentset_select_by_type(): # Test with no type specified (should select all agents) all_agents = agentset.select() assert len(all_agents) == len(mixed_agents) + + +def test_agentset_shuffle(): + model = Model() + test_agents = [TestAgent(model.next_id(), model) for _ in range(12)] + + agentset = AgentSet(test_agents, model=model) + agentset = agentset.shuffle() + assert not all(a1 == a2 for a1, a2 in zip(test_agents, agentset)) + + agentset = AgentSet(test_agents, model=model) + agentset.shuffle(inplace=True) + assert not all(a1 == a2 for a1, a2 in zip(test_agents, agentset)) diff --git a/tests/test_time.py b/tests/test_time.py index 3cfc2f35078..53967d1a8ef 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -224,6 +224,28 @@ def test_get_agent_keys(self): agent_ids = {agent.unique_id for agent in model.agents} assert all(entry in agent_ids for entry in keys) + def test_not_sequential(self): + model = MockModel(activation=RANDOM) + # Create 10 agents + for _ in range(10): + model.schedule.add(MockAgent(model.next_id(), model)) + # Run 3 steps + for _ in range(3): + model.step() + # Filter out non-integer elements from the log + filtered_log = [item for item in model.log if isinstance(item, int)] + + # Check that there are no 18 consecutive agents id's in the filtered log + total_agents = 10 + assert not any( + all( + (filtered_log[(i + j) % total_agents] - filtered_log[i]) % total_agents + == j % total_agents + for j in range(18) + ) + for i in range(len(filtered_log)) + ), f"Agents are activated sequentially:\n{filtered_log}" + class TestSimultaneousActivation(TestCase): """