前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Conway生命游戏

Conway生命游戏

作者头像
窗户
发布2018-11-21 18:24:33
9300
发布2018-11-21 18:24:33
举报
文章被收录于专栏:窗户窗户窗户

  1970年,英国数学家Conway发明了生命游戏。抛开元胞自动机的复杂概念,我们只是去感受一下二维的生命游戏,这其实是元胞自动机的一个特例。

生命游戏

  我们先考虑有限的情况,对于mXn的方格,每个方格都会有一个状态,该状态有两个可能值:有生命、无生命。

  如上图8X8的方格,红色的格子代表状态为有生命,白色的格子代表状态为无生命。

  生命游戏是一代一代的演化,每一代就是所有格子的一组状态。我们来说演化规则,对于每个格子,我们来数这个格子所有的周围格子状态为由生命的数目。

  这里的周围格子是指:这个格子的上、下、左、右、左上、右上、左下、右下这8个格子。当然,有例外,角上的格子只有3个周围格子,而边上的格子只有5个周围格子。

  于是,我们把上面这个图的每个格子的周围有生命格子数目标注出来。

  下一代所有格子状态由以下规则确定:

  1.如果周围有生命格子的数目小于2,则下一代这个格子状态为无生命(解释为太孤单)。

  2.如果周围有生命格子的数目大于3,则下一代这个格子为无生命(解释为周围生命太多,资源消耗厉害)。

  3.如果周围有生命格子的数目等于2,则下一代这个格子的状态继续保持当前的状态。

  4.如果周围有生命格子的数目等于3,则下一代这个格子的状态为有生命。

  于是,下一代应为如下:

  把各代组成动画如下:

  只可惜这个到了第6代,所有的格子都变成无生命状态。

震荡子

  有一类神奇的图案,可以反复不断的循环,称为震荡子。

  上面这个震荡子周期为15。

枪型图

  下面这个图是Bill Gosper于1970年发现的第一个Gun,你看那一个个向右下方向而去的像不像“子弹"?实际上,Gun描述的是一个无限的方格,因为子弹是在不断变多的,图形的尺寸实际上会越来越大,但在有限的方格情况下其实是震荡子(下图实际上是虚拟的从无限的方格中截取的有限图像)。

  这是发现的第二个Gun。

  以我的能力,我是完全不知道这两个Gun是怎么被拼出来的。

程序实现

  生命游戏规则简单,我想在学习程序的过程中实现一个并不是什么难事。

  我上面的这些动画实际上也是用程序生成的,我推荐python用cv2库,它属于opencv,开发效率还是很高的。

  真想从底层动手,那就用C语言造轮子吧,只要体力好,也没什么不可以。

  如果要生成bmp,研究一下bmp文件的格式,wiki上就有,https://en.wikipedia.org/wiki/BMP_file_format

  如果想要jpeg,那么可以使用libjpeg,只是libjpeg只有从bmp文件转成jpeg,默认接口里没有从内存转的,这可能不太方便,需要的话得自己来加个接口,很多年前我加过。

计算周围生命格子数目

  我想大部分的人来计算都是对于某个点,依次数周围的格子,然后挨个相加,从而计算整个矩阵的加法数量的线性系数是7(因为大多格子周围都是8个格子,要做7次加法),也就是加法数量除以矩阵规模(节点数)的极限为7。

  如果只从加法数量来说,这个规模不能让人满意。下面这个方法会好很多。

  第一步,同行的两两结对相加。

  a0,0+a0,1 a0,2+a0,3 a0,4+a0,5 ...

  ...

  an,0+an,1 an,2+an,3 an,4+an,5 ... 

  ...

  这样使用线性系数0.5次加法

  第二步,每个格子再多加一次得到这个格子自身和左、右两格的和。

  显然,这次使用加法数量系数为1。

  于是我们看到了,使用系数为1.5的加法数量就完成了每个格子自身和左、右两格的和,而本来平凡的手段这个系数为2。

  第三步,在此基础上,使用第一步、和第二步,只是第一步和第二步从矩阵的横向考虑,现在统统改成纵向。

  这样就得到了每个格子以自身为中心的九宫格的九个格子之和。

  这样累计一下,系数翻个倍,为3。

  第四步,上面其实多加了自身这个格子,于是减掉自身。

  系数就变成4,比之前7要好。

  以上只是简单的说一说道理,而真正在优化卷积、中值滤波等应用的时候,要比这个复杂的多。

稀疏矩阵

  先放个动画。

  我们似乎在上述动画中看到了星际战争^_^

  图像中大多数格子的状态都是无生命,这种情况下,如果还是依次去计算矩阵的每一个格子,是个很大的浪费。

  实际上,我们只需要记录其中状态为有生命的格子就行了,这是因为,下一代有生命的格子就在这一代有生命的格子的近旁。

  这就是稀疏矩阵的出发点,当然,稀疏矩阵本身有着非常多的算法,基本都是本着相近的元素会发生相互作用,从而相近的元素要给予更为快速的查找。对于完全无序的集合,稀疏矩阵的元素一旦多起来,效率非常低下。

  有兴趣的就自己去研究吧,比如四叉树就是常用的空间索引。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档