白冥 发表于 2025-2-3 21:00:40

【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()







rayyyyy 发表于 2025-6-23 15:35:48

刚才试着用vscode跑了一下,确实很有意思

zhnlwwdzz 发表于 2025-3-2 13:49:29

楼主在讲座中分享的知识逐渐有深度了,就拿这蚂蚁来说,看着还挺酷炫。

zhuovboyan 发表于 2025-2-9 04:25:01

QAQ 今天也是默默给大佬呈上膝盖的一天 越来越深入看不懂领域jpg

Sam30 发表于 2025-2-7 22:01:18

感覺也是比較有意思的內容呢, 可惜自己也只能看看了, 加油囉:loveliness:

大河内太 发表于 2025-2-6 04:33:30

惹 感觉可以用来做一些小小的游戏厚
互动之类的{:6_169:}

Yang羊 发表于 2025-2-4 12:56:13

白大的知识小课堂又开课了,但还是一点都看不懂呢

圣卫幻梦 发表于 2025-2-4 11:37:39

没很深入接触Python,有些看不懂,我粘到vs 里面运行看看是什么。

2302594 发表于 2025-2-4 06:45:57

这个是那个叫......兰顿蚂蚁来着的东西的原理?

万俟 发表于 2025-2-4 06:20:07

感觉楼主的讲座知识开始变得深刻了啊,看这个蚂蚁感觉挺酷的

野生阿努厨 发表于 2025-2-3 22:55:05

学习区楼主{:6_169:}等我以后有师弟了一定让他们来copy楼主的代码,少走十年弯路{:6_197:}

coldwolf 发表于 2025-2-3 22:35:53

我又来支持(氵)了,感觉距离上一篇发布并没有多久诶,拓展了新模型还是很有水平的

娱乐法师火布偶 发表于 2025-2-3 21:41:30

只能说论坛就是天然不适合发布太多代码

Morphyus 发表于 2025-2-3 21:35:22

{:6_188:} 让我跑跑看能出什么有意思的图案
页: [1]
查看完整版本: 【Python】【原创】元胞自动机与动态迁移模型