ABM

ABM丨Python - MESA - APIs

Posted by Cao Zihang on July 24, 2025 Word Count:

MESA APIs

目录

Model

1
class Model(*agrs: Any, seed: float | None = None, rng: Generator | BitGenerator | int | integer | Sequence[int] | SeedSequence | None = None, **kwargs: Any)

Model类是创建智能体基模型的基础框架,它包含用于初始化和运行仿真模型的必备基础属性和方法。

Attributes:

  • running: 指示模型是否继续运行的布尔型变量
  • stepsmodel.step()被调用的次数
  • random: python.random随机数生成器
  • rng: numpy.random随机数生成器

Model.agents返回一个包含所有该模型注册的智能体AgentSet,最好不要直接修改这个AgentSet,只能使用副本

创建新模型

通过继承mesa.Model创建新模型

覆写__init__方法通常首先super().__init__()初始化模型对象

1
2
3
4
5
6
7
def __init__(
    self,
    *args: Any,
    seed: float | None = None,
    rng: RNGLike | SeedLike | None = None,
    **kwargs: Any,
) -> None

Args:

  • args: 传递给super的参数
  • seed: 随机数种子
  • rng: 伪随机数生成器状态
    • None: 基于操作系统熵创建numpy.random.Generator
    • numpy.random.Generator会被传递给numpy.random.default_rng实例化生成器
  • kwargs: 关键字参数传递给super

seedrng必须选择一个,不能同时使用

属性

  • property agents -> ‘AgentSet’
    • 返回模型中所有的智能体(含所有类型智能体)
  • property agent_types -> list[type]
    • 返回该模型注册的所有的唯一智能体类型
  • property agents_by_type -> dict[type[Agent], AgentSet]
    • 由智能体类型:对应智能体合集AgentSet键值对组成的字典

智能体功能函数

  • register_agent(self, agent)
    • 向模型注册一个智能体,通常会在传递了model参数的Agent类的__init__方法中自动调用,无需手动调用
  • deregister_agent(self, agent)
    • 从模型中注销一个智能体,通常会被Agent.remove方法自动调用,无需手动调用

模型调用方法

  • run_model() -> None
    • 模型运行,调用self.step()
    • 默认代码为while self.running: self.step()
    • 需要时可以覆写该方法
  • step() -> None
    • 模型步进,默认是空白的
    • 通常会调用模型中的智能体step方法
  • reset_randomizer(self, seed: int | None = None)
    • 重置模型随机数生成器
  • reset_rng(self, rng: RNGLike | SeedLike | None = None) -> None
    • 重置模型随机数生成器
  • remove_all_agents() -> None
    • 移除模型中所有智能体
    • 它会迭代调用模型中所有Agent的agent.remove方法

Agent

智能体相关类,拥有两个核心对象:AgentAgentSet

Agent

1
class Agent(model: Model, *args, **kwargs)

Mesa模型智能体基类

Attributes:

  • model (Model): 相关的模型实例
  • unique_id (int): 智能体的唯一标识符
  • pos (Position): 智能体位置引用

unique_id相对一个模型示例而言是唯一的,从1开始计数

类中实现了一个_ids整数迭代器

1
_ids = defaultdict(functools.partial(itertools.count, 1))

