Is there anyway to define subagents in a multiagent system while using Mesa library in Python?

342 Views Asked by At

I'm trying to write a multiagent system in python using the Mesa library, and while the library has been great for a beginner like me(unlike something like Spade, which I found too complex), I can't figure out how I would define subagents using the library.

Here's a rudimentary code of a very basic agent system

from mesa import Agent
from mesa import Model
import random


class Device(Agent):

    def __init__(self, unique_id, model, energy, threshold, status):

        super().__init__(unique_id, model)
        self.energy = energy
        self.threshold = threshold
        self.status = 0

    def _cost(self, price):

        self.elec_cost = price*self.energy

    def run(self, price):

        print('price:', price)
        self._cost(price)

        if self.elec_cost > self.threshold:
            self.status = 0

        elif self.elec_cost <= self.threshold:
            self.status = 1

    def getStatus(self):
        if self.status == 1:
            return 'on'

        elif self.status == 0:
            return 'off'


class Fan(Device):

    def __init__(self, unique_id, model, energy=0.06, threshold=0.55, status=0):

        super().__init__(unique_id, model, energy, threshold, status)


class Light(Device):

    def __init__(self, unique_id, model, energy=0.06, threshold=0.55, status=0):

        super().__init__(unique_id, model, energy, threshold, status)


class HVAC(Device):
    def __init__(self, unique_id, model, energy=3, threshold=31, status=0):

        super().__init__(unique_id, model, energy, threshold, status)


class HomeModel(Model):

    def __init__(self):

        self.fan1 = Fan(1, self)
        self.fan2 = Fan(2, self)

        self.light1 = Light(3, self)
        self.light2 = Light(4, self)

    def run(self):
        self.price = get_Price()
        self._run(self.fan1)
        self._run(self.fan2)
        self._run(self.light1)
        self._run(self.light2)

    def _run(self, x):
        x.run(self.price)
        print(x.unique_id, 'is: ', x.getStatus())

def get_Price():
    priceSet = [8, 9, 7, 9, 7, 7, 6, 8, 9, 7, 7, 10, 13, 4, 7, 9, 7, 9, 10, 11, 14, 13]
    return random.choice(priceSet)

model = HomeModel()
model.run()

What I want to test out is that instead of a model of just one house, I want to see if I can scale it up to a neighborhood, and so I'm looking to define each house as one agent instead of a complete model with appliances as subagents in that house. I thought about making each house an agent and defining appliances as subagents but each instance of an agent takes the instance of the model it belongs to as an argument, so I was kind of stumped on how to define appliance agents within the house agent.

I know there might be other ways to do this too but I'm relatively new to python (barely 3 months working with it) so I can't figure out what those other methods might be. I would be extremely grateful if someone can guide me out here.

1

There are 1 best solutions below

1
On BEST ANSWER

I would add a Home class which has devices within it. Then add the Home to you agent schedule.

For example:

class Home(Agent): 

    def __init__(self, unique_id, model):
        super().__init__(unique_id, model)
        self.fan1 = Fan(1, self)
        self.fan2 = Fan(2, self)

        self.light1 = Light(3, self)
        self.light2 = Light(4, self)

class HomeModel(Model):

    def __init__(self):

         self.schedule = RandomActivation(self)

         for i in range(some_number_of_houses): 
              a = Home(i, self) #This will then add a house with the devices you want
                                # an object within an object