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的urllib2模块处理url和图片的技巧两则
Feb 18 Python
Windows安装Python、pip、easy_install的方法
Mar 05 Python
《Python学习手册》学习总结
Jan 17 Python
influx+grafana自定义python采集数据和一些坑的总结
Sep 17 Python
关于Python中定制类的比较运算实例
Dec 19 Python
基于Keras 循环训练模型跑数据时内存泄漏的解决方式
Jun 11 Python
Python datetime模块使用方法小结
Jun 18 Python
在CentOS7下安装Python3教程解析
Jul 09 Python
Python实例教程之检索输出月份日历表
Dec 16 Python
用Python将GIF动图分解成多张静态图片
Jun 11 Python
Python几种酷炫的进度条的方式
Apr 11 Python
python中 Flask Web 表单的使用方法
May 20 Python
使用python绘制横竖条形图
python多次执行绘制条形图
Apr 20 #Python
Python 数据可视化工具 Pyecharts 安装及应用
python画条形图的具体代码
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 #Python
Pandas 数据编码的十种方法
Apr 20 #Python
Python读取和写入Excel数据
You might like
优化使用mysql存储session的php代码
2008/01/10 PHP
PHP文件及文件夹操作之创建、删除、移动、复制
2016/07/13 PHP
jQuery 1.2.x 升? 1.3.x 注意事项
2009/05/06 Javascript
jquery表单验证框架提供的身份证验证方法(示例代码)
2013/12/27 Javascript
js截取中英文字符串、标点符号无乱码示例解读
2014/04/17 Javascript
解决自定义$(id)的方法与jquery选择器$冲突的问题
2014/06/14 Javascript
浅谈Javascript实现继承的方法
2015/07/06 Javascript
js验证真实姓名与身份证号,手机号的简单实例
2016/07/18 Javascript
bootstrap模态框远程示例代码分享
2017/05/22 Javascript
react-router browserHistory刷新页面404问题解决方法
2017/12/29 Javascript
从vue基础开始创建一个简单的增删改查的实例代码(推荐)
2018/02/11 Javascript
jQuery实现获取动态添加的标签对象示例
2018/06/28 jQuery
新手入门带你学习JavaScript引擎运行原理
2019/06/24 Javascript
解决vue项目axios每次请求session不一致的问题
2020/10/24 Javascript
[05:05]DOTA2亚洲邀请赛 战队出场仪式
2015/02/07 DOTA
详解Python中的__getitem__方法与slice对象的切片操作
2016/06/27 Python
python爬虫之百度API调用方法
2017/06/11 Python
JSONLINT:python的json数据验证库实例解析
2017/11/28 Python
django1.11.1 models 数据库同步方法
2018/05/30 Python
Python Django框架单元测试之文件上传测试示例
2019/05/17 Python
用Python调用win命令行提高工作效率的实例
2019/08/14 Python
用python求一重积分和二重积分的例子
2019/12/06 Python
Python字符串查找基本操作代码案例
2020/10/27 Python
python爬虫scrapy框架的梨视频案例解析
2021/02/20 Python
俄罗斯香水在线商店:AromaCode
2019/12/04 全球购物
董事长职责范文
2013/11/08 职场文书
工程师岗位职责
2013/11/08 职场文书
费用会计岗位职责
2014/01/01 职场文书
党员干部三严三实心得体会
2014/10/13 职场文书
2015年信访工作总结
2015/04/07 职场文书
单位车辆管理制度
2015/08/05 职场文书
党校培训学习心得体会
2016/01/06 职场文书
入党申请书格式
2019/06/20 职场文书
企业版Windows 11有哪些新功能? Win11适用于企业的功能介绍
2021/11/21 数码科技
html粘性页脚的具体使用
2022/01/18 HTML / CSS
日本官方排名前10的动漫,名侦探柯南上榜,第一是一部创造历史的动漫
2022/03/18 日漫