为何初始化ResourceModel时出现缺少4个必填参数的TypeError?
问题:Mesa多智能体系统初始化参数报错
报错信息
TypeError: ResourceModel.__init__() missing 4 required positional arguments: 'width' 'height' 'n_agents' & 'n_resources'
已尝试位置参数和命名参数两种方式传入width=10, height=10, n_agents=5, n_resources=10,但问题依旧。
错误原因
核心问题出在ModularServer的使用方式错误:
- 手动创建
ResourceModel实例后,将该实例的grid_viz传给服务器,但ModularServer启动时会自动调用ResourceModel()(不带任何参数)创建新模型实例,直接导致参数缺失报错。 - 模型类
ResourceModel中不应包含可视化相关代码(CanvasGrid定义),可视化配置属于服务器端设置,需与模型逻辑分离。
修复方案
- 移除模型类中的
self.grid_viz定义,单独编写代理绘制函数; - 配置
ModularServer时传入模型参数默认值,让服务器自动处理模型实例化; - 删除手动创建
model实例的代码。
修复后的完整代码
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): # 寻找相邻资源 neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False) resources = [agent for agent in neighbors if isinstance(agent, Resource)] # 收集资源 for resource in resources: self.resources += resource.amount self.model.grid.remove_agent(resource) # 随机移动 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) # 创建资源 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) # 创建智能体 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) 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) # 定义代理绘制函数,用于可视化区分不同类型智能体 def agent_portrayal(agent): portrayal = {"Shape": "circle", "Filled": "true", "r": 0.5} if isinstance(agent, Resource): portrayal["Color"] = "green" portrayal["Layer"] = 0 elif isinstance(agent, ResourceAgent): portrayal["Color"] = "blue" portrayal["Layer"] = 1 portrayal["text"] = str(agent.resources) portrayal["text_color"] = "white" return portrayal # 配置可视化网格 canvas_element = CanvasGrid(agent_portrayal, 10, 10, 500, 500) # 启动服务器,传入模型类、可视化模块、模型名称和参数默认值 server = ModularServer(ResourceModel, [canvas_element], "Resource Model", {"width":10, "height":10, "n_agents":5, "n_resources":10}) server.launch()
额外说明
agent_portrayal函数用于定义不同类型代理的可视化样式,让界面能清晰区分资源和智能体;ModularServer的最后一个参数是模型参数默认值,启动服务器后也可在网页界面调整这些参数;- 模型逻辑与可视化配置分离,符合Mesa框架设计规范,避免了实例化冲突问题。
内容的提问来源于stack exchange,提问作者BubmbleBee
相关产品推荐
相关产品推荐

