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 相关文章推荐
linux系统使用python监测系统负载脚本分享
Jan 15 Python
举例讲解Python中的Null模式与桥接模式编程
Feb 02 Python
分析python切片原理和方法
Dec 19 Python
Python的多维空数组赋值方法
Apr 13 Python
简单了解django缓存方式及配置
Jul 19 Python
Python安装selenium包详细过程
Jul 23 Python
Python实现字符串中某个字母的替代功能
Oct 21 Python
Scrapy框架介绍之Puppeteer渲染的使用
Jun 19 Python
如何完美的建立一个python项目
Oct 09 Python
Django haystack实现全文搜索代码示例
Nov 28 Python
python实现文件+参数发送request的实例代码
Jan 05 Python
用python修改excel表某一列内容的操作方法
Jun 11 Python
使用python绘制横竖条形图
python多次执行绘制条形图
Apr 20 #Python
Python 数据可视化工具 Pyecharts 安装及应用
python画条形图的具体代码
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 #Python
Pandas 数据编码的十种方法
Apr 20 #Python
Python读取和写入Excel数据
You might like
高亮度显示php源代码
2006/10/09 PHP
PHP 已经成熟
2006/12/04 PHP
linux下为php添加curl扩展的方法
2011/07/29 PHP
php图片加中文水印实现代码分享
2012/10/31 PHP
探讨GDFONTPATH能否被winxp下的php支持
2013/06/21 PHP
Laravel 默认邮箱登录改成用户名登录的实现方法
2019/08/12 PHP
IE 下的只读 innerHTML
2009/08/21 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
JS运动改变单物体透明度的方法分析
2018/01/23 Javascript
基于webpack-hot-middleware热加载相关错误的解决方法
2018/02/22 Javascript
vue keep-alive请求数据的方法示例
2018/05/16 Javascript
理理Vue细节(推荐)
2019/04/16 Javascript
3分钟读懂移动端rem使用方法(推荐)
2019/05/06 Javascript
小程序多图列表实现性能优化的方法步骤
2019/05/28 Javascript
Vue的属性、方法、生命周期实例代码详解
2019/09/17 Javascript
layer 关闭指定弹出层的例子
2019/09/25 Javascript
[47:20]DAC2018 4.4 淘汰赛 Optic vs Mineski 第一场
2018/04/05 DOTA
python生成随机mac地址的方法
2015/03/16 Python
Python3控制路由器——使用requests重启极路由.py
2016/05/11 Python
python验证码识别的实例详解
2016/09/09 Python
python2.7安装图文教程
2018/03/13 Python
Pandas 对Dataframe结构排序的实现方法
2018/04/10 Python
浅谈python的深浅拷贝以及fromkeys的用法
2019/03/08 Python
python实现定时压缩指定文件夹发送邮件
2020/12/22 Python
python调用其他文件函数或类的示例
2019/07/16 Python
Python实现时间序列可视化的方法
2019/08/06 Python
Python打开文件、文件读写操作、with方式、文件常用函数实例分析
2020/01/07 Python
python中最小二乘法详细讲解
2021/02/19 Python
html5是什么_动力节点Java学院整理
2017/07/07 HTML / CSS
夏威夷灵感服装及配饰:Reyn Spooner
2018/09/18 全球购物
如何在C# winform中异步调用web services
2015/09/21 面试题
后勤园长自我鉴定
2013/10/17 职场文书
自荐信结尾
2013/10/27 职场文书
酒鬼酒广告词
2014/03/21 职场文书
毕业实习单位意见
2015/06/04 职场文书
Vue router配置与使用分析讲解
2022/12/24 Vue.js