Skip to content

fix: update alliance_formation example to use AgentSet.to_list()#3235

Merged
quaquel merged 9 commits intomesa:mainfrom
souro26:fix-alliance-formation-agentset-deprecation
Feb 1, 2026
Merged

fix: update alliance_formation example to use AgentSet.to_list()#3235
quaquel merged 9 commits intomesa:mainfrom
souro26:fix-alliance-formation-agentset-deprecation

Conversation

@souro26
Copy link
Copy Markdown
Contributor

@souro26 souro26 commented Jan 31, 2026

Summary

Updates the alliance_formation example model to use the new AgentSet.to_list() method instead of deprecated direct indexing.

Bug / Issue

The alliance_formation model uses deprecated AgentSet.__getitem__ (e.g., agents[0]), which was deprecated in #3208 and will be removed in Mesa 4.0.
This triggers PendingDeprecationWarning when running the example, and since this is a reference example that users often copy, it should demonstrate current best practices.

Implementation

Replaced direct indexing:

agent_0 = agents[0]
agent_1 = agents[1]

With the recommended pattern from the migration guide (#3218):

agent_list = agents.to_list()
agent_0 = agent_list[0]
agent_1 = agent_list[1]

Testing

Ran the alliance_formation example test:

pytest tests/examples/test_examples.py::test_alliance_formation_model -v

Additional Notes

Follow-up to #3208 and #3218.
This change eliminates deprecation warnings in the alliance_formation example model.

@github-actions
Copy link
Copy Markdown

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 -1.4% [-1.6%, -1.1%] 🔵 -1.2% [-1.4%, -1.1%]
BoltzmannWealth large 🔵 +1.5% [+0.9%, +2.1%] 🔵 -0.3% [-0.8%, +0.2%]
Schelling small 🔵 +0.6% [+0.4%, +0.8%] 🔵 +0.7% [+0.7%, +0.8%]
Schelling large 🔵 +0.7% [+0.2%, +1.2%] 🔴 +3.5% [+3.1%, +3.9%]
WolfSheep small 🔵 -1.4% [-1.6%, -1.3%] 🔵 -0.5% [-0.7%, -0.3%]
WolfSheep large 🔵 -0.7% [-1.5%, +0.1%] 🔵 -0.9% [-1.4%, -0.5%]
BoidFlockers small 🔵 -0.1% [-0.3%, +0.2%] 🔵 +1.7% [+1.5%, +1.8%]
BoidFlockers large 🔵 +0.1% [-0.3%, +0.5%] 🔵 +1.6% [+1.2%, +2.0%]

agent_1 = agents[1]
agent_list = agents.to_list()
agent_0 = agent_list[0]
agent_1 = agent_list[1]
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 suggest fixing this find_combinations instead.

@souro26
Copy link
Copy Markdown
Contributor Author

souro26 commented Feb 1, 2026

Thanks for the quick review @quaquel.

I double-checked find_combinations, and it doesn’t use deprecated indexing. The deprecated access was in calculate_shapley_value, which is now resolved by converting the AgentSet once via to_list(). I avoided changing find_combinations since converting the AgentSet there would alter its iteration semantics. Please let me know if you’d prefer a different approach.

@quaquel
Copy link
Copy Markdown
Member

quaquel commented Feb 1, 2026

That is not entirely true. Look at the typing of find_combinations. group is an AgentSet. This should be changed to a list, or, looking at the code, an iterable. Next, evaluate_combination explicitly puts the group (which is typed as a tuple) into an agent set. This line should be removed. Also, the typing of evaluation_func should be updated across all of meta_agents.py.

@quaquel quaquel added the bug Release notes label label Feb 1, 2026
souro26 and others added 2 commits February 1, 2026 23:11
- Update find_combinations to operate on iterables/tuples
- Remove intermediate AgentSet creation in evaluate_combination
- Update evaluation_func typing across meta_agents
- Adjust alliance_formation example to convert tuple to AgentSet internally
@souro26
Copy link
Copy Markdown
Contributor Author

souro26 commented Feb 1, 2026

Thanks for the clarification — I’ve updated the implementation accordingly.

Changes made:

  • Updated evaluation_func typing across meta_agents.py to operate on tuple[Agent, ...]

  • Removed internal AgentSet construction from evaluate_combination

  • Updated find_combinations to accept AgentSet | Iterable, converting once for iteration

  • Updated the alliance_formation example to explicitly convert the tuple to AgentSet only where AgentSet-specific methods are required

I’ve also noticed a couple of now-redundant lines in calculate_shapley_value (duplicate agent extraction / AgentSet usage) and can clean those up if you’d like me to push a small follow-up commit.

All relevant tests are passing:

  • tests/experimental/test_meta_agents.py

  • tests/examples/test_examples.py::test_alliance_formation_model

I'm happy to adjust further based on your preference.

def find_combinations(
model,
group: AgentSet,
group: AgentSet | list | Iterable,
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.

Suggested change
group: AgentSet | list | Iterable,
group: Iterable,

iterable is enough here. AgentSet and list are already iterable so no need to add them here.

Args:
model: The model instance.
group (AgentSet): The set of agents to find combinations in.
group (AgentSet | list | Iterable): The set of agents to find combinations in.
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.

please remove all typing from docstring. Should not be there if typing is used.

Comment on lines +103 to +107
if isinstance(group, AgentSet):
agent_list = group.to_list()
else:
agent_list = list(group) if not isinstance(group, list) else group

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.

not needed at all.

Comment on lines +100 to +101
group_set = AgentSet(group, random=self.random)
agent_ids = sorted(group_set.get("unique_id")) # by default is bilateral
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.

you don't need an agentset here. You can just use operator.itemgetter instead as key in sorted.

@quaquel
Copy link
Copy Markdown
Member

quaquel commented Feb 1, 2026

I’ve also noticed a couple of now-redundant lines in calculate_shapley_value (duplicate agent extraction / AgentSet usage) and can clean those up if you’d like me to push a small follow-up commit.

Please do.

- Remove unnecessary AgentSet conversions
- Accept Iterable directly in find_combinations
- Simplify calculate_shapley_value agent handling
- Clean up redundant logic per review feedback
@souro26 souro26 force-pushed the fix-alliance-formation-agentset-deprecation branch from 9de6e4c to 95d97c7 Compare February 1, 2026 20:00
agent_0 = agents[0]
agent_1 = agents[1]
agent_0, agent_1 = agents
agent_set = AgentSet(agents, random=self.random)
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.

this should not be needed at all.

positions = agent_set.get("position")
new_position = 1 - (max(positions) - min(positions))
potential_utility = agents.agg("power", sum) * 1.2 * new_position
potential_utility = agent_set.agg("power", sum) * 1.2 * new_position
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.

You only have 2 agents, so why use an aggregation here? Just write it up explicitly for 2 agents.

@souro26
Copy link
Copy Markdown
Contributor Author

souro26 commented Feb 1, 2026

Thanks for the feedback, it makes sense I'll simplify it to use the attributes directly since it's just 2 agents.

@quaquel quaquel merged commit 2f2656b into mesa:main Feb 1, 2026
11 of 12 checks passed
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.

2 participants