Python探索生命起源 matplotlib细胞自动机动画演示


Posted in Python onApril 21, 2022

维基百科上有个有意思的话题叫细胞自动机:https://en.wikipedia.org/wiki/Cellular_automaton

在20世纪70年代,一种名为生命游戏的二维细胞自动机变得广为人知,特别是在早期的计算机界。由约翰 · 康威发明,马丁 · 加德纳在《科学美国人》的一篇文章中推广,其规则如下:

  1. Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
  2. Any live cell with two or three live neighbours lives on to the next generation.
  3. Any live cell with more than three live neighbours dies, as if by overpopulation.
  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

总结就是:任何活细胞在有两到三个活邻居时能活到下一代,否则死亡。任何有三个活邻居的死细胞会变成活细胞,表示繁殖。

在Conway’s Game of Life中,展示了几种初始状态:

Python探索生命起源 matplotlib细胞自动机动画演示

下面我们用python来模拟,首先尝试表示Beacon:

import numpy as np
import matplotlib.pyplot as plt
universe = np.zeros((6, 6), "byte")
# Beacon
universe[1:3, 1:3] = 1
universe[3:5, 3:5] = 1
print(universe)
im = plt.imshow(universe, cmap="binary")
[[0 0 0 0 0 0]
 [0 1 1 0 0 0]
 [0 1 1 0 0 0]
 [0 0 0 1 1 0]
 [0 0 0 1 1 0]
 [0 0 0 0 0 0]]

Python探索生命起源 matplotlib细胞自动机动画演示

可以看到已经成功的打印出了Beacon的形状,下面我们继续编写细胞自动机的演化规则:

def cellular_auto(universe):
    universe_new = universe.copy()
    h, w = universe.shape
    for y in range(h):
        for x in range(w):
            neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
            # 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
            if universe[x, y] == 0 and neighbor_num == 3:
                universe_new[x, y] = 1
            # 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
            if universe[x, y] == 1 and neighbor_num not in (2, 3):
                universe_new[x, y] = 0
    return universe_new
universe = cellular_auto(universe)
print(universe)
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
[[0 0 0 0 0 0]
 [0 1 1 0 0 0]
 [0 1 0 0 0 0]
 [0 0 0 0 1 0]
 [0 0 0 1 1 0]
 [0 0 0 0 0 0]]

Python探索生命起源 matplotlib细胞自动机动画演示

ArtistAnimation动画

基于此我们可以制作matplotlib的动画,下面直接将Blinker、Toad、Beacon都放上去:

from matplotlib import animation
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook

def cellular_auto(universe):
    universe_new = universe.copy()
    h, w = universe.shape
    for y in range(h):
        for x in range(w):
            neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
            # 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
            if universe[x, y] == 0 and neighbor_num == 3:
                universe_new[x, y] = 1
            # 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
            if universe[x, y] == 1 and neighbor_num not in (2, 3):
                universe_new[x, y] = 0
    return universe_new
universe = np.zeros((12, 12), "byte")
# Blinker
universe[2, 1:4] = 1
# Beacon
universe[4:6, 5:7] = 1
universe[6:8, 7:9] = 1
# Toad
universe[8, 2:5] = 1
universe[9, 1:4] = 1
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
frame = []
for _ in range(2):
    frame.append((plt.imshow(universe, cmap="binary"),))
    universe = cellular_auto(universe)
animation.ArtistAnimation(fig, frame, interval=500, blit=True)

Python探索生命起源 matplotlib细胞自动机动画演示

然后我们画一下Pulsar:

# Pulsar
universe = np.zeros((17, 17), "byte")
universe[[2, 7, 9, 14], 4:7] = 1
universe[[2, 7, 9, 14], 10:13] = 1
universe[4:7, [2, 7, 9, 14]] = 1
universe[10:13, [2, 7, 9, 14]] = 1
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
frame = []
for _ in range(3):
    frame.append((plt.imshow(universe, cmap="binary"),))
    universe = cellular_auto(universe)
animation.ArtistAnimation(fig, frame, interval=500, blit=True)

Python探索生命起源 matplotlib细胞自动机动画演示

FuncAnimation动画

另一种创建matplotlib动画的方法是使用FuncAnimation,完整代码:

from matplotlib import animation
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import HTML
# %matplotlib notebook

def cellular_auto(universe):
    universe_new = universe.copy()
    h, w = universe.shape
    for y in range(h):
        for x in range(w):
            neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
            # 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
            if universe[x, y] == 0 and neighbor_num == 3:
                universe_new[x, y] = 1
            # 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
            if universe[x, y] == 1 and neighbor_num not in (2, 3):
                universe_new[x, y] = 0
    return universe_new
def update(i=0):
    global universe
    im.set_data(universe)
    universe = cellular_auto(universe)
    return im,
# Pulsar
universe = np.zeros((17, 17), "byte")
universe[[2, 7, 9, 14], 4:7] = 1
universe[[2, 7, 9, 14], 10:13] = 1
universe[4:7, [2, 7, 9, 14]] = 1
universe[10:13, [2, 7, 9, 14]] = 1
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
plt.show()
anim = animation.FuncAnimation(
    fig, update, frames=3, interval=500, blit=True)
HTML(anim.to_jshtml())

Python探索生命起源 matplotlib细胞自动机动画演示

这种动画生成速度较慢,好处是可以导出html文件:

with open("out.html", "w") as f:
    f.write(anim.to_jshtml())

还可以保存MP4视频:

anim.save("out.mp4")

或gif动画:

anim.save("out.gif")

注意:保存MP4视频或GIF动画,需要事先将ffmpeg配置到环境变量中

ffmpeg下载地址:

链接: https://pan.baidu.com/s/1aioB_BwpKb6LxJs26HbbiQ?pwd=ciui 
提取码: ciui

随机生命游戏

接下来,我们创建一个50*50的二维生命棋盘,并选取其中1500个位置作为初始活细胞点,我们看看最终生成的动画如何。

完整代码如下:

from matplotlib import animation
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook

def cellular_auto(universe):
    universe_new = universe.copy()
    h, w = universe.shape
    for y in range(1, h-1):
        for x in range(1, w-1):
            neighbor_num = universe[x-1:x+2, y-1:y+2].sum()-universe[x, y]
            # 任何有三个活邻居的死细胞都变成了活细胞,繁殖一样。
            if universe[x, y] == 0 and neighbor_num == 3:
                universe_new[x, y] = 1
            # 任何有两到三个活邻居的活细胞都能活到下一代,否则就会死亡。
            if universe[x, y] == 1 and neighbor_num not in (2, 3):
                universe_new[x, y] = 0
    # 边缘置零
    universe[[0, -1]] = 0
    universe[:, [0, -1]] = 0
    return universe_new
boardsize, pad = 50, 2
universe = np.zeros((boardsize+pad, boardsize+pad), "byte")
# 随机选取1500个点作为初始活细胞
for i in range(1500):
    x, y = np.random.randint(1, boardsize+1, 2)
    universe[y, x] = 1
    
fig = plt.figure()
plt.axis("off")
im = plt.imshow(universe, cmap="binary")
frame = []
for _ in range(200):
    frame.append((plt.imshow(universe, cmap="binary"),))
    universe = cellular_auto(universe)
animation.ArtistAnimation(fig, frame, interval=50, blit=True)

Python探索生命起源 matplotlib细胞自动机动画演示

到此这篇关于Python实现的matplotlib动画演示之细胞自动机的文章就介绍到这了!


Tags in this post...

Python 相关文章推荐
python中星号变量的几种特殊用法
Sep 07 Python
python中利用xml.dom模块解析xml的方法教程
May 24 Python
Python3.5 处理文本txt,删除不需要的行方法
Dec 10 Python
对python判断ip是否可达的实例详解
Jan 31 Python
python绘制评估优化算法性能的测试函数
Jun 25 Python
Python多线程爬取豆瓣影评API接口
Oct 22 Python
django实现类似触发器的功能
Nov 15 Python
python 实现多维数组转向量
Nov 30 Python
Django在Model保存前记录日志实例
May 14 Python
Python实现文件压缩和解压的示例代码
Aug 12 Python
python3代码输出嵌套式对象实例详解
Dec 03 Python
python中对列表的删除和添加方法详解
Feb 24 Python
使用python绘制横竖条形图
python多次执行绘制条形图
Apr 20 #Python
Python 数据可视化工具 Pyecharts 安装及应用
python画条形图的具体代码
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 #Python
Pandas 数据编码的十种方法
Apr 20 #Python
Python读取和写入Excel数据
You might like
php csv操作类代码
2009/12/14 PHP
php的list()的一步操作给一组变量进行赋值的使用
2011/05/18 PHP
destoon网站转移服务器后搜索汉字出现乱码的解决方法
2014/06/21 PHP
thinkPHP连接sqlite3数据库的实现方法(附Thinkphp代码生成器下载)
2016/05/27 PHP
利用phpexcel对数据库数据的导入excel(excel筛选)、导出excel
2017/04/27 PHP
解决Yii2邮件发送结果返回成功,但接收不到邮件的问题
2017/05/23 PHP
PHP实现的权重算法示例【可用于游戏根据权限来随机物品】
2019/02/15 PHP
laravel接管Dingo-api和默认的错误处理方式
2019/10/25 PHP
ext form 表单提交数据的方法小结
2008/08/08 Javascript
ie focus bug 解决方法
2009/09/03 Javascript
Json序列化和反序列化方法解析
2013/12/19 Javascript
ext前台接收action传过来的json数据示例
2014/06/17 Javascript
bootstrap实现的自适应页面简单应用示例
2017/03/09 Javascript
js实现扫雷小程序的示例代码
2017/09/27 Javascript
深入理解react-router 路由的实现原理
2018/09/26 Javascript
layer弹出层自定义提交取消按钮的例子
2019/09/10 Javascript
解决vue的过渡动画无法正常实现问题
2019/10/31 Javascript
nodejs使用socket5进行代理请求的实现
2020/02/21 NodeJs
Typescript3.9 常用新特性一览(推荐)
2020/05/14 Javascript
vue 子组件和父组件传值的示例
2020/09/11 Javascript
python实现决策树分类(2)
2018/08/30 Python
一步步教你用python的scrapy编写一个爬虫
2019/04/17 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
Python爬虫:url中带字典列表参数的编码转换方法
2019/08/21 Python
Python实现多线程/多进程的TCP服务器
2019/09/03 Python
python绘制封闭多边形教程
2020/02/18 Python
分享一枚pycharm激活码适用所有pycharm版本我的pycharm2020.2.3激活成功
2020/11/20 Python
Oral-B荷兰:牙医最推荐的品牌
2020/02/25 全球购物
英国自行车商店:AW Cycles
2021/02/24 全球购物
工程师求职简历的自我评价分享
2013/10/10 职场文书
教师的实习自我鉴定
2013/12/17 职场文书
上海世博会口号
2014/06/19 职场文书
师德师风自查总结
2014/10/14 职场文书
工伤调解协议书
2016/03/21 职场文书
python用字节处理文件实例讲解
2021/04/13 Python
详解vue中v-for的key唯一性
2021/05/15 Vue.js