Skip to content

Fix MultiGrid._empty_mask not updated correctly#3019

Merged
quaquel merged 7 commits intomesa:mainfrom
Nithin9585:fix-multigrid-empty-mask
Dec 31, 2025
Merged

Fix MultiGrid._empty_mask not updated correctly#3019
quaquel merged 7 commits intomesa:mainfrom
Nithin9585:fix-multigrid-empty-mask

Conversation

@Nithin9585
Copy link
Copy Markdown
Contributor

Fixes #3017

MultiGrid.place_agent() and remove_agent() were not correctly updating the _empty_mask array, causing select_cells(only_empty=True) to incorrectly return occupied cells.

Changes

  • Fixed place_agent() to set _empty_mask[pos] = False (occupied) outside the conditional block
  • Fixed remove_agent() to set _empty_mask[pos] = True (empty) when cell becomes empty
  • Added test for _empty_mask behavior

Root Cause

The _empty_mask update was placed inside the if self._empties_built: block, so it only executed when that flag was True. Also, the boolean values were inverted compared to SingleGrid.

@github-actions
Copy link
Copy Markdown

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 -2.5% [-3.6%, -1.4%] 🟢 -3.4% [-3.5%, -3.3%]
BoltzmannWealth large 🔵 -3.8% [-6.6%, +1.1%] 🔵 -1.8% [-3.6%, +0.1%]
Schelling small 🔵 -4.9% [-6.7%, -3.0%] 🔵 -2.3% [-3.4%, -1.3%]
Schelling large 🔵 -1.9% [-3.4%, +1.0%] 🔵 -1.7% [-2.9%, -0.8%]
WolfSheep small 🟢 -4.7% [-6.0%, -3.8%] 🔵 -0.3% [-0.4%, -0.1%]
WolfSheep large 🟢 -6.7% [-12.2%, -3.5%] 🔵 -0.5% [-2.0%, +0.6%]
BoidFlockers small 🔵 +0.4% [+0.1%, +0.8%] 🔵 +0.2% [+0.1%, +0.3%]
BoidFlockers large 🔵 +0.1% [-0.2%, +0.4%] 🔵 +0.1% [-0.1%, +0.3%]

@quaquel quaquel added the bug Release notes label label Dec 30, 2025
if self._empties_built:
self._empties.discard(pos)
self._empty_mask[agent.pos] = True
self._empty_mask[pos] = False
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change the boolean on the empty_mask both in place_agent and remove_agent?

mesa.space is legacy code and will be deprecated. I haven't implemented any of this, so I am trying to get my head around what the empty_maks is supposed to do.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to add: I think the key issue is to clarify what true and false mean in this mask. The proper place to do so would be in line 823, where the mask is initialized. It seems true means that a cell is empty, so then the changes you have made make sense.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quaquel Thanks for reviewing!

_empty_mask tracks cell occupancy: True = empty, False = occupied.

The Bug: The boolean values were inverted, and updates were inside if self._empties_built:, so they only ran when that flag was True.

The Fix:

  • place_agent(): Set _empty_mask[pos] = False (occupied) - moved outside conditional
  • remove_agent(): Set _empty_mask[pos] = True (empty) - moved outside conditional

This keeps _empty_mask synchronized with grid state, fixing select_cells(only_empty=True).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured as much, but it's good to see it confirmed. Could you add a comment to line 823 explaining the meaning of 'true' and 'false' in the mask? Otherwise, this looks fine to me.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quaquel Done! I've added the comment at line 823 explaining that True = cell is empty, False = cell is occupied.

@quaquel quaquel merged commit 8b9da04 into mesa:main Dec 31, 2025
13 of 14 checks passed
@Nithin9585 Nithin9585 deleted the fix-multigrid-empty-mask branch December 31, 2025 09:05
@EwoutH EwoutH changed the title Fix MultiGrid._empty_mask not updated correctly (Issue #3017) Fix MultiGrid._empty_mask not updated correctly Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Release notes label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MultiGrid._empty_mask not updated correctly - select_cells(only_empty=True) returns occupied cells

2 participants