【Python】【原创】元胞自动机与动态迁移模型
本帖最后由 白冥 于 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):
state = cell.get_state()
x, y = tuple(cell.get_coordinate())
black_neighbors =
white_neighbors =
ant = next(, None)
ant_moving = {
"white": {
("w_l", ): Cell("b_u", x, y),
("w_r", ): Cell("b_d", x, y),
("w_u", ): Cell("b_r", x, y),
("w_d", ): Cell("b_l", x, y),
("b_l", ): Cell("b_d", x, y),
("b_r", ): Cell("b_u", x,y),
("b_u", ): Cell("b_l", x,y),
("b_d", ): Cell("b_r", x,y)
},
"black": {
("w_l", ): Cell("w_u", x, y),
("w_r", ): Cell("w_d", x, y),
("w_u", ): Cell("w_r", x, y),
("w_d", ): Cell("w_l", x, y),
("b_l", ): Cell("w_d", x, y),
("b_r", ): Cell("w_u", x,y),
("b_u", ): Cell("w_l", x,y),
("b_d", ): 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:
return ant_moving
elif state in ant_state:
return alter_color
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):
state = cell.get_state()
x,y = tuple(cell.get_coordinate())
empty_neighbors =
grass_neighbors =
sheep_neighbors =
wolf_neighbors =
w_moving = {
("w_l_str", ): Cell("w_l_sta", x,y),
("w_r_str", ): Cell("w_r_sta", x,y),
("w_u_str", ): Cell("w_u_sta", x,y),
("w_d_str", ): Cell("w_d_sta", x,y),
("w_l_lt", ): Cell("w_d_sta", x,y),
("w_r_lt", ): Cell("w_u_sta", x,y),
("w_u_lt", ): Cell("w_l_sta", x,y),
("w_d_lt", ): Cell("w_r_sta", x,y),
("w_l_rt", ): Cell("w_u_sta", x,y),
("w_r_rt", ): Cell("w_d_sta", x,y),
("w_u_rt", ): Cell("w_r_sta", x,y),
("w_d_rt", ): Cell("w_l_sta", x,y)}
w_foraging = {
("w_l_sta", ): Cell("w_l_str", x,y),
("w_l_sta", ): Cell("w_l_lt", x,y),
("w_l_sta", ): Cell("w_l_rt",x,y),
("w_r_sta", ): Cell("w_r_str", x,y),
("w_r_sta", ): Cell("w_r_rt", x,y),
("w_r_sta", ): Cell("w_r_lt",x,y),
("w_u_sta", ): Cell("w_u_str", x,y),
("w_u_sta", ): Cell("w_u_lt", x,y),
("w_u_sta", ): Cell("w_u_rt",x,y),
("w_d_sta", ): Cell("w_d_str", x,y),
("w_d_sta", ): Cell("w_d_rt", x,y),
("w_d_sta", ): Cell("w_d_lt",x,y)}
s_moving = {
("s_l_str", ): Cell("s_l_sta", x,y),
("s_r_str", ): Cell("s_r_sta", x,y),
("s_u_str", ): Cell("s_u_sta", x,y),
("s_d_str", ): Cell("s_d_sta", x,y),
("s_l_lt", ): Cell("s_d_sta", x,y),
("s_r_lt", ): Cell("s_u_sta", x,y),
("s_u_lt", ): Cell("s_l_sta", x,y),
("s_d_lt", ): Cell("s_r_sta", x,y),
("s_l_rt", ): Cell("s_u_sta", x,y),
("s_r_rt", ): Cell("s_d_sta", x,y),
("s_u_rt", ): Cell("s_r_sta", x,y),
("s_d_rt", ): Cell("s_l_sta", x,y)}
s_foraging = {
("s_l_sta", ): Cell("s_l_str", x,y),
("s_l_sta", ): Cell("s_l_lt", x,y),
("s_l_sta", ): Cell("s_l_rt",x,y),
("s_r_sta", ): Cell("s_r_str", x,y),
("s_r_sta", ): Cell("s_r_rt", x,y),
("s_r_sta", ): Cell("s_r_lt",x,y),
("s_u_sta", ): Cell("s_u_str", x,y),
("s_u_sta", ): Cell("s_u_lt", x,y),
("s_u_sta", ): Cell("s_u_rt",x,y),
("s_d_sta", ): Cell("s_d_str", x,y),
("s_d_sta", ): Cell("s_d_rt", x,y),
("s_d_sta", ): 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()
刚才试着用vscode跑了一下,确实很有意思 楼主在讲座中分享的知识逐渐有深度了,就拿这蚂蚁来说,看着还挺酷炫。 QAQ 今天也是默默给大佬呈上膝盖的一天 越来越深入看不懂领域jpg 感覺也是比較有意思的內容呢, 可惜自己也只能看看了, 加油囉:loveliness: 惹 感觉可以用来做一些小小的游戏厚
互动之类的{:6_169:} 白大的知识小课堂又开课了,但还是一点都看不懂呢 没很深入接触Python,有些看不懂,我粘到vs 里面运行看看是什么。 这个是那个叫......兰顿蚂蚁来着的东西的原理? 感觉楼主的讲座知识开始变得深刻了啊,看这个蚂蚁感觉挺酷的 学习区楼主{:6_169:}等我以后有师弟了一定让他们来copy楼主的代码,少走十年弯路{:6_197:} 我又来支持(氵)了,感觉距离上一篇发布并没有多久诶,拓展了新模型还是很有水平的 只能说论坛就是天然不适合发布太多代码 {:6_188:} 让我跑跑看能出什么有意思的图案
页:
[1]