Python Mesa建模时无法修改TeamAgent对象属性的问题排查
问题原因
你代码里属性修改不生效的核心问题有两个:
- 你在
linkage()方法里每次写TeamAgent(neighbor, TeamModel),都会创建一个全新的TeamAgent临时实例,后续所有的append、remove操作都是在修改这些临时生成、用完就被回收的对象,完全没有触达你在TeamModel初始化阶段创建并加入调度队列的那些真实Agent实例,所以打印原实例的属性时看不到任何变化。 - 代码调用了
random.choice但没有导入random模块,实际运行会直接抛出导入错误。
修正方法
不要重复实例化Agent,先从当前模型的调度器中,通过Agent的unique_id获取到已经存在的真实实例,再修改对应实例的属性即可。
修正后的完整可运行代码如下:
from mesa import Agent, Model from mesa.time import RandomActivation import networkx as nx import random # 补全缺失的导入 G = nx.path_graph(4) class TeamAgent(Agent): def __init__(self, unique_id, model): super().__init__(unique_id, model) self.neighbors = [n for n in G.neighbors(self.unique_id)] self.notneighbors = [item for item in list(G) if item not in self.neighbors and item not in [self.unique_id]] def linkage(self): for neighbor_id in self.neighbors: # 从当前模型的调度器中获取已存在的邻居Agent实例,不要重新创建 neighbor_agent = self.model.schedule._agents[neighbor_id] list_of_non_neighbors = neighbor_agent.notneighbors if list_of_non_neighbors: one_non_neighbor = random.choice(list_of_non_neighbors) # 获取要建立连接的非邻居Agent实例 target_agent = self.model.schedule._agents[one_non_neighbor] # 双向更新邻居、非邻居列表 neighbor_agent.neighbors.append(one_non_neighbor) neighbor_agent.notneighbors.remove(one_non_neighbor) target_agent.neighbors.append(neighbor_id) target_agent.notneighbors.remove(neighbor_id) def step(self): self.linkage() print(self.unique_id, self.neighbors) class TeamModel(Model): def __init__(self): self.schedule = RandomActivation(self) for i, node in enumerate(G.nodes()): a = TeamAgent(i, self) self.schedule.add(a) def step(self): self.schedule.step() my_model = TeamModel() my_model.step()
运行后就能看到控制台打印的neighbors列表已经按照预期追加了新连接的节点。
注:如果你使用的是mesa 2.0+版本,调度器存储Agent的字典属性名从
_agents改成了agents,如果运行提示找不到_agents,把代码里的self.model.schedule._agents替换成self.model.schedule.agents即可。
内容的提问来源于stack exchange,提问作者Aman Kabra
相关产品推荐
相关产品推荐

