From 2b0be4681b339a63337a15ac63a171ba48ae5544 Mon Sep 17 00:00:00 2001 From: Tom Pike Date: Fri, 20 Dec 2024 06:55:33 -0500 Subject: [PATCH 1/4] meta-agent creation - adds ability to dynamically create meta-agents - adds alliance formation model to demonstrate - adds tests to agent.py for meta agent creation --- mesa/agent.py | 98 ++++++++++++++++++- .../basic/alliance_formation_model/Readme.md | 41 ++++++++ .../alliance_formation_model/__init__.py | 0 .../basic/alliance_formation_model/agents.py | 68 +++++++++++++ .../basic/alliance_formation_model/app.py | 75 ++++++++++++++ .../basic/alliance_formation_model/model.py | 37 +++++++ tests/test_agent.py | 48 +++++++++ 7 files changed, 366 insertions(+), 1 deletion(-) create mode 100644 mesa/examples/basic/alliance_formation_model/Readme.md create mode 100644 mesa/examples/basic/alliance_formation_model/__init__.py create mode 100644 mesa/examples/basic/alliance_formation_model/agents.py create mode 100644 mesa/examples/basic/alliance_formation_model/app.py create mode 100644 mesa/examples/basic/alliance_formation_model/model.py diff --git a/mesa/agent.py b/mesa/agent.py index 5cfc1131e2c..62f5e6a8610 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -67,7 +67,10 @@ def __init__(self, model: Model, *args, **kwargs) -> None: self.unique_id: int = next(self._ids[model]) self.pos: Position | None = None self.model.register_agent(self) - + # Private attribute to track parent agent if metaagents are created + # Uses name mangling to prevent name clashes + self.__metaagent = None # Currently restricted to one parent agent + def remove(self) -> None: """Remove and delete the agent from the model. @@ -132,7 +135,100 @@ def __getitem__(self, i): agent = cls(model, *instance_args, **instance_kwargs) agents.append(agent) return AgentSet(agents, random=model.random) + + def create_metaagent(self, new_agent_class: str, agents: Iterable[Agent], **unique_attributes_functions) -> None: + + """Dynamically create a new meta-agent class and instantiate agents in that class. + + Args: + new_agent_class (str): The name of the new meta-agent class. + agents (Iterable[Agent]): The agents to be grouped into the new meta-agent class. + **unique_attributes_functions: A dictionary of unique attributes for that class. + + Returns: + Adds the new meta-agent instance to agentset if adding agent to new class or new agent instance + - None if adding agent to exsiting class + - New class instance if created a new instance of a dynamically created agent type + - New class instance if created a new dynamically created agent type + Notes: + This method is useful for creating meta-agents that represent groups of agents with interdependent characteristics. + The new meta-agent class is created dynamically using the provided name and unique attributes and functions. + + Currently restricted to one parent agent and one meta-agent per agent. Goal is to assess usage and expand functionality. + + Method has three paths of execution: + 1. Add agents to existing metaagent + 2. Create new meta-agent instance of existing metaagent class + 3. Create new meta-agent class + + See alliance formation example for usage. + + """ + # Convert agents to set to ensure uniqueness + agents = set(agents) + + # Helper function to update agents __metaagent attribute and store agent's metaagent + def update_agents_metaagent(agents, metaagent): + for agent in agents: + agent._Agent__metaagent = metaagent + + # Path 1 - Add agents to existing meta-agent + subagents = [agent for agent in agents if agent._Agent__metaagent is not None] + + if len(subagents) > 0: + if len(subagents) == 1: + # Update metaagents agent set with new agents + subagents[0]._Agent__metaagent.agents.update(agents) + # Update subagents with metaagent + update_agents_metaagent(agents, subagents[0]._Agent__metaagent) + else: + # If there are multiple subagents, one is chosen at random to be the parent metaagent + subagent = self.random.choice(subagents) + # Remove agent who are already part of metaagent + agents = set(agents) - set(subagents) + subagent._Agent__metaagent.agents.update(agents) + update_agents_metaagent(agents, subagent._Agent__metaagent) + # TODO: Add way for user to add function to specify how agents join metaagent + + else: + # Path 2 - Create a new instance of an exsiting meta-agent class + agent_class = next((agent_type for agent_type in self.model.agent_types if agent_type.__name__ == new_agent_class), None) + if agent_class: + # Create an instance of the meta-agent class + meta_agent_instance = agent_class(self.model, **unique_attributes_functions) + # Add agents to meta-agent instance + meta_agent_instance.agents = agents + # Update subagents Agent.__metaagent attribute + update_agents_metaagent(agents, meta_agent_instance) + # Register the new meta-agent instance + self.model.register_agent(meta_agent_instance) + + return meta_agent_instance + + # Path 3 - Create a new meta-agent class + else: + # Get agent types of subagents to create the new meta-agent class + agent_types = tuple(set((type(agent) for agent in agents))) + + meta_agent_class = type( + new_agent_class, + agent_types, + { + "unique_id": None, + "agents": agents, + } + ) + + # Create an instance of the meta-agent class + meta_agent_instance = meta_agent_class(self.model, **unique_attributes_functions) + # Register the new meta-agent instance + self.model.register_agent(meta_agent_instance) + # Update subagents Agent.__metaagent attribute + update_agents_metaagent(agents, meta_agent_instance) + + return meta_agent_instance + @property def random(self) -> Random: """Return a seeded stdlib rng.""" diff --git a/mesa/examples/basic/alliance_formation_model/Readme.md b/mesa/examples/basic/alliance_formation_model/Readme.md new file mode 100644 index 00000000000..195522eacd4 --- /dev/null +++ b/mesa/examples/basic/alliance_formation_model/Readme.md @@ -0,0 +1,41 @@ +# Alliance Formation Model + +## Summary + +This model demonstrates Mesa's ability to dynamically create new classes of agents that are composed of existing agents. These meta-agents inherits functions and attributes from their sub-agents and users can specify new functionality or attributes they want the meta agent to have. For example, if a user is doing a factory simulation with autonomous systems, each major component of that system can be a sub-agent of the overall robot agent. Or, if someone is doing a simulation of an organization, individuals can be part of different organizational units that are working for some purpose. + +To provide a simple demonstration of this capability is an alliance formation model. + +In this simulation n agents are created, who have two attributes (1) power and (2) preference. Each attribute is a number between 0 and 1 over a gaussian distribution. Agents then randomly select other agents and use the [bilateral shapley value](https://en.wikipedia.org/wiki/Shapley_value) to determine if they should form an alliance. If the expected utility support an alliances, the agent creates a meta-agent. Subsequent steps may add agents to the meta-agent, create new instances of similar hierarchy, or create a new hierarchy level where meta-agents form an alliance of meta-agents. In this visualization of this model a new meta-agent hierarchy will be a larger node and a new color. + +In its current configuration, agents being part of multiple meta-agents is not supported + +## Installation + +This model requires Mesa's recommended install +``` + $ pip install mesa[rec] +``` + +## How to Run + +To run the model interactively, in this directory, run the following command + +``` + $ solara run app.py +``` + +## Files + +* ``model.py``: Contains creation of agents, the network and management of agent execution. +* ``agents.py``: Contains logic for forming alliances and creation of new agents +* ``app.py``: Contains the code for the interactive Solara visualization. + +## Further Reading + +The full tutorial describing how the model is built can be found at: +https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html + +An example of the bilateral shapley value in another model: +[Techno-Social Energy Infrastructure Siting: Sustainable Energy Modeling Programming (SEMPro)](https://www.jasss.org/16/3/6.html) + diff --git a/mesa/examples/basic/alliance_formation_model/__init__.py b/mesa/examples/basic/alliance_formation_model/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mesa/examples/basic/alliance_formation_model/agents.py b/mesa/examples/basic/alliance_formation_model/agents.py new file mode 100644 index 00000000000..7f8a8fd3c33 --- /dev/null +++ b/mesa/examples/basic/alliance_formation_model/agents.py @@ -0,0 +1,68 @@ +import mesa + + +def calculate_shapley_value(self, other_agent): + """ + Calculate the Shapley value of the two agents + """ + other_agent.hierarchy = other_agent.hierarchy + self.hierarchy = self.hierarchy + new_position = 1 - abs(self.position - other_agent.position) + potential_utility = (self.power + other_agent.power) * 1.1 * new_position + value_me = 0.5 * self.power + 0.5 * (potential_utility - other_agent.power) + value_other = 0.5 * other_agent.power + 0.5 * (potential_utility - self.power) + + # Determine ig there is value in the alliance + if value_me > self.power and value_other > other_agent.power: + if other_agent.hierarchy > self.hierarchy: + hierarchy = other_agent.hierarchy + elif other_agent.hierarchy == self.hierarchy: + hierarchy = self.hierarchy + 1 + else: + hierarchy = self.hierarchy + + return (potential_utility, new_position, hierarchy) + else: + return None + + +class AllianceAgent(mesa.Agent): + """ + Agent has three attributes power (float), position (float) and hierarchy (int) + + """ + + def __init__(self, model, power, position, hierarchy=0): + super().__init__(model) + self.power = power + self.position = position + self.hierarchy = hierarchy + + def form_alliance(self): + # Randomly select another agent of the same type + other_agents = [ + agent for agent in self.model.agents_by_type[type(self)] if agent != self + ] + + # Determine if there is a beneficial alliance + if other_agents: + other_agent = self.random.choice(other_agents) + shapley_value = calculate_shapley_value(self, other_agent) + if shapley_value: + class_name = f"MetaAgentHierarchy{shapley_value[2]}" + meta = self.create_metaagent( + class_name, + {other_agent, self}, + hierarchy=shapley_value[2], + power=shapley_value[0], + position=shapley_value[1], + ) + + # Update the network if a new meta agent instance created + if meta: + self.model.network.add_node( + meta.unique_id, size=(meta.hierarchy + 1) * 200 + ) + self.model.new_agents = True + else: + self.model.new_agents = False diff --git a/mesa/examples/basic/alliance_formation_model/app.py b/mesa/examples/basic/alliance_formation_model/app.py new file mode 100644 index 00000000000..c894395acfc --- /dev/null +++ b/mesa/examples/basic/alliance_formation_model/app.py @@ -0,0 +1,75 @@ +import matplotlib.pyplot as plt +import networkx as nx +import solara +from matplotlib.figure import Figure + +from mesa.examples.basic.alliance_formation.model import AllianceModel +from mesa.mesa_logging import DEBUG, log_to_stderr +from mesa.visualization import SolaraViz +from mesa.visualization.utils import update_counter + +log_to_stderr(DEBUG) + + +model_params = { + "seed": { + "type": "InputText", + "value": 42, + "label": "Random Seed", + }, + "n": { + "type": "SliderInt", + "value": 50, + "label": "Number of agents:", + "min": 10, + "max": 100, + "step": 1, + }, +} + +# Create visualization elements. The visualization elements are solara components +# that receive the model instance as a "prop" and display it in a certain way. +# Under the hood these are just classes that receive the model instance. +# You can also author your own visualization elements, which can also be functions +# that receive the model instance and return a valid solara component. + + +@solara.component +def plot_network(model): + update_counter.get() + g = model.network + pos = nx.spring_layout(g) + fig = Figure() + ax = fig.subplots() + labels = {agent.unique_id: agent.unique_id for agent in model.agents} + node_sizes = [g.nodes[node]["size"] for node in g.nodes] + node_colors = [g.nodes[node]["size"] for node in g.nodes()] + + nx.draw( + g, + pos, + node_size=node_sizes, + node_color=node_colors, + cmap=plt.cm.coolwarm, + labels=labels, + ax=ax, + ) + + solara.FigureMatplotlib(fig) + + +# Create initial model instance +model = AllianceModel(50) + +# Create the SolaraViz page. This will automatically create a server and display the +# visualization elements in a web browser. +# Display it using the following command in the example directory: +# solara run app.py +# It will automatically update and display any changes made to this file +page = SolaraViz( + model, + components=[plot_network], + model_params=model_params, + name="Alliance Formation Model", +) +page # noqa diff --git a/mesa/examples/basic/alliance_formation_model/model.py b/mesa/examples/basic/alliance_formation_model/model.py new file mode 100644 index 00000000000..acca61b92a1 --- /dev/null +++ b/mesa/examples/basic/alliance_formation_model/model.py @@ -0,0 +1,37 @@ +import networkx as nx +import numpy as np +from agents import AllianceAgent + +import mesa + + +class AllianceModel(mesa.Model): + def __init__(self, n=50, mean=0.5, std_dev=0.1, seed=42): + super().__init__(seed=seed) + self.population = n + self.network = nx.Graph() # Initialize the network + self.datacollector = mesa.DataCollector(model_reporters={"Network": "network"}) + + # Create Agents + power = np.random.normal(mean, std_dev, n) + power = np.clip(power, 0, 1) + position = np.random.normal(mean, std_dev, n) + position = np.clip(position, 0, 1) + AllianceAgent.create_agents(self, n, power, position) + agent_ids = [(agent.unique_id, {"size": 100}) for agent in self.agents] + self.network.add_nodes_from(agent_ids) + + def add_link(self, metaagent, agents): + for agent in agents: + self.network.add_edge(metaagent.unique_id, agent.unique_id) + + def step(self): + for agent_class in list( + self.agent_types + ): # Convert to list to avoid modification during iteration + self.agents_by_type[agent_class].shuffle_do("form_alliance") + + # Update graph + if agent_class is not AllianceAgent: + for metaagent in self.agents_by_type[agent_class]: + self.add_link(metaagent, metaagent.agents) diff --git a/tests/test_agent.py b/tests/test_agent.py index b1ca0ba0eb7..8c6725e14de 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -682,3 +682,51 @@ def custom_agg(values): assert custom_result[False] == custom_agg( [agent.value for agent in agents if not agent.even] ) + + +class TestMetaAgent(Agent): + """Test MetaAgent creation.""" + + def __init__(self, model, power, position, hierarchy=0): + """Initialize a TestMetaAgent.""" + super().__init__(model) + self.power = power + self.position = position + self.hierarchy = hierarchy + + +def test_create_metaagent(): + """Test creating a new meta-agent class.""" + model = Model() + agent1 = TestMetaAgent(model, power=0.5, position=0.5) + agent2 = TestMetaAgent(model, power=0.6, position=0.6) + agent3 = TestMetaAgent(model, power=0.7, position=0.7) + agent4 = TestMetaAgent(model, power=0.8, position=0.8) + + # Test creating a new meta-agent class + meta = agent1.create_metaagent( + "MetaAgentClass1", {agent1, agent2}, power=1.1, position=0.55, hierarchy=1 + ) + assert len(model.agent_types) == 2 + assert len(model.agents) == 5 + assert meta.power == 1.1 + assert meta.position == 0.55 + assert meta.hierarchy == 1 + + # Test adding agents to an existing meta-agent + agent1.create_metaagent( + "MetaAgentClass1", {agent3, agent2}, power=1.8, position=0.65, hierarchy=1 + ) + assert len(model.agent_types) == 2 + assert len(model.agents) == 5 + assert len(meta.agents) == 3 + + # Test creating a new instance of an existing meta-agent class + meta2 = agent4.create_metaagent( + "MetaAgentClass2", {agent4}, power=0.8, position=0.8, hierarchy=2 + ) + assert len(model.agent_types) == 3 + assert len(model.agents) == 6 + assert meta2.power == 0.8 + assert meta2.position == 0.8 + assert meta2.hierarchy == 2 From 7c4ae09614478421717a6452ea2da85d29aef7f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:31:19 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/agent.py | 63 ++++++++++++------- .../basic/alliance_formation_model/Readme.md | 10 +-- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/mesa/agent.py b/mesa/agent.py index 62f5e6a8610..e24d2baea35 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -69,8 +69,8 @@ def __init__(self, model: Model, *args, **kwargs) -> None: self.model.register_agent(self) # Private attribute to track parent agent if metaagents are created # Uses name mangling to prevent name clashes - self.__metaagent = None # Currently restricted to one parent agent - + self.__metaagent = None # Currently restricted to one parent agent + def remove(self) -> None: """Remove and delete the agent from the model. @@ -135,9 +135,13 @@ def __getitem__(self, i): agent = cls(model, *instance_args, **instance_kwargs) agents.append(agent) return AgentSet(agents, random=model.random) - - def create_metaagent(self, new_agent_class: str, agents: Iterable[Agent], **unique_attributes_functions) -> None: + def create_metaagent( + self, + new_agent_class: str, + agents: Iterable[Agent], + **unique_attributes_functions, + ) -> None: """Dynamically create a new meta-agent class and instantiate agents in that class. Args: @@ -172,17 +176,17 @@ def create_metaagent(self, new_agent_class: str, agents: Iterable[Agent], **uniq def update_agents_metaagent(agents, metaagent): for agent in agents: agent._Agent__metaagent = metaagent - + # Path 1 - Add agents to existing meta-agent subagents = [agent for agent in agents if agent._Agent__metaagent is not None] - + if len(subagents) > 0: - if len(subagents) == 1: + if len(subagents) == 1: # Update metaagents agent set with new agents subagents[0]._Agent__metaagent.agents.update(agents) # Update subagents with metaagent update_agents_metaagent(agents, subagents[0]._Agent__metaagent) - else: + else: # If there are multiple subagents, one is chosen at random to be the parent metaagent subagent = self.random.choice(subagents) # Remove agent who are already part of metaagent @@ -190,45 +194,56 @@ def update_agents_metaagent(agents, metaagent): subagent._Agent__metaagent.agents.update(agents) update_agents_metaagent(agents, subagent._Agent__metaagent) # TODO: Add way for user to add function to specify how agents join metaagent - - else: + + else: # Path 2 - Create a new instance of an exsiting meta-agent class - agent_class = next((agent_type for agent_type in self.model.agent_types if agent_type.__name__ == new_agent_class), None) + agent_class = next( + ( + agent_type + for agent_type in self.model.agent_types + if agent_type.__name__ == new_agent_class + ), + None, + ) if agent_class: # Create an instance of the meta-agent class - meta_agent_instance = agent_class(self.model, **unique_attributes_functions) + meta_agent_instance = agent_class( + self.model, **unique_attributes_functions + ) # Add agents to meta-agent instance meta_agent_instance.agents = agents # Update subagents Agent.__metaagent attribute - update_agents_metaagent(agents, meta_agent_instance) + update_agents_metaagent(agents, meta_agent_instance) # Register the new meta-agent instance self.model.register_agent(meta_agent_instance) - return meta_agent_instance - + return meta_agent_instance + # Path 3 - Create a new meta-agent class - else: + else: # Get agent types of subagents to create the new meta-agent class - agent_types = tuple(set((type(agent) for agent in agents))) + agent_types = tuple({type(agent) for agent in agents}) meta_agent_class = type( new_agent_class, agent_types, { "unique_id": None, - "agents": agents, - } + "agents": agents, + }, ) - + # Create an instance of the meta-agent class - meta_agent_instance = meta_agent_class(self.model, **unique_attributes_functions) + meta_agent_instance = meta_agent_class( + self.model, **unique_attributes_functions + ) # Register the new meta-agent instance self.model.register_agent(meta_agent_instance) # Update subagents Agent.__metaagent attribute - update_agents_metaagent(agents, meta_agent_instance) + update_agents_metaagent(agents, meta_agent_instance) + + return meta_agent_instance - return meta_agent_instance - @property def random(self) -> Random: """Return a seeded stdlib rng.""" diff --git a/mesa/examples/basic/alliance_formation_model/Readme.md b/mesa/examples/basic/alliance_formation_model/Readme.md index 195522eacd4..df1ef1dd5a0 100644 --- a/mesa/examples/basic/alliance_formation_model/Readme.md +++ b/mesa/examples/basic/alliance_formation_model/Readme.md @@ -2,13 +2,13 @@ ## Summary -This model demonstrates Mesa's ability to dynamically create new classes of agents that are composed of existing agents. These meta-agents inherits functions and attributes from their sub-agents and users can specify new functionality or attributes they want the meta agent to have. For example, if a user is doing a factory simulation with autonomous systems, each major component of that system can be a sub-agent of the overall robot agent. Or, if someone is doing a simulation of an organization, individuals can be part of different organizational units that are working for some purpose. +This model demonstrates Mesa's ability to dynamically create new classes of agents that are composed of existing agents. These meta-agents inherits functions and attributes from their sub-agents and users can specify new functionality or attributes they want the meta agent to have. For example, if a user is doing a factory simulation with autonomous systems, each major component of that system can be a sub-agent of the overall robot agent. Or, if someone is doing a simulation of an organization, individuals can be part of different organizational units that are working for some purpose. -To provide a simple demonstration of this capability is an alliance formation model. +To provide a simple demonstration of this capability is an alliance formation model. -In this simulation n agents are created, who have two attributes (1) power and (2) preference. Each attribute is a number between 0 and 1 over a gaussian distribution. Agents then randomly select other agents and use the [bilateral shapley value](https://en.wikipedia.org/wiki/Shapley_value) to determine if they should form an alliance. If the expected utility support an alliances, the agent creates a meta-agent. Subsequent steps may add agents to the meta-agent, create new instances of similar hierarchy, or create a new hierarchy level where meta-agents form an alliance of meta-agents. In this visualization of this model a new meta-agent hierarchy will be a larger node and a new color. +In this simulation n agents are created, who have two attributes (1) power and (2) preference. Each attribute is a number between 0 and 1 over a gaussian distribution. Agents then randomly select other agents and use the [bilateral shapley value](https://en.wikipedia.org/wiki/Shapley_value) to determine if they should form an alliance. If the expected utility support an alliances, the agent creates a meta-agent. Subsequent steps may add agents to the meta-agent, create new instances of similar hierarchy, or create a new hierarchy level where meta-agents form an alliance of meta-agents. In this visualization of this model a new meta-agent hierarchy will be a larger node and a new color. -In its current configuration, agents being part of multiple meta-agents is not supported +In its current configuration, agents being part of multiple meta-agents is not supported ## Installation @@ -36,6 +36,6 @@ To run the model interactively, in this directory, run the following command The full tutorial describing how the model is built can be found at: https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html -An example of the bilateral shapley value in another model: +An example of the bilateral shapley value in another model: [Techno-Social Energy Infrastructure Siting: Sustainable Energy Modeling Programming (SEMPro)](https://www.jasss.org/16/3/6.html) From f603b01eb3d04e05c7cd5e01d8493231b5e94a3c Mon Sep 17 00:00:00 2001 From: Tom Pike Date: Fri, 20 Dec 2024 06:55:33 -0500 Subject: [PATCH 3/4] meta-agent creation - adds ability to dynamically create meta-agents - adds alliance formation model to demonstrate - adds tests to agent.py for meta agent creation --- mesa/agent.py | 4 ++-- .../examples/basic/alliance_formation_model/Readme.md | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/mesa/agent.py b/mesa/agent.py index e24d2baea35..b95ba8c2c6c 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -151,7 +151,7 @@ def create_metaagent( Returns: Adds the new meta-agent instance to agentset if adding agent to new class or new agent instance - - None if adding agent to exsiting class + - None if adding agent to existing class - New class instance if created a new instance of a dynamically created agent type - New class instance if created a new dynamically created agent type @@ -196,7 +196,7 @@ def update_agents_metaagent(agents, metaagent): # TODO: Add way for user to add function to specify how agents join metaagent else: - # Path 2 - Create a new instance of an exsiting meta-agent class + # Path 2 - Create a new instance of an existing meta-agent class agent_class = next( ( agent_type diff --git a/mesa/examples/basic/alliance_formation_model/Readme.md b/mesa/examples/basic/alliance_formation_model/Readme.md index df1ef1dd5a0..7de1b9b26fd 100644 --- a/mesa/examples/basic/alliance_formation_model/Readme.md +++ b/mesa/examples/basic/alliance_formation_model/Readme.md @@ -1,14 +1,13 @@ # Alliance Formation Model ## Summary +This model demonstrates Mesa's ability to dynamically create new classes of agents that are composed of existing agents. These meta-agents inherits functions and attributes from their sub-agents and users can specify new functionality or attributes they want the meta agent to have. For example, if a user is doing a factory simulation with autonomous systems, each major component of that system can be a sub-agent of the overall robot agent. Or, if someone is doing a simulation of an organization, individuals can be part of different organizational units that are working for some purpose. -This model demonstrates Mesa's ability to dynamically create new classes of agents that are composed of existing agents. These meta-agents inherits functions and attributes from their sub-agents and users can specify new functionality or attributes they want the meta agent to have. For example, if a user is doing a factory simulation with autonomous systems, each major component of that system can be a sub-agent of the overall robot agent. Or, if someone is doing a simulation of an organization, individuals can be part of different organizational units that are working for some purpose. +To provide a simple demonstration of this capability is an alliance formation model. -To provide a simple demonstration of this capability is an alliance formation model. +In this simulation n agents are created, who have two attributes (1) power and (2) preference. Each attribute is a number between 0 and 1 over a gaussian distribution. Agents then randomly select other agents and use the [bilateral shapley value](https://en.wikipedia.org/wiki/Shapley_value) to determine if they should form an alliance. If the expected utility support an alliances, the agent creates a meta-agent. Subsequent steps may add agents to the meta-agent, create new instances of similar hierarchy, or create a new hierarchy level where meta-agents form an alliance of meta-agents. In this visualization of this model a new meta-agent hierarchy will be a larger node and a new color. -In this simulation n agents are created, who have two attributes (1) power and (2) preference. Each attribute is a number between 0 and 1 over a gaussian distribution. Agents then randomly select other agents and use the [bilateral shapley value](https://en.wikipedia.org/wiki/Shapley_value) to determine if they should form an alliance. If the expected utility support an alliances, the agent creates a meta-agent. Subsequent steps may add agents to the meta-agent, create new instances of similar hierarchy, or create a new hierarchy level where meta-agents form an alliance of meta-agents. In this visualization of this model a new meta-agent hierarchy will be a larger node and a new color. - -In its current configuration, agents being part of multiple meta-agents is not supported +In its current configuration, agents being part of multiple meta-agents is not supported ## Installation @@ -36,6 +35,6 @@ To run the model interactively, in this directory, run the following command The full tutorial describing how the model is built can be found at: https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html -An example of the bilateral shapley value in another model: +An example of the bilateral shapley value in another model: [Techno-Social Energy Infrastructure Siting: Sustainable Energy Modeling Programming (SEMPro)](https://www.jasss.org/16/3/6.html) From 5975e446d26a741fec694ff0590d1d903b13443f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:36:29 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/examples/basic/alliance_formation_model/Readme.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mesa/examples/basic/alliance_formation_model/Readme.md b/mesa/examples/basic/alliance_formation_model/Readme.md index 7de1b9b26fd..a28286c54fa 100644 --- a/mesa/examples/basic/alliance_formation_model/Readme.md +++ b/mesa/examples/basic/alliance_formation_model/Readme.md @@ -1,13 +1,13 @@ # Alliance Formation Model ## Summary -This model demonstrates Mesa's ability to dynamically create new classes of agents that are composed of existing agents. These meta-agents inherits functions and attributes from their sub-agents and users can specify new functionality or attributes they want the meta agent to have. For example, if a user is doing a factory simulation with autonomous systems, each major component of that system can be a sub-agent of the overall robot agent. Or, if someone is doing a simulation of an organization, individuals can be part of different organizational units that are working for some purpose. +This model demonstrates Mesa's ability to dynamically create new classes of agents that are composed of existing agents. These meta-agents inherits functions and attributes from their sub-agents and users can specify new functionality or attributes they want the meta agent to have. For example, if a user is doing a factory simulation with autonomous systems, each major component of that system can be a sub-agent of the overall robot agent. Or, if someone is doing a simulation of an organization, individuals can be part of different organizational units that are working for some purpose. -To provide a simple demonstration of this capability is an alliance formation model. +To provide a simple demonstration of this capability is an alliance formation model. -In this simulation n agents are created, who have two attributes (1) power and (2) preference. Each attribute is a number between 0 and 1 over a gaussian distribution. Agents then randomly select other agents and use the [bilateral shapley value](https://en.wikipedia.org/wiki/Shapley_value) to determine if they should form an alliance. If the expected utility support an alliances, the agent creates a meta-agent. Subsequent steps may add agents to the meta-agent, create new instances of similar hierarchy, or create a new hierarchy level where meta-agents form an alliance of meta-agents. In this visualization of this model a new meta-agent hierarchy will be a larger node and a new color. +In this simulation n agents are created, who have two attributes (1) power and (2) preference. Each attribute is a number between 0 and 1 over a gaussian distribution. Agents then randomly select other agents and use the [bilateral shapley value](https://en.wikipedia.org/wiki/Shapley_value) to determine if they should form an alliance. If the expected utility support an alliances, the agent creates a meta-agent. Subsequent steps may add agents to the meta-agent, create new instances of similar hierarchy, or create a new hierarchy level where meta-agents form an alliance of meta-agents. In this visualization of this model a new meta-agent hierarchy will be a larger node and a new color. -In its current configuration, agents being part of multiple meta-agents is not supported +In its current configuration, agents being part of multiple meta-agents is not supported ## Installation @@ -35,6 +35,6 @@ To run the model interactively, in this directory, run the following command The full tutorial describing how the model is built can be found at: https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html -An example of the bilateral shapley value in another model: +An example of the bilateral shapley value in another model: [Techno-Social Energy Infrastructure Siting: Sustainable Energy Modeling Programming (SEMPro)](https://www.jasss.org/16/3/6.html)