Skip to content
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

Fix AgentSet inplace shuffle (and thus RandomActivation), add tests #2007

Merged
merged 10 commits into from
Jan 26, 2024
4 changes: 2 additions & 2 deletions mesa/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
13 changes: 13 additions & 0 deletions tests/test_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(4)]
EwoutH marked this conversation as resolved.
Show resolved Hide resolved

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))
22 changes: 22 additions & 0 deletions tests/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down
Loading