创建新智能体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Agent:
    def __init__(self, model: Model, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        self.model: Model = model
        # 已经实现的迭代器
        self.unique_id: int = next(self._ids[type(self)])
        self.pos: Position | None = None
        self.model.register_agent(self)

class MyAgent(Agent):
    def __init__(self, model: Model, *args, **kwargs):
        super().__init__(model)
        self.my_arg = args

args:

  • model: 智能体存在的模型实例

属性

  • property random -> Random
    • 返回self.model.random
  • property rng -> np.random.Generator
    • 返回self.model.rng

模型调用方法

  • remove() -> None
    • 从self.model中移除该智能体 -> 调用模型的deregister_agent方法
  • step() -> None
    • 智能体步进,默认是空白的
  • classmethod create_agent(cls, model: Model, n: int, *args, **kwargs) -> AgentSet[Agent]
    • 创建n个智能体,并返回一个AgentSet
    • @param model: 智能体实例所属的模型
    • @param n: 创建的智能体数量
    • @param args: 传递给智能体实例的参数,长度为n的序列或单个参数
    • @param kwargs: 传递给智能体实例的关键字参数,长度为n的序列或单个参数
    • @return: 创建的智能体合集AgentSet

AgentSet

ABM中智能体的有序集合

AgentSet类通过拓展MutableSet和Sequence提供了类集合函数和有序序列操作

AgentSet使用对智能体的弱引用,实现对智能体生命周期的高效管理

1
class AgentSet(agents: Iterable[Agent], random: Random | None = None)

创建AgentSet

通过传递一个(空)智能体集合初始化AgentSet

Args:

  • agents (Iterable[Agent]): 一个纳入集合的可迭代智能体对象
  • random (Random): 随机数生成器

调用方法

实现了__len____iter____contains__ (agent in agentset)、__getitem__ 方法

  • select(filter_func: callable[[Agent], bool] | None = None, at_most: int | float = inf, inplace: bool = False, agent_type: type[Agent] | None = None) -> AgentSet
    • 从AgentSet根据过滤函数或/和数量限制提取智能体子集
    • @param filter_func: 过滤函数,返回True的Agent会被添加到子集
    • @param at_most: 最大数量限制,默认为无限大
      • 如果为整数则为选择优先匹配的智能体
      • 如果为0~1之间的浮点数,则选择原始智能体集合的百分比
      • 默认依顺序选择,若希望随机化先使用shuffle()
    • @param inplace: 是否在原集合上操作,默认为否返回新集合
    • @param agent_type: 选子的智能体类型,默认为None,表示所有智能体类型
  • shuffle(inplace: bool = False) -> AgentSet
    • @param inplace: 是否在原集合上操作,默认为否返回新集合,True性能更高
    • @return: 随机化后的AgentSet
  • sort(key: callable[[Agent], Any] | str, ascending: bool = True, inplace: bool = False) -> AgentSet
    • @param key: 排序依赖的函数或属性名
    • @param ascending: 是否升序排序,默认为降序
    • @param inplace: 是否在原集合上操作,默认为否返回新集合
  • do(method: str | callable, *args, **kwargs) -> AgentSet
    • 对AgentSet中的每个智能体调用方法或函数
    • @param method: 方法名或函数
      • 若为str则调用每个智能体的同名方法
      • 若为callable则将每个智能体作为第一个参数传入函数
    • @param args和kwargs: 会被传递给每个智能体的方法或函数
  • shuffle_do(method: str | callable, *args, **kwargs) -> AgentSet
    • 优化版shuffle+do
  • map(method: str | callable, *args, **kwargs) -> list[Any]
    • 对AgentSet中的每个智能体调用方法或函数并返回结果
    • do基本一致,但会将结果存储到一个列表中返回
  • agg(attribute: str, func: Callable) -> Any
    • 对AgentSet中所有智能体的一个属性使用指定函数进行聚合
    • @param attribute: 属性名
    • @param func: 聚合函数,如min, max, sum, np.mean等
  • get(attr_names: str, handle_missing: Literal['error', 'default'] = 'error', default: Any = None) -> list[Any]
    • attr_names: list[str],则返回list[list[Any]]
    • 提取AgentSet中每个智能体的指定属性
    • @param attr_names: 属性名str或属性名列表list[str]
    • @param handle_missing: 缺失属性的处理方式,默认为error,即抛出异常,default返回指定默认值default_value
    • @param default_value: default返回的值
  • set(attr_names: str, value: Any) -> AgentSet
    • 赋值AgentSet中每个智能体的指定属性
  • add(agent: Agent)
    • 向AgentSet中添加一个智能体
  • discard(agent: Agent)
    • 从AgentSet中移除一个智能体,若不存在该智能体不会报错
  • remove(agent: Agent)
    • 移除智能体,但不存在会报错
  • groupby(by: Callable | str, result_type: str = "agentset") -> GroupBy
    • @param by
      • Callable: 对每个智能体调用该函数,返回结果作为分组依据
      • str: 检查智能体同名属性值作为分组依据
    • @param result_type
      • “agentset” / “list”
      • 结果组的数据类型
      • list性能更佳
  • count(value) -> int
    • 返回AgentSet中指定值出现的次数
  • index(value[, start[, stop]]) -> int
    • 返回指定值在AgentSet中的索引,若不存在则报错
  • isdisjoint(other) -> bool
    • 检查两个AgentSet是否没有共同元素
    • True则没有交集
  • pop()返回最后一个值并删除

GroupBy

1
class GroupBy(groups: dict[Any, list | AgentSet])

AgentSet.groupby方法的辅助类

Attributes:

  • groups (dict): group_name:group键值对字典
1
2
3
class Group:
    def __init__(self, groups: dict[Any, list | AgentSet]):
        self.groups = groups

调用方法

  • map(method: Callable | str, *args, **kwargs) -> dict[Any, Any]
    • 对所有的组执行Callable函数或调用str方法
    • 返回group_name:result键值对字典
    • 适用于执行有返回值的函数
  • do(method: Callable | str, *args, **kwargs) -> GroupBy
    • 返回原始GroupBy示例
    • 适用于没有返回值的函数
  • count() -> dict[Any, int]
    • 返回每组的智能体数量
  • agg(attr_names: str, func: Callable) -> dict[Hashable, Any]
    • 使用给定函数聚合每个组中指定属性的值
    • 常用sum, min, max, mean

Spaces

此处所有Grid类目前处于仅维护状态,新的开发在实验单元空间模型mesa.expeimental.cell_space PropertyLayerContinuousSpace类仍然完全支持且活跃开发

  • accept_tuple_argument(wrapped_func: F) -> F
    • @accept_tuple_argument装饰器
    • 允许接受(x,y)元组列表的网络方法同样接受单个位置(x,y)且无需用户手动放置到列表[(x,y)]中
    • F为泛型
  • is_integer(x: Real) -> bool
    • 检查x是否为CPython整数或Numpy整数
  • warn_if_agent_has_position_already(placemetn_func)
    • @warn_if_agent_has_position_already装饰器
    • 当智能体有位置属性时,会发出警告
    • 通常用于重置智能体位置前的检查
  • is_single_argument_function(func) -> bool
    • 检查函数是否只接受一个参数
  • ufunc_requires_additional_input(ufunc) -> bool
    • 判断NumPy通用函数是否需要额外的输入
  • class _Grid
    • 长方形网格的基类
    • 采用二维坐标[x, y],坐下角为[0, 0],右上角为[width-1, height-1]
    • Args
      • @param width: 网格宽度
      • @param height: 网格高度
      • @param torus: 是否回环
    • 初始化后将新单元元素默认为空
    • 属性
      • property empties -> set
        • 返回空单元格集合
        • 若没有类尚未创建空单元集合则调用build_empties方法通过self.is_cell_empty遍历所有的单元格构建空单元格集合
      • property agents -> AgentSet(agents, random=rng)
        • 通过遍历返回网格中所有智能体集合
        • 函数尝试通过agents中第一个智能体的random属性作为AgentSet的随机数生成器
      • self._grid网格单元数据结构
        • list[list[GridContent]]
        • 即width_index[height_index[内容]]
    • 方法
      • __getitem__(self, index)
        • 访问网格中的内容
        • 接受单个整数索引、坐标元组、坐标列表、坐标元组列表
        • 坐标会进行回环调整
      • __iter__(self) -> Iterator[GridContent]
        • 返回网格中所有单元格的迭代器
        • itertools.chain(*self._grid)
      • coord_iter(self) -> Iterator[tuple[GridContent, Coordinate]]
        • 返回(单元格内容,坐标)迭代器
      • iter_neighborhood(self, pos: Coordinate, moore: bool, incluide_center: bool = False, radius: int = 1) -> Iterator[Coordinate]
        • 返回遍历指定坐标邻居单元格的迭代器
        • @param pos: 指定点坐标元组
        • @param moore: 是否使用moore邻居(含对角线),若为False使用排除对角线的Von Neumann邻居
        • @param incluide_center: 是否包含中心单元格
        • @param radius: 邻居半径
        • 实际行为是将self.get_neighborhood方法结果传入迭代器中
      • get_neighborhood(self, pos: Coordinate, moore: bool, incluide_center: bool = False, radius: int = 1) -> Sequence[Coordinate]
        • 返回指定坐标邻居单元格坐标元组
        • 每次查询结果会保存在self._neighborhood_cache中进行缓存
      • iter_neighbors(self, pos: Coordinate, moore: bool, incluide_center: bool = False, radius: int = 1) -> Iterator[Agent]
        • 返回指定点邻居单元格内智能体的迭代器
        • 通过调用self.get_neighborhood获取邻居单元格,将其中非空的单元格内智能体进行迭代
      • get_neighbor(self, pos: Coordinate, moore: bool, incluide_center: bool = False, radius: int = 1) -> list[Agent]
        • 返回指定点邻居单元格内智能体的列表
        • 调用list(self.iter_neighbors)
      • torus_adj(self, pos: Coordinate) -> Coordinate
        • 将坐标进行回环调整
        • 简单的整除运算
      • out_of_bounds(self, pos: Coordinate) -> bool
        • 判断坐标是否超出网格边界
      • iter_cell_list_contents(self, cell_list: Iterable[Coordinate]) -> Iterator[Agent]
        • 将一系列单元格列表中包含的智能体放入迭代器
        • 可接受坐标元组列表或单个元组(x,y)
          • @accept_tuple_argument
      • get_cell_list_contents(self, cell_list: Iterable[Coordinate]) -> list[Agent]
        • 返回一系列单元格列表中包含的智能体列表
        • @accept_tuple_argument
      • place_agent(self, agent: Agent, pos: Coordinate) -> None : …
        • 放置智能体的抽象方法,基类未实现
        • 没有使用@abstractmethod强制子类实现
      • remove_agent(self, agent: Agent) -> None : …
      • move_agent(self, agent: Agent, pos: Coordinate) -> None
        • 移动智能体到指定位置
        • @param agent: 待移动的智能体,并假定它将当前位置存储在pos元组中
        • @param pos: 移动到的位置
        • 实际行为是删除当前智能体,在新位置放置该智能体
      • _distance_squared(self, pos1: Coordinate, pos2: Coordinate) -> float
        • 计算两个坐标之间的欧氏距离平方
      • move_agent_to_one_of(self, agent: Agent, pos: list[Coordinate]), selection: str = "random", handel_empty: str | None = None) -> None
        • 将智能体移动到一系列位置中的一个
        • @param agent: 待移动智能体
        • @param pos: 可选位置列表
        • @param selection: 选择方法, “random” (default), “closet”
          • closet若存在多个相同距离的最近位置,则会从中随机选择
        • @param handel_empty: None (default), “warning”, “error”,若候选位置列表是空的时候如何处
      • swap_pos(self, agent_a: Agent, agent_b: Agent) -> None
        • 交换两个智能体的位置
        • 与移动位置一样,调用remove_agent和place_agent
      • is_cell_empty(self, pos: Coordinate) -> bool
        • 判断单元格是否为空
      • move_to_empty(self, agent: Agent) -> None
        • 将智能体随机移动到一个空单元格
        • 若不存在空单元格,则raise Exception
      • exists_empty_cells(self) -> bool
        • 判断网格中是否存在空单元格

PropertyLayer Active

可以添加到网格中的属性层,用以存储每一个单元格具有的指定属性

1
2
3
4
class PropertyLayer:
    def __init__(
        self, name: str, width: int, height: int, default_value: Any = None, dtype=np.float64
    )

Args:

  • name: str 属性层名称
  • width: int 网格宽度
  • height: int 网格高度
  • default_value: Any 默认值
  • dtype=np.float64 属性值的数据类型

初始化会创建一个指定形状的Numpy数组

1
self.data = np.full((width, height), default_value, dtype=dtype)

调用方法

  • set_cell(self, position: Coordinate, value) -> None
    • 设置指定位置单元格的值
  • set_cells(self, value, condition: callable=None) -> None
    • 对所有或指定条件单元格进行批量值设置
    • @param value: 待设置的值
    • @param condition (Option): 返回布尔数组的lambda函数或Numpy ufunc
  • modify_cell(self, position: Coordinate, operation, value: None) -> None
    • 使用指定操作更新指定单元格的值
    • @param position: 待操作单元格
    • @

SingleGrid

强制强制每个单元格至多有一个智能体的网格

MultiGrid

每个单元可以包含一组智能体的网络

HexSingleGrid

用于处理六边形邻居的单智能体网络

HexMultiGrid

用于处理六边形邻居的多智能体网络

ContinuousSpace Active

智能体可以位于浮点坐标的二维网格

NetworkGrid

图网络结构,每个节点包含0到多个智能体

Data Colletion

Batchrunner

Visualization

Experimental

Cell Space

Cell

CellAgent

CellCollection

DiscreteSpace

FixedAgent

Grid

Grid2DMovingAgent

HexGrid

Network

OrthogonalMooreGrid

OrthogonalVonNeumannGrid

PropertyLayer

VoronoiGrid

Cell

HasCellProtocol

HasCell

BasicMovement

FixedCell

CellAgent

FixedAgent

Grid2DMovingAgent

CellCollection

DiscreteSpace

Grid

OrthogonalMooreGrid

OrthogonalVonNeumannGrid

HexGrid

Network

Delaunay

VoronoiGrid

Devs

Continuous Space