zoukankan      html  css  js  c++  java
  • Python 元胞自动机模拟——生命游戏

    简介
    元胞自动机(cellular automata) 是离散而抽象的计算系统。元胞自动机在时间和空间上是离散的,最小单位是简单元胞(单元格)。每个元胞会产生有限数量的状态集,后续元胞由其邻域元胞的状态确定。这里所说的领域元胞,是指当前元胞的前一个元胞(记作元胞A)以及元胞A左右两个元胞。也就是说,邻域元胞总共包含三个元胞。给定初始层的状态,基于一定规则,我们可以不断更新下一层元胞的状态。通俗的讲,元胞自动机就是基于一定规则的“繁衍机器”。

    最简单的例子
    这里,我们选取的元胞状态只有两种,分别为 0 和 1。每一层由 64 个元胞组成,若元胞状态为 1,那么控制台将打印星号(*);如果元胞状态为 0,那么控制台将打印连字符(-)。也就是说,每一行由 64 个混合星号与连字符的图案组成。
    那么,我们如何确定每一行的状态呢?

    首先,我们要对第一行进行初始化操作。我们设置第 31 个元胞的状态为 1、其余 63 个元胞的状态为 0.
    状态更新规则:若当前元胞的前一个元胞的状态为 1,或者前一个元胞的左右两边的元胞的状态有且只有一个值为 1, 那么该元胞的状态就为 1。反之,元胞的状态设为 0。对于第一列和最后一列,我们只需分别考虑右元胞和左元胞即可。对于中间部分的元胞来说,若其领域元胞的状态为[0,1,0]、[0,0,1]、[1,0,0]、[1,1,0]等状态时,当前元胞的状态就为 1。
    代码

    """
    元胞自动机 Python 实现
    """
    import numpy as np
    import matplotlib.pyplot as plt
     
     
    class GameOfLife(object):
     
      def __init__(self, cells_shape):
        """
        Parameters
        ----------
        cells_shape : 一个元组,表示画布的大小。
     
        Examples
        --------
        建立一个高20,宽30的画布
        game = GameOfLife((20, 30))
         
        """
     
        # 矩阵的四周不参与运算
        self.cells = np.zeros(cells_shape)
     
        real_width = cells_shape[0] - 2
        real_height = cells_shape[1] - 2
         
        self.cells[1:-1, 1:-1] = np.random.randint(2, size=(real_width, real_height))
        self.timer = 0
        self.mask = np.ones(9)
        self.mask[4] = 0
       
      def update_state(self):
        """更新一次状态"""
        buf = np.zeros(self.cells.shape)
        cells = self.cells
        for i in range(1, cells.shape[0] - 1):
          for j in range(1, cells.shape[0] - 1):
            # 计算该细胞周围的存活细胞数
            neighbor = cells[i-1:i+2, j-1:j+2].reshape((-1, ))
            neighbor_num = np.convolve(self.mask, neighbor, 'valid')[0]
            if neighbor_num == 3:
              buf[i, j] = 1
            elif neighbor_num == 2:
              buf[i, j] = cells[i, j]
            else:
              buf[i, j] = 0
        self.cells = buf
        self.timer += 1
       
      def plot_state(self):
        """画出当前的状态"""
        plt.title('Iter :{}'.format(self.timer))
        plt.imshow(self.cells)
        plt.show()
     
      def update_and_plot(self, n_iter):
        """更新状态并画图
        Parameters
        ----------
        n_iter : 更新的轮数
        """
        plt.ion()
        for _ in range(n_iter):
          plt.title('Iter :{}'.format(self.timer))
          plt.imshow(self.cells)
          self.update_state()
          plt.pause(0.2)
        plt.ioff()
               
     
    if __name__ == '__main__':
      game = GameOfLife(cells_shape=(60, 60))
      game.update_and_plot(200)

  • 相关阅读:
    Multi-Sensor, Multi- Network Positioning
    基于智能手机的3D地图导航
    2010上海世博会三维导航地图
    hdu 5452(树链刨分)
    蓝桥杯危险系数
    蓝桥杯横向打印二叉树(中序+先序遍历)
    蓝桥杯幸运数(线段树)
    hdu 5185(DP)
    2014江西理工大学C语言程序设计竞赛高级组题解
    uva 12730(期望经典)
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/12421266.html
Copyright © 2011-2022 走看看