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
: 指示模型是否继续运行的布尔型变量steps
:model.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
实例化生成器
- None: 基于操作系统熵创建
- kwargs: 关键字参数传递给super
seed
或rng
必须选择一个,不能同时使用
属性
- property
agents
-> ‘AgentSet’- 返回模型中所有的智能体(含所有类型智能体)
- property
agent_types
-> list[type]- 返回该模型注册的所有的唯一智能体类型
- property
agents_by_type
-> dict[type[Agent], AgentSet]- 由智能体类型:对应智能体合集AgentSet键值对组成的字典
智能体功能函数
register_agent(self, agent)
- 向模型注册一个智能体,通常会在传递了model参数的Agent类的
__init__
方法中自动调用,无需手动调用
- 向模型注册一个智能体,通常会在传递了model参数的Agent类的
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
智能体相关类,拥有两个核心对象:Agent
和AgentSet
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
- @param inplace: 是否在原集合上操作,默认为否返回新集合,
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
性能更佳
- @param by
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
PropertyLayer
和ContinuousSpace
类仍然完全支持且活跃开发
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[内容]]
- property
- 方法
__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到多个智能体