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

Add select_agents method to Model #1911

Closed
wants to merge 2 commits into from

Conversation

EwoutH
Copy link
Contributor

@EwoutH EwoutH commented Dec 18, 2023

This PR introduces a new select_agents method to the Model class. It's inspired by NetLogo's n-of functions and an earlier concept from @rht as discussed in #1894. It aims to provide a flexible and efficient way to select and filter agents in a model, based on a wide range of criteria.

Features

The select_agents method offers several key functionalities:

  1. Selective quantity (n): Specify the number of agents to select. If n is omitted, all matching agents are chosen.
  2. Criteria-based sorting (sort and direction): Sort agents based on one or more attributes. The sorting order can be set individually for each attribute.
  3. Functional filtering (filter_func): Use a lambda function or a callable to apply complex filter conditions.
  4. Type-based filtering (agent_type): Filter agents by their class type, allowing for selection among specific subclasses.
  5. Flexible size handling (up_to): When True, the method returns up to n agents, which is useful when the available agent count is less than n.

Usage examples

  1. Random Selection of a Specific Number of Agents:

    selected_agents = model.select_agents(n=10)
  2. Sorting and Selecting Agents Based on Multiple Criteria:

    selected_agents = model.select_agents(n=5, sort=['wealth', 'age'], direction=['highest', 'lowest'])
  3. Using a Custom Filter Function:

    selected_agents = model.select_agents(filter_func=lambda agent: agent.energy >= 5)
  4. Selecting Agents of a Specific Type:

    selected_agents = model.select_agents(agent_type=SpecificAgentClass)
  5. Selecting Agents with a Complex Conditional Filter:

    selected_agents = model.select_agents(filter_func=lambda agent: agent.age > 30 and agent.wealth > 50)
  6. Combining Type Filtering with Attribute Sorting:

    selected_agents = model.select_agents(agent_type=WorkerAgent, sort=['experience'], direction=['highest'])
  7. Selecting a Maximum Number of Agents when Available Agents are Fewer:

    selected_agents = model.select_agents(n=15, up_to=True)
  8. Inverse Functional Filtering for Excluding Certain Agents:

    selected_agents = model.select_agents(filter_func=lambda agent: not agent.is_retired)

Implementation Details

This method is implemented in the Model class and tested in test_model.py. The tests cover various scenarios and edge cases, and therefore are examples in themselves.

Review

When reviewing, please:

  • Check the API: Is everything conceptually logically and named right?
  • Check the implementation: Is it performant and implemented following best practice Python?
  • Check the tests: Didn't I forget any edge cases?

Closes #1905.

This commit introduces a new feature to the Mesa Agent-Based Modeling framework: a select_agents method. This enhancement is inspired by NetLogo's n-of functions and a smart idea from @rht as discussed in projectmesa#1894. It aims to provide a flexible and efficient way to select and filter agents in a model, based on a wide range of criteria.

#### Features
The `select_agents` method offers several key functionalities:

1. **Selective Quantity (`n`):** Specify the number of agents to select. If `n` is omitted, all matching agents are chosen.

2. **Criteria-Based Sorting (`sort` and `direction`):** Sort agents based on one or more attributes. The sorting order can be set individually for each attribute.

3. **Functional Filtering (`filter`):** Use a lambda function or a callable to apply complex filter conditions.

4. **Type-Based Filtering (`agent_type`):** Filter agents by their class type, allowing for selection among specific subclasses.

5. **Flexible Size Handling (`up_to`):** When `True`, the method returns up to `n` agents, which is useful when the available agent count is less than `n`.
Copy link

codecov bot commented Dec 18, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (9495a5a) 77.53% compared to head (c8c7a58) 77.99%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1911      +/-   ##
==========================================
+ Coverage   77.53%   77.99%   +0.45%     
==========================================
  Files          15       15              
  Lines        1015     1036      +21     
  Branches      221      231      +10     
==========================================
+ Hits          787      808      +21     
  Misses        197      197              
  Partials       31       31              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@EwoutH
Copy link
Contributor Author

EwoutH commented Dec 18, 2023

Note to self: Check correct randomization of selecting n agents without sorting.

Edit: Implemented in c8c7a58.

When n is defined, it should randomly select n agents. Therefore a shuffle step is added.
@EwoutH
Copy link
Contributor Author

EwoutH commented Dec 18, 2023

Two things I want to explicitly link to this proposal:

  1. @quaquel suggested to consider creating a new AgentSet class, and returning that instead of a list. An AgentSet class could have it's own methods, for example to short or shuffle.
  2. A select_agent() method could help solve a bit part of the problem that we have with multiple agent data collection. I would like to keep in discuss how this method can help, and if we need to add / modify anything to let it be more useful for selecting subsets of agents for datacollection.

@EwoutH EwoutH marked this pull request as draft December 19, 2023 08:58
@EwoutH
Copy link
Contributor Author

EwoutH commented Dec 19, 2023

I'm leaning stronger and stronger in the direction of going with AgentSets. That would mean select_agents() most likely would become an AgentSet method (instead of a Model one), and select should also return another AgentSet.

Let's see how the AgentSet discussion in #1912 progresses before continuing with this PR.

@EwoutH EwoutH mentioned this pull request Dec 19, 2023
@EwoutH
Copy link
Contributor Author

EwoutH commented Dec 26, 2023

Closing this one, the AgentSet now includes this functionality. See #1916.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: Agent selection method
1 participant