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统计列表中的重复项出现的次数的方法
Aug 18 Python
Python简单实现enum功能的方法
Apr 25 Python
用python处理图片之打开\显示\保存图像的方法
May 04 Python
flask中过滤器的使用详解
Aug 01 Python
Python BS4库的安装与使用详解
Aug 08 Python
Python机器学习之scikit-learn库中KNN算法的封装与使用方法
Dec 14 Python
神经网络相关之基础概念的讲解
Dec 29 Python
Python中调用其他程序的方式详解
Aug 06 Python
Python 解析简单的XML数据
Jul 24 Python
Python之字典对象的几种创建方法
Sep 30 Python
python利用faker库批量生成测试数据
Oct 15 Python
python中使用asyncio实现异步IO实例分析
Feb 26 Python
使用python绘制横竖条形图
python多次执行绘制条形图
Apr 20 #Python
Python 数据可视化工具 Pyecharts 安装及应用
python画条形图的具体代码
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 #Python
Pandas 数据编码的十种方法
Apr 20 #Python
Python读取和写入Excel数据
You might like
PHPMYADMIN 简明安装教程 推荐
2010/03/07 PHP
php检查是否是ajax请求的方法
2015/04/16 PHP
PHP正则验证Email的方法
2015/06/15 PHP
Yii实现显示静态页的方法
2016/04/25 PHP
PHP中strpos、strstr和stripos、stristr函数分析
2016/06/11 PHP
详解PHP归并排序的实现
2016/10/18 PHP
php实现的统计字数函数定义与使用示例
2017/07/26 PHP
php+ajax实现仿百度查询下拉内容功能示例
2017/10/20 PHP
php封装的page分页类完整实例代码
2020/02/01 PHP
javascript textarea光标定位方法(兼容IE和FF)
2011/03/12 Javascript
jQuery实现页面内锚点平滑跳转特效的方法总结
2015/05/11 Javascript
深入理解ECMAScript的几个关键语句
2016/06/01 Javascript
模仿password输入框的实现代码
2016/06/07 Javascript
在Mac OS上安装使用Node.js的项目自动化构建工具Gulp
2016/06/18 Javascript
JS实现对中文字符串进行utf-8的Base64编码的方法(使其与Java编码相同)
2016/06/21 Javascript
jquery设置表单元素为不可用的简单代码
2016/07/04 Javascript
JavaScript学习笔记整理_setTimeout的应用
2016/09/19 Javascript
jQuery webuploader分片上传大文件
2016/11/07 Javascript
Mac 安装 nodejs方法(图文详细步骤)
2017/10/30 NodeJs
p5.js入门教程和基本形状绘制
2018/03/15 Javascript
微信小程序 高德地图路线规划实现过程详解
2019/08/05 Javascript
python结合selenium获取XX省交通违章数据的实现思路及代码
2016/06/26 Python
python爬虫headers设置后无效的解决方法
2017/10/21 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
python实现京东订单推送到测试环境,提供便利操作示例
2019/08/09 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
2019/11/19 Python
python-xpath获取html文档的部分内容
2020/03/06 Python
德国街头和运动文化高品质商店:BSTN Store
2017/08/26 全球购物
Unix里面如何在后台运行程序
2016/10/14 面试题
临时租车协议范本
2014/09/23 职场文书
2015年秘书个人工作总结
2015/04/25 职场文书
2015年环境整治工作总结
2015/05/22 职场文书
Go使用协程交替打印字符
2021/04/29 Golang
Vue中插槽slot的使用方法与应用场景详析
2021/06/08 Vue.js
通过shell脚本对mysql的增删改查及my.cnf的配置
2021/07/07 MySQL
Flask使用SQLAlchemy实现持久化数据
2021/07/16 Python