本帖最后由 白冥 于 2025-2-4 00:56 编辑
目录
- 概述
- 安装与环境配置
- 系列技术贴
- 类结构与方法
- 源代码
- 示例1-兰顿蚂蚁
- 示例2-草地捕食链
概述
上一篇元胞自动机的贴子中,我们研究过森林火灾、核污染扩散 ,并扩展了康威的生命游戏的背景知识,这些都是动态扩散模型。众所周知,元胞自动机是一个离散动力学系统,这就说明了它不仅仅可以模拟此前我们研究过的动态扩散模型,本帖将给大家带来元胞自动机的另一种应用——动态迁移模型。
本帖代码均由本人写就。
安装与系统配置
本代码基于 Python 3,建议使用 Python 3.8 及以上版本。
代码中仅使用了标准库itertools, typing,无需安装额外的第三方库。
系列技术贴
元胞自动机(一):元胞自动机与动态扩散模型
类结构与方法
与《元胞自动机与动态扩散模型》相同
源代码
与《元胞自动机与动态扩散模型》相同
示例1-兰顿蚂蚁
背景:在平面上的正方形格被填上白色。在其中一格正方形有一只“蚂蚁”。它的头部朝向上下左右其中一方。若蚂蚁在白格,右转90度,将该格改为黑格,向前移一步;若蚂蚁在黑格,左转90度,将该格改为白格,向前移一步。
- if __name__ == "__main__":
- from random import choice
-
- ant_state = ["w_l", "w_r", "w_u", "w_d", "b_l", "b_r", "b_u", "b_d"]
-
- def ant_rule(cell:Cell, neighbors:List[Cell]):
- state = cell.get_state()
- x, y = tuple(cell.get_coordinate())
- black_neighbors = [n for n in neighbors if n.get_state() == "black"]
- white_neighbors = [n for n in neighbors if n.get_state() == "white"]
- ant = next([n for n in neighbors if n.get_state() in ant_state], None)
- ant_moving = {
- "white": {
- ("w_l", [x,y-1]): Cell("b_u", x, y),
- ("w_r", [x,y+1]): Cell("b_d", x, y),
- ("w_u", [x-1,y]): Cell("b_r", x, y),
- ("w_d", [x+1,y]): Cell("b_l", x, y),
- ("b_l", [x,y+1]): Cell("b_d", x, y),
- ("b_r", [x,y-1]): Cell("b_u", x,y),
- ("b_u", [x+1,y]): Cell("b_l", x,y),
- ("b_d", [x-1,y]): Cell("b_r", x,y)
- },
- "black": {
- ("w_l", [x,y-1]): Cell("w_u", x, y),
- ("w_r", [x,y+1]): Cell("w_d", x, y),
- ("w_u", [x-1,y]): Cell("w_r", x, y),
- ("w_d", [x+1,y]): Cell("w_l", x, y),
- ("b_l", [x,y+1]): Cell("w_d", x, y),
- ("b_r", [x,y-1]): Cell("w_u", x,y),
- ("b_u", [x+1,y]): Cell("w_l", x,y),
- ("b_d", [x-1,y]): Cell("w_r", x,y)
- }
- }
- alter_color = {
- "w_l": Cell("black", x, y),
- "w_r": Cell("black", x, y),
- "w_u": Cell("black", x, y),
- "w_d": Cell("black", x, y),
- "b_l": Cell("white", x, y),
- "b_r": Cell("white", x, y),
- "b_u": Cell("white", x, y),
- "b_d": Cell("white", x, y)
- }
- if state in ant_moving and ant:
- ant_state = ant.get_state()
- ant_coord = ant.get_coordinate()
- key = (ant_state, ant_coord)
- if key in ant_moving[state]:
- return ant_moving[state][key]
- elif state in ant_state:
- return alter_color[state]
- return cell
- def main():
- L = Space()
- size = (120,120)
- status = ["black", "white", "w_l", "w_r", "w_u", "w_d", "b_l", "b_r", "b_u", "b_d"]
- d = 2
- S = Status(default = "white", *status)
- N = Neighborhood(*size)
- f = Rule(S, ant_rule)
- ca = CA(L, d, S, N,f)
- cells = []
- for i in range(120):
- for j in range(120):
- cells.append(Cell("white", i, j))
- cell = choice(cells)
- towards = ["w_l", "w_r", "w_u", "w_d"]
- state = choice(towards)
- ant=Cell(state, *cell.get_coordinate())
- cells.remove(cell)
- cells.append(ant)
- ca.evolution(cells, time = 100)
-
- main()
复制代码
示例2-草地捕食链
背景:某片草地(长200,宽100)存在着羊群和狼群,羊以当地的牧草为食,狼则以羊为食。模拟草地上的形势。
全局数据结构:
- sheep_state = ["s_l_str", "s_r_str", "s_u_str", "s_d_str", "s_l_lt", "s_r_lt", "s_u_lt", "s_d_lt", "s_l_rt", "s_r_rt", "s_u_rt", "s_d_rt", "s_l_sta", "s_r_sta", "s_u_sta", "s_d_sta"]
- sheep_stays = ["s_l_sta", "s_r_sta", "s_u_sta", "s_d_sta"]
- wolf_state = ["w_l_str", "w_r_str", "w_u_str", "w_d_str", "w_l_lt", "w_r_lt", "w_u_lt", "w_d_lt", "w_l_rt", "w_r_rt", "w_u_rt", "w_d_rt", "w_l_sta", "w_r_sta", "w_u_sta", "w_d_sta"]
- wolf_stays = ["w_l_sta", "w_r_sta", "w_u_sta", "w_d_sta"]
复制代码
导入库:
- from random import random
- from random import choice
复制代码
代码主体:
- if __name__ == "__main__":
-
- def rule(cell:Cell, neighbors:List[Cell]):
- state = cell.get_state()
- x,y = tuple(cell.get_coordinate())
- empty_neighbors = [n for n in neighbors if n.get_state() == "empty"]
- grass_neighbors = [n for n in neighbors if n.get_state() == "grass"]
- sheep_neighbors = [n for n in neighbors if n.get_state() in sheep_state]
- wolf_neighbors = [n for n in neighbors if n.get_state() in wolf_state]
- w_moving = {
- ("w_l_str", [x+1,y]): Cell("w_l_sta", x,y),
- ("w_r_str", [x-1,y]): Cell("w_r_sta", x,y),
- ("w_u_str", [x,y-1]): Cell("w_u_sta", x,y),
- ("w_d_str", [x,y+1]): Cell("w_d_sta", x,y),
- ("w_l_lt", [x+1,y+1]): Cell("w_d_sta", x,y),
- ("w_r_lt", [x-1,y-1]): Cell("w_u_sta", x,y),
- ("w_u_lt", [x+1,y-1]): Cell("w_l_sta", x,y),
- ("w_d_lt", [x-1,y+1]): Cell("w_r_sta", x,y),
- ("w_l_rt", [x+1,y-1]): Cell("w_u_sta", x,y),
- ("w_r_rt", [x-1,y+1]): Cell("w_d_sta", x,y),
- ("w_u_rt", [x-1,y-1]): Cell("w_r_sta", x,y),
- ("w_d_rt", [x+1,y+1]): Cell("w_l_sta", x,y)}
- w_foraging = {
- ("w_l_sta", [x-1,y]): Cell("w_l_str", x,y),
- ("w_l_sta", [x-1,y-1]): Cell("w_l_lt", x,y),
- ("w_l_sta", [x-1,y+1]): Cell("w_l_rt",x,y),
- ("w_r_sta", [x+1,y]): Cell("w_r_str", x,y),
- ("w_r_sta", [x+1,y-1]): Cell("w_r_rt", x,y),
- ("w_r_sta", [x+1,y+1]): Cell("w_r_lt",x,y),
- ("w_u_sta", [x, y+1]): Cell("w_u_str", x,y),
- ("w_u_sta", [x-1, y+1]): Cell("w_u_lt", x,y),
- ("w_u_sta", [x+1, y+1]): Cell("w_u_rt",x,y),
- ("w_d_sta", [x,y-1]): Cell("w_d_str", x,y),
- ("w_d_sta", [x-1,y-1]): Cell("w_d_rt", x,y),
- ("w_d_sta", [x+1,y+1]): Cell("w_d_lt",x,y)}
- s_moving = {
- ("s_l_str", [x+1,y]): Cell("s_l_sta", x,y),
- ("s_r_str", [x-1,y]): Cell("s_r_sta", x,y),
- ("s_u_str", [x,y-1]): Cell("s_u_sta", x,y),
- ("s_d_str", [x,y+1]): Cell("s_d_sta", x,y),
- ("s_l_lt", [x+1,y+1]): Cell("s_d_sta", x,y),
- ("s_r_lt", [x-1,y-1]): Cell("s_u_sta", x,y),
- ("s_u_lt", [x+1,y-1]): Cell("s_l_sta", x,y),
- ("s_d_lt", [x-1,y+1]): Cell("s_r_sta", x,y),
- ("s_l_rt", [x+1,y-1]): Cell("s_u_sta", x,y),
- ("s_r_rt", [x-1,y+1]): Cell("s_d_sta", x,y),
- ("s_u_rt", [x-1,y-1]): Cell("s_r_sta", x,y),
- ("s_d_rt", [x+1,y+1]): Cell("s_l_sta", x,y)}
- s_foraging = {
- ("s_l_sta", [x-1,y]): Cell("s_l_str", x,y),
- ("s_l_sta", [x-1,y-1]): Cell("s_l_lt", x,y),
- ("s_l_sta", [x-1,y+1]): Cell("s_l_rt",x,y),
- ("s_r_sta", [x+1,y]): Cell("s_r_str", x,y),
- ("s_r_sta", [x+1,y-1]): Cell("s_r_rt", x,y),
- ("s_r_sta", [x+1,y+1]): Cell("s_r_lt",x,y),
- ("s_u_sta", [x, y+1]): Cell("s_u_str", x,y),
- ("s_u_sta", [x-1, y+1]): Cell("s_u_lt", x,y),
- ("s_u_sta", [x+1, y+1]): Cell("s_u_rt",x,y),
- ("s_d_sta", [x,y-1]): Cell("s_d_str", x,y),
- ("s_d_sta", [x-1,y-1]): Cell("s_d_rt", x,y),
- ("s_d_sta", [x+1,y+1]): Cell("s_d_lt",x,y)}
- if state == "empty":
- for n in wolf_neighbors:
- n_state = n.get_state()
- n_coord = n.get_coordinate()
- if n_state in wolf_state:
- if (n_state, n_coord) in w_moving:
- return w_moving[(n_state, n_coord)]
- for n in sheep_neighbors:
- n_state = n.get_state()
- n_coord = n.get_coordinate()
- if n_state in sheep_state:
- if (n_state, n_coord) in s_moving:
- return s_moving[(n_state, n_coord)]
- if len(grass_neighbors):
- if random()<0.1:
- return Cell("grass", x, y)
- return cell
- elif state == "grass":
- for n in sheep_neighbors:
- n_state = n.get_state()
- n_coord = n.get_coordinate()
- if n_state in sheep_state:
- if (n_state, n_coord) in s_moving:
- return s_moving[(n_state, n_coord)]
- return cell
- elif state in sheep_state:
- if state in sheep_stays:
- for n in grass_neighbors:
- n_coord = n.get_coordinate()
- if (state,n_coord) in s_foraging:
- return s_foraging[(state,n_coord)]
- elif state not in sheep_stays:
- return Cell("empty", x,y)
- return cell
- elif state in wolf_state:
- if state in wolf_stays:
- for n in sheep_neighbors:
- n_coord = n.get_coordinate()
- if (state,n_coord) in w_foraging:
- return w_foraging[(state,n_coord)]
- elif state not in wolf_stays:
- return Cell("empty", x,y)
- return cell
- def main():
- L = Space()
- size = (200,100)
- status = ["empty", "grass", "s_l_str", "s_r_str", "s_u_str", "s_d_str", "s_l_lt", "s_r_lt", "s_u_lt", "s_d_lt", "s_l_rt", "s_r_rt", "s_u_rt", "s_d_rt", "s_l_sta", "s_r_sta", "s_u_sta", "s_d_sta", "w_l_str", "w_r_str", "w_u_str", "w_d_str", "w_l_lt", "w_r_lt", "w_u_lt", "w_d_lt", "w_l_rt", "w_r_rt", "w_u_rt", "w_d_rt", "w_l_sta", "w_r_sta", "w_u_sta", "w_d_sta"]
- d = 2
- S = Status(default="grass", *status)
- N = Neighborhood(*size)
- f = Rule(S, rule)
- ca = CA(L, d, S, N,f)
- cells=[]
- for i in range(200):
- for j in range(100):
- r =random()
- if r<0.6:
- cells.append(Cell("grass",i,j))
- elif r<0.7:
- cell = Cell(choice(sheep_state),i,j)
- cells.append(cell)
- elif r<0.73:
- cell = Cell(choice(wolf_state),i,j)
- cells.append(cell)
- else:
- cells.append(Cell("empty",i,j))
- ca.evolution(cells, time=100)
-
- main()
复制代码
|