pythonartificial-intelligenceagentmesa

Why am I getting the error 'TypeError: ResourceModel.__init__() missing 4 required positional arguments: 'width' 'height' 'n_agents' & 'n_resources''?


I am trying to make a multi-agent system using mesa, but the code won't run. I keep on getting the same error, but from what I can see I have added the correct parameters.

from mesa import Agent, Model
from mesa.space import MultiGrid
from mesa.time import RandomActivation
from mesa.visualization.modules import CanvasGrid
from mesa.visualization.ModularVisualization import ModularServer
from mesa import DataCollector

class Resource(Agent):
    def __init__(self, unique_id, model):
        super().__init__(unique_id, model)
        self.amount = 10
        
    def step(self):
        pass

class ResourceAgent(Agent):
    def __init__(self, unique_id, model):
        super().__init__(unique_id, model)
        self.resources = 0
        
    def step(self):
        # Find neighboring resources
        neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False)
        resources = [agent for agent in neighbors if isinstance(agent, Resource)]
        
        # Collect resources
        for resource in resources:
            self.resources += resource.amount
            self.model.grid.remove_agent(resource)
        
        # Move randomly
        x, y = self.pos
        dx, dy = self.random.choice([-1, 0, 1]), self.random.choice([-1, 0, 1])
        self.model.grid.move_agent(self, (x+dx, y+dy))


class ResourceModel(Model):
    def __init__(self, width, height, n_agents, n_resources):
        self.grid = MultiGrid(width, height, torus=True)
        self.schedule = RandomActivation(self)

        # Create resources
        for i in range(n_resources):
            resource = Resource(i, self)
            x, y = self.random.randrange(width), self.random.randrange(height)
            self.grid.place_agent(resource, (x, y))
            self.schedule.add(resource)

        # Create agents
        for i in range(n_agents):
            agent = ResourceAgent(n_resources + i, self)
            x, y = self.random.randrange(width), self.random.randrange(height)
            self.grid.place_agent(agent, (x, y))
            self.schedule.add(agent)

        # Create a grid visualization
        self.grid_viz = CanvasGrid(lambda: self.grid.grid, width, height, 500, 500)

        # Run the model
        self.running = True
        self.datacollector = DataCollector(
            {"Resources": lambda m: self.count_resources()},
            agent_reporters={"Resources": lambda a: a.resources},
        )

    def count_resources(self):
        return len([agent for agent in self.schedule.agents if isinstance(agent, Resource)])

    def step(self):
        self.schedule.step()
        self.datacollector.collect(self)


# Create a ResourceModel object
model = ResourceModel(width=10, height=10, n_agents=5, n_resources=10)
server = ModularServer(ResourceModel, [model.grid_viz], "Resource Model")
server.launch()

I have tried rewriting model = ResourceModel(width=10, height=10, n_agents=5, n_resources=10) with model = ResourceModel(10, 10, 5, 10) but of course this makes no difference.


Solution

  • You're missing the model_params argument to ModularServer(), so it's not passing the required arguments when it calls ResourceModel().

    server = ModularServer(ResourceModel, [model.grid_viz], "Resource Model", model_params={'width': 10, 'heigh': 10, 'n_agents': 5, 'n_resources': 10})