用Python实现元胞自动机:从生命游戏到交通流模拟(附完整代码)

python实现元胞自动机 该元胞自动机的功能: 1.初始化按一定概率在各个位置生成元胞。 2.迭代,每次迭代元胞八个方向若没有一个以上存活的元胞数量,则该元胞死亡;若一个空格子周围有三个及三个以上元胞存活,则该空格子出长出新元胞。 3.不断迭代,直到所有元胞存活状态不再改变(或所有元胞全部死亡)。 阅读详情

用Python实现元胞自动机:从生命游戏到交通流模拟(附完整代码)

如果你对复杂系统的涌现行为着迷,或者好奇那些看似简单的规则如何演化出令人惊叹的图案,那么元胞自动机(Cellular Automata, CA)绝对是你不能错过的领域。它不仅仅是数学建模中的一个经典工具,更是理解“整体大于部分之和”这一哲学思想的计算实验场。对于Python开发者而言,实现一个元胞自动机模型,就像是在代码中构建一个微缩的、遵循特定物理或社会法则的宇宙,其过程既充满挑战又极具成就感。本文将带你从零开始,用Python亲手搭建两个最著名的元胞自动机模型:康威的生命游戏和一维交通流模型。我们不会停留在理论介绍,而是深入到代码实现的每一个细节,探讨如何高效地处理网格更新、如何可视化动态过程,以及如何将这些模型扩展到更复杂的场景中。无论你是想为你的数据科学项目添加一个有趣的模拟组件,还是纯粹出于对算法和复杂系统的兴趣,这篇文章都将提供一套完整、可运行的代码库和清晰的实现思路。

1. 元胞自动机核心概念与Python实现框架

在动手写代码之前,我们需要统一几个核心概念。你可以把元胞自动机想象成一个巨大的棋盘,棋盘上的每一个格子就是一个“元胞”。每个元胞在任意时刻都处于某一种明确的状态,比如“生”或“死”,“有车”或“无车”。这个棋盘就是“元胞空间”。游戏规则并不复杂:每一个元胞下一时刻的状态,只由它自己当前的状态以及它周围少数几个邻居元胞的当前状态共同决定。所有元胞依据同一套规则,同步更新状态,时间就这样一帧一帧地向前推进。

这种基于局部相互作用的并行更新机制,是元胞自动机能够模拟复杂全局现象的关键。在Python中,我们很自然地会想到使用NumPy数组来表示这个元胞空间。数组的每个元素对应一个元胞的状态值,利用NumPy高效的向量化运算,我们可以避免低效的循环,一次性计算整个网格在下一时刻的状态。

首先,我们来搭建一个通用的元胞自动机模拟框架。这个框架将负责初始化网格、定义邻居规则、执行状态更新循环以及进行可视化。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import colors

class CellularAutomaton:
    """
    一个通用的二维元胞自动机基类。
    """
    def __init__(self, rows, cols, states=None):
        """
        初始化元胞自动机。
        
        参数:
            rows (int): 网格行数。
            cols (int): 网格列数。
            states (list, optional): 所有可能的状态列表。默认为[0, 1]。
        """
        self.rows = rows
        self.cols = cols
        self.states = states if states is not None else [0, 1]
        # 当前网格状态,初始化为随机状态
        self.grid = np.random.choice(self.states, size=(rows, cols))
        # 历史记录,用于回溯或分析
        self.history = [self.grid.copy()]

    def get_neighbors(self, i, j):
        """
        获取位置(i, j)处元胞的邻居状态。
        这是一个需要子类具体实现的方法。
        
        参数:
            i (int): 行索引。
            j (int): 列索引。
        
        返回:
            ndarray: 邻居状态数组。
        """
        raise NotImplementedError("子类必须实现此方法以定义邻居规则")

    def update_rule(self, cell_state, neighbors):
        """
        根据当前元胞状态及其邻居状态,计算下一时刻的状态。
        这是一个需要子类具体实现的方法。
        
        参数:
            cell_state: 当前元胞状态。
            neighbors (ndarray): 邻居状态数组。
        
        返回:
            下一时刻的元胞状态。
        """
        raise NotImplementedError("子类必须实现此方法以定义更新规则")

    def step(self):
        """
        执行一次同步更新,将整个网格推进到下一时刻。
        """
        new_grid = np.zeros_like(self.grid)
        for i in range(self.rows):
            for j in range(self.cols):
                neighbors = self.get_neighbors(i, j)
                new_grid[i, j] = self.update_rule(self.grid[i, j], neighbors)
        self.grid = new_grid
        self.history.append(self.grid.copy())

    def simulate(self, steps):
        """
        模拟指定步数。
        
        参数:
            steps (int): 要模拟的步数。
        """
        for _ in range(steps):
            self.step()

    def animate(self, steps, interval=200, cmap='binary'):
        """
        创建并运行动画,可视化模拟过程。
        
        参数:
            steps (int): 动画总帧数(模拟步数)。
            interval (int): 动画帧间隔(毫秒)。
            cmap (str): 用于渲染网格的matplotlib色彩映射。
        """
        fig, ax = plt.subplots()
        # 根据状态数创建颜色映射
        if len(self.states) <= 2:
            cmap = colors.ListedColormap(['white', 'black'])
            bounds = [0, 0.5, 1]
            norm = colors.BoundaryNorm(bounds, cmap.N)
        else:
            norm = None
        img = ax.imshow(self.grid, cmap=cmap, norm=norm, interpolation='nearest')
        ax.set_xticks([])
        ax.set_yticks([])
        plt.title('Cellular Automaton Simulation')

        def update(frame):
            self.step()
            img.set_data(self.grid)
            return [img]

        ani = FuncAnimation(fig, update, frames=steps, interval=interval, blit=True, repeat=False)
        plt.show()
        return ani

注意:上面的基类中,step方法使用了双重循环,这在网格很大时可能成为性能瓶颈。在后续的具体模型实现中,我们将展示如何利用NumPy的切片和卷积操作进行向量化优化,这是提升Python科学计算效率的关键技巧。

这个框架为我们后续实现具体模型打下了基础。接下来,我们将在这个框架上构建第一个经典模型:生命游戏。

2. 实现康威的生命游戏:探索秩序与混沌的边缘

生命游戏(Game of Life)由数学家约翰·康威在1970年提出,它可能是最广为人知的元胞自动机。规则极其简单,却能够产生出极其复杂的模式,如滑翔机、脉冲星甚至可自我复制的结构。其规则基于摩尔邻居(Moore Neighborhood),即一个元胞的上、下、左、右、左上、右上、左下、右下共八个相邻元胞。

生命游戏规则(经典版本):

  1. 生存:如果一个活细胞(状态为1)周围有2个或3个活细胞邻居,它在下一世代仍然存活。
  2. 死亡:
    • 孤独:活细胞周围活细胞数少于2个,则因孤独而死亡。
    • 过度拥挤:活细胞周围活细胞数多于3个,则因过度拥挤而死亡。
  3. 繁殖:如果一个死细胞(状态为0)周围恰好有3个活细胞邻居,则在下一世代复活。

现在,我们继承之前的通用框架,创建一个GameOfLife类。关键在于高效计算每个元胞的活邻居数量。我们可以使用二维卷积(scipy.signal.convolve2d)来一次性计算整个网格的邻居和,这比循环快几个数量级。

from scipy.signal import convolve2d

class GameOfLife(CellularAutomaton):
    """
    康威生命游戏的实现。
    """
    def __init__(self, rows=100, cols=100, initial_config='random', density=0.2):
        """
        初始化生命游戏网格。
        
        参数:
            rows, cols: 网格尺寸。
            initial_config (str): 初始配置,'random'或'glider'等。
            density (float): 当initial_config='random'时,细胞的初始存活概率。
        """
        super().__init__(rows, cols, states=[0, 1]) # 状态:0死,1活
        if initial_config == 'random':
            self.grid = (np.random.rand(rows, cols) < density).astype(int)
        elif initial_config == 'glider':
            # 在网格中央放置一个滑翔机
            self.grid[:, :] = 0
            center_r, center_c = rows//2, cols//2
            glider = np.array([[0, 1, 0],
                               [0, 0, 1],
                               [1, 1, 1]])
            r_start = center_r - 1
            c_start = center_c - 1
            self.grid[r_start:r_start+3, c_start:c_start+3] = glider
        self.history = [self.grid.copy()]
        # 定义卷积核,用于计算活邻居数(不包括中心自身)
        self.kernel = np.array([[1, 1, 1],
                                [1, 0, 1],
                                [1, 1, 1]])

    def get_neighbors(self, i, j):
        # 在向量化版本中,此方法不会被直接调用,但为保持接口一致而保留
        # 实际计算在update_rule_vectorized中完成
        pass

    def step_vectorized(self):
        """
        使用卷积进行向量化更新的step方法,性能远高于循环。
        """
        # 计算每个元胞的活邻居数量
        neighbor_sum = convolve2d(self.grid, self.kernel, mode='same', boundary='wrap')
        # 应用生命游戏规则
        birth = (self.grid == 0) & (neighbor_sum == 3)
        survive = (self.grid == 1) & ((neighbor_sum == 2) | (neighbor_sum == 3))
        # 生成新网格
        new_grid = np.where(birth | survive, 1, 0)
        self.grid = new_grid
        self.history.append(self.grid.copy())

    def step(self):
        """重写父类方法,使用向量化版本。"""
        self.step_vectorized()

    def update_rule(self, cell_state, neighbors):
        # 在向量化版本中,此方法不会被直接调用
        pass

使用这个类,你可以轻松地创建并运行动画:

# 创建一个100x100的随机初始网格的生命游戏
life = GameOfLife(rows=80, cols=80, initial_config='random', density=0.3)
# 运行动画,模拟200代
ani = life.animate(steps=200, interval=100)

除了随机初始状态,生命游戏中有许多著名的初始图案能产生有趣的动力学行为。下表列举了几个经典图案及其特性:

图案名称描述行为特性在代码中的初始化方式
滑翔机 (Glider)由5个活细胞组成的小型图案。在网格上沿对角线方向持续移动。在指定位置放置特定的3x3矩阵。
轻量级飞船 (LWSS)比滑翔机更大的移动图案。沿直线移动,速度比滑翔机慢。定义特定的4x5矩阵。
脉冲星 (Pulsar)一个周期为3的振荡器。每3代在三种形态间循环。定义复杂的13x13矩阵。
高斯帕滑翔机枪 (Gosper Glider Gun)由多个稳定结构组成。能周期性地发射出滑翔机。定义复杂的36x9矩阵。

提示:在探索生命游戏时,边界条件的选择会影响图案的行为。上面的代码使用了boundary='wrap',即周期性边界(环面拓扑),图案从一边移出会从对边移入。你也可以尝试boundary='fill'(固定边界,外侧视为死细胞)来观察不同效果。

通过调整初始密度和观察演化,你会发现生命游戏的行为可以大致归入斯蒂芬·沃尔夫勒姆提出的四类:趋于均匀(平稳型)、形成稳定或周期振荡的结构(周期型)、产生看似随机的混沌(混沌型),以及介于周期和混沌之间、能产生持续复杂结构的复杂型。生命游戏正是复杂型的典型代表。

3. 构建一维交通流模型:从NS模型到现实交通模拟

将视线从二维的生命游戏转向一维,元胞自动机同样能出色地模拟另一种常见系统:交通流。Nagel-Schreckenberg (NS) 模型是一个经典的一维随机元胞自动机交通模型。在这个模型中,一条道路被离散化为一系列格子(元胞),每个格子要么被一辆车占据,要么为空。每辆车有一个速度(单位:格子/时间步),并且遵循一套模拟驾驶员行为的规则。

NS模型的核心规则(每时间步按顺序执行):

  1. 加速:只要没达到最大速度,司机就倾向于加速。v -> min(v+1, v_max)
  2. 减速(安全距离):为了避免撞上前车,如果距离前车太近,速度必须减到gap-1。v -> min(v, gap-1),其中gap是到前一辆车之间的空单元格数。
  3. 随机慢化:以概率p,司机可能会随机减速一个单位(模拟注意力不集中、路面状况等)。v -> max(v-1, 0)
  4. 运动:车辆根据更新后的速度向前移动v个格子。

下面我们用Python实现这个模型,并观察交通相变(自由流、同步流、拥堵)现象。

class TrafficFlowNS(CellularAutomaton):
    """
    基于Nagel-Schreckenberg模型的一维交通流模拟。
    状态:每个元胞存储一个整数,-1表示空,非负整数表示车辆的速度。
    但为了继承框架,我们使用一个二维数组(单行)来存储,并额外维护速度和位置信息。
    """
    def __init__(self, length=100, density=0.2, v_max=5, slowdown_prob=0.3):
        """
        初始化交通流模型。
        
        参数:
            length (int): 道路长度(元胞数)。
            density (float): 车辆密度(0到1之间)。
            v_max (int): 车辆最大速度。
            slowdown_prob (float): 随机慢化概率p。
        """
        # 使用1行*length列的网格,但状态不再是简单的0/1
        super().__init__(rows=1, cols=length, states=None)
        self.length = length
        self.density = density
        self.v_max = v_max
        self.p = slowdown_prob
        
        # 重新初始化:创建道路,-1表示空位
        self.road = np.full(length, -1, dtype=int)
        # 随机放置车辆,初始速度设为0
        num_cars = int(density * length)
        car_positions = np.random.choice(length, size=num_cars, replace=False)
        self.road[car_positions] = 0  # 初始速度为0
        # 为了高效更新,我们维护一个车辆列表:每个元素是[位置, 速度]
        self.cars = [[pos, 0] for pos in sorted(car_positions)]
        self.grid = self._road_to_grid() # 为了兼容父类的可视化
        self.history = [self.grid.copy()]

    def _road_to_grid(self):
        """将道路状态转换为一个二值网格用于可视化(1有车,0无车)。"""
        grid_1d = (self.road != -1).astype(int)
        return grid_1d.reshape(1, -1) # 变成1行N列的二维数组

    def _update_speeds(self):
        """更新所有车辆的速度(规则1-3)。"""
        num_cars = len(self.cars)
        for i in range(num_cars):
            pos_i, v_i = self.cars[i]
            # 规则1: 加速
            v_i = min(v_i + 1, self.v_max)
            
            # 规则2: 减速(保持安全距离)
            # 计算到前车的距离(考虑周期性边界)
            next_pos = self.cars[(i + 1) % num_cars][0]
            if next_pos > pos_i:
                gap = next_pos - pos_i - 1
            else: # 周期性边界,绕回开头
                gap = (next_pos + self.length) - pos_i - 1
            v_i = min(v_i, gap)
            
            # 规则3: 以概率p随机慢化
            if np.random.rand() < self.p:
                v_i = max(v_i - 1, 0)
            
            self.cars[i][1] = v_i

    def _update_positions(self):
        """根据速度更新所有车辆的位置(规则4)。"""
        # 先按位置排序,确保顺序更新(对于一维模型,通常从最前面的车开始更新或并行更新)
        # NS模型通常是同步更新,但为了避免同一格子多辆车,需要特殊处理或使用“换道”思想。
        # 这里采用一个简单方法:创建新的空道路,然后按顺序放置车辆。
        new_road = np.full(self.length, -1, dtype=int)
        for i, (pos, v) in enumerate(self.cars):
            new_pos = (pos + v) % self.length # 周期性边界
            # 检查新位置是否已被占(理论上在NS规则下不应发生,但安全起见)
            while new_road[new_pos] != -1:
                new_pos = (new_pos + 1) % self.length # 如果被占,移到下一个格子(模拟轻微挤压)
            new_road[new_pos] = v
            self.cars[i][0] = new_pos
        self.road = new_road
        # 按新位置重新排序车辆列表
        self.cars.sort(key=lambda x: x[0])

    def step(self):
        """执行一个完整的时间步。"""
        self._update_speeds()
        self._update_positions()
        self.grid = self._road_to_grid()
        self.history.append(self.grid.copy())

    def get_flow(self):
        """计算当前时间步的流量(单位时间内通过某点的车辆数)。"""
        # 简单估算:平均速度 * 密度
        avg_speed = np.mean([v for _, v in self.cars])
        return avg_speed * self.density

    def animate(self, steps, interval=200):
        """重写动画方法,更适合一维交通流可视化。"""
        fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))
        # 第一幅图:道路状态快照
        img = ax1.imshow(self.grid, cmap='binary', aspect='auto')
        ax1.set_title(f'Traffic Flow (Density={self.density}, Vmax={self.v_max}, p={self.p})')
        ax1.set_xlabel('Cell Position')
        ax1.set_yticks([])
        # 第二幅图:流量随时间变化
        flow_history = []
        line, = ax2.plot([], [], 'b-')
        ax2.set_xlim(0, steps)
        ax2.set_ylim(0, self.v_max * self.density * 1.2)
        ax2.set_xlabel('Time Step')
        ax2.set_ylabel('Flow (veh/step)')
        ax2.set_title('Flow vs. Time')
        ax2.grid(True)

        def update(frame):
            self.step()
            # 更新道路图像
            img.set_data(self.grid)
            # 更新流量历史曲线
            flow_history.append(self.get_flow())
            line.set_data(range(len(flow_history)), flow_history)
            ax2.relim()
            ax2.autoscale_view(scalex=False, scaley=True)
            return [img, line]

        ani = FuncAnimation(fig, update, frames=steps, interval=interval, blit=False, repeat=False)
        plt.tight_layout()
        plt.show()
        return ani

运行这个模型,你可以直观地看到车辆如何形成车队、如何产生“幽灵堵车”(即使没有事故,由于随机减速和传播效应也会形成拥堵),以及流量如何随密度变化。

# 模拟一段中等密度的交通
sim = TrafficFlowNS(length=200, density=0.15, v_max=5, slowdown_prob=0.2)
ani = sim.animate(steps=300, interval=100)

为了系统研究交通行为,我们可以进行参数扫描。例如,固定v_max=5和p=0.3,改变车辆密度density,观察平均流量和平均速度的变化。这能帮助我们绘制出经典的流量-密度关系图,其中可以清晰地看到自由流相、饱和流相和拥堵相。

交通相密度范围(示例)特征描述平均速度流量
自由流低密度 (如 <0.1)车辆间互不影响,均以最大速度或接近最大速度行驶。高,接近v_max随密度线性增加
同步流/饱和流中等密度 (如 0.1-0.3)车辆开始相互影响,形成车队,速度分布较广,可能出现走走停停。中等达到最大值(道路容量)
宽移动堵塞高密度 (如 >0.3)出现大规模、几乎静止的拥堵区域,并向上下游传播。极低低,随密度增加而下降

注意:NS模型是一个高度简化的模型。现实交通中,驾驶员的反应时间、车辆加速度、车道变换等因素未被考虑。你可以尝试扩展这个模型,例如引入慢启动规则(车辆从静止加速需要更多时间步)、多车道(需要定义换道规则)或异构车辆(不同车辆有不同的v_max或p值),这会让模拟更加贴近现实。

4. 性能优化与高级技巧:让模拟飞起来

当网格尺寸变大或模拟步数增多时,纯Python循环的效率瓶颈会非常明显。为了让我们的元胞自动机模拟能够处理更大规模的系统,掌握一些性能优化技巧至关重要。

1. 向量化计算:拥抱NumPy 这是提升Python科学计算性能的首选方法。核心思想是避免在Python层面使用for循环,转而利用NumPy底层用C实现的数组操作。在生命游戏部分,我们已经展示了如何使用scipy.signal.convolve2d进行邻居求和。对于更通用的邻居规则,可以使用np.roll来移位网格。

def step_life_vectorized_numpy(grid):
    """使用NumPy的roll操作实现生命游戏,避免显式循环。"""
    # 计算活邻居数量
    # 将网格向八个方向滚动并求和
    neighbor_sum = (
        np.roll(grid, 1, axis=0) + np.roll(grid, -1, axis=0) +  # 上下
        np.roll(grid, 1, axis=1) + np.roll(grid, -1, axis=1) +  # 左右
        np.roll(grid, (1, 1), axis=(0,1)) + np.roll(grid, (1, -1), axis=(0,1)) + # 对角
        np.roll(grid, (-1, 1), axis=(0,1)) + np.roll(grid, (-1, -1), axis=(0,1))
    )
    # 应用规则
    birth = (grid == 0) & (neighbor_sum == 3)
    survive = (grid == 1) & ((neighbor_sum == 2) | (neighbor_sum == 3))
    return np.where(birth | survive, 1, 0)

2. 使用Numba进行即时编译 对于无法完全向量化的复杂规则,Numba库是一个神器。它通过装饰器将Python函数即时编译为机器码,能带来数十倍甚至上百倍的性能提升。

import numba

@numba.jit(nopython=True)
def step_life_numba(grid):
    """使用Numba加速的生命游戏更新函数(仍使用循环,但速度极快)。"""
    rows, cols = grid.shape
    new_grid = np.zeros_like(grid)
    for i in range(rows):
        for j in range(cols):
            # 计算邻居和(考虑周期性边界)
            total = 0
            for di in (-1, 0, 1):
                for dj in (-1, 0, 1):
                    if di == 0 and dj == 0:
                        continue
                    ni = (i + di) % rows
                    nj = (j + dj) % cols
                    total += grid[ni, nj]
            # 应用规则
            if grid[i, j] == 1:
                if total == 2 or total == 3:
                    new_grid[i, j] = 1
                else:
                    new_grid[i, j] = 0
            else:
                if total == 3:
                    new_grid[i, j] = 1
    return new_grid

3. 稀疏矩阵存储 对于像生命游戏这样,活细胞密度通常很低的网格,使用稀疏矩阵格式(如scipy.sparse)可以大幅减少内存占用和计算量,因为你只需要处理非零元素。

4. 并行计算 元胞自动机的同步更新本质上是并行的。你可以使用multiprocessing或concurrent.futures库将网格分块,在多核CPU上并行计算每一块的下一个状态。对于超大规模模拟,可以考虑使用GPU计算库如CuPy或JAX,它们能将数组计算直接卸载到显卡上。

下面是一个简单的性能对比表格,展示了不同方法在模拟1000步1000x1000网格生命游戏时的相对速度(基准为纯Python循环):

实现方法关键技术相对速度(近似)适用场景
纯Python双重循环基础实现1x (基准)教学、小网格原型
NumPy向量化 (roll)数组移位与广播10x - 50x中等网格,规则简单可向量化
SciPy卷积 (convolve2d)二维卷积运算50x - 200x邻居规则为求和类操作
Numba JIT编译LLVM即时编译100x - 500x复杂规则,循环难以向量化
GPU加速 (CuPy)大规模并行计算1000x+超大网格(如10k x 10k)

提示:在开发过程中,建议先用简单清晰的循环实现逻辑,确保正确性。在逻辑验证无误后,再针对性能瓶颈应用上述优化技巧。使用%timeit魔术命令(在Jupyter Notebook中)或time模块来测量函数运行时间,做到有的放矢。

掌握了这些优化技巧,你就能轻松应对更大规模、更长时间的模拟需求,为研究更复杂的元胞自动机模型(如森林火灾模型、表面吸附模型、晶体生长模型)打下坚实的基础。元胞自动机的魅力在于,用简单的代码规则探索复杂的系统行为,每一次模拟都像是一次新的实验。

元胞自动机-附代码注释 元胞自动机(Cellular Automata CA)是一种时空离散的局部动力学模型,是研究复杂系统的一种典型方法,适用于空间复杂系统的时空动态模拟研究 元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的规则构成。凡是满足这些规则的模型都可以算作是元胞自动机模型。因此,元胞自动机是一类模型的总称,或者说是一个方法框架。 在CA模型中,散布在规则格网(Lattice Grid)中的每一元胞(Cell)取有限的离散状态,遵循同样的作用规则,依据确定的局部规则作同步更新。大量元胞通过简单的相互作 阅读详情

相关推荐

元胞自动机python代码_Python实现元胞自动机(康威生命游戏)

元胞自动机是很常用的传播/交通模型,因此写下这篇文章,以后忘了可以再翻看元胞自动机元胞自动机又被称为康威生命游戏,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。它最初于1970年10月在《科学美国人》杂志上马丁·葛登能的“数学游戏”专栏出现元胞自动机是一个零玩家游戏。他包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞。一个细胞在下一时刻的生死取决于相邻八个方格中或...

weixin_35878217的博客 3167

元胞自动机代码超通俗解释(MATLAB)

元胞自动机超通俗解释,小白专用,MATLAB代码

m0_62526778的博客 1612

Python实现元胞自动机代码与绘图实战指南

元胞自动机(Cellular Automata,简称CA)是计算数学的一个概念,由多组规则和状态组成,通过迭代计算可模拟复杂系统的行为。它由一维或多维的元胞网格构成,每个元胞具有有限数量的状态,依据既定的局部规则进行状态更新。元胞自动机的魔力在很大程度上来源于其规则定义和状态更新机制。这一章节将深入探讨这些核心概念,并展示如何用Python实现它们。元胞自动机的运作依赖于一套简单的规则,它们指导着每个元胞如何基于周围邻居的状态来更新自己的状态。

weixin_30765637的博客 1503

简单元胞自动机实现—Python

基于Python编程语言实现简单元胞自动机的小游戏

不要仅为成功而努力,要为做一个有价值的人而努力 2999

毫米波雷达入门知识

毫米波雷达入门知识

ssbzxcvbnm1234567的博客 5446

Xilinx Vitis 2020.1中Microblaze SREC SPI Bootloader初始化失败的调试与修复指南

本文详细解析了在Xilinx Vitis 2020.1开发环境中,Microblaze SREC SPI Bootloader初始化失败的常见原因与解决方案。核心问题通常源于Flash上电时序或软件配置,如`serial_flash_family`参数未生效、链接脚本设置不当或BRAM初始化文件选择错误。文章提供了从硬件配置检查、工程设置修正到代码级添加重试机制的完整调试路径,帮助开发者快速定位并修复启动故障,确保系统稳定启动。

weixin_29163857的博客 186

【数学建模】元胞自动机

【数学建模】元胞自动机

shaozheng0503的博客 5198

YOLOv11涨点改进| Kimi团队 2026 |独家创新首发、注意力改进篇|爆火AttnRes残差自注意力模块,含多种创新改进,借助残差思想,缓解细节信息在传播过程中被稀释,促进YOLOv11涨点

🔥本文提出AttnRes残差自注意力模块,通过深度维度的注意力加权机制替代传统固定残差累加方式,使YOLOv11网络能自适应选择更有价值的历史层特征进行聚合。该方法缓解了浅层细节信息在深层传播过程中被稀释的问题,有效融合浅层纹理与深层语义特征,提升小目标、密集目标和复杂场景的检测能力。AttnRes还改善了深层网络的梯度分布与训练稳定性,增强模型收敛质量和泛化能力。实验表明,该模块能以较小计算开销显著提升YOLOv11的特征表达能力、检测精度和整体鲁棒性。文中详细介绍了模块结构、实现原理、优势特点

Ai缝合怪、助力小伙伴高效发论文 125

python元胞自动机模拟交通_最有趣的元胞自动机模型

元胞自动机(Cellular Automata,CA)是20世纪50年代初由计算机之父冯·诺依曼(J.von Neumann)为了模拟生命系统所具有的自复制功能而提出来的。此后,史蒂芬·沃尔夫勒姆(Stephen Wolfram)对元胞自动机理论进行了深入的研究。例如,他对一维初等元胞机全部256种规则所产生的模型进行了深入研究,并将元胞自动机分为平稳型、周期型、混沌型和复杂型 4 种类型。这是一...

weixin_39881859的博客 2904

多个linux系统安装到一块硬盘(Kylin+UOS+ubuntu)

之前写过一篇类似的文档,笔者把kylin和UOS安装在一块硬盘上上一篇的文档地址多个linux系统安装到一块硬盘(Kylin+UOS)_银河麒麟系统和uos安装成双系统-优快云博客本次记录的是三个系统到一块硬件上银河麒麟:Kylin-Desktop-V10-SP1-Release-2107-arm64统信:uniontechos-desktop-20-professional-1050-arm64乌班图:ubuntu-22.04.5-live-server-arm64。

aggs1990的专栏 570

R语言Rstudio突然无法启动且报错:ERROR system error 42 [str: 一, len: 3, from: UTF-8, to: ISO8859-1]...如何解决

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 2848

元胞自动机( Cellular Automata)研究附Python代码

元胞自动机 (Cellular Automata, CA) 作为一种离散空间、离散时间的动力系统,凭借其简洁的规则、强大的模拟能力以及广泛的应用领域,在近几十年受到了学界和工业界的广泛关注。本文将深入探讨元胞自动机的理论基础,回顾其在各个领域的应用拓展,并展望其未来的发展趋势。一、 元胞自动机的理论基础:从简单规则到复杂行为元胞自动机的核心思想是将复杂系统分解为简单的、相互作用的个体(元胞),通过定义简单的局部规则来驱动这些个体在离散空间和时间上的演化,从而模拟复杂系统的行为。

qq_72962865的博客 1730

深入解析ZYNQ PL触发PS中断:从原理到创新实践

通过本文,您不仅学会了ZYNQ PL-PS中断的基础实现,更掌握了动态优先级调整中断负载均衡等创新技术。响应延迟降低40%以上系统吞吐量提升2-3倍功耗降低30%支持更复杂的实时应用硬件是身体的骨骼,软件是流动的血液,而中断则是连接二者的神经系统。只有精确控制每一条神经冲动,才能构建真正智能的嵌入式系统。拓展思考如何将AI决策引入中断调度?能否实现跨芯片中断同步?量子计算对中断架构的挑战?

QQ_778132974的博客 417

【交通流】基于元胞自动机模拟交通流单车道Nasch模型(含时空图)附Matlab代码

摘要: 交通流模拟是理解和预测交通系统行为的关键工具。本文基于元胞自动机 (Cellular Automata, CA) 方法,模拟单车道交通流的Nagel-Schreckenberg (NaSch) 模型。NaSch模型因其简洁性和对交通流复杂现象的有效捕捉而备受关注。本文首先详细介绍NaSch模型的规则,然后通过计算机程序实现该模型,并通过时空图直观地展示不同参数下交通流的演化过程,最终分析车速、密度与流量之间的关系,探讨NaSch模型的优缺点及未来研究方向。关键词: 交通流模拟;元胞自动机;

qq_59747472的博客 1388

echarts 饼图(加载进度条动画效果)

1、外侧动画细线效果运动“custom”自定义系列中“renderItem”属性来实现,动态修改起始角度和终止角度。2、圆环使用" pie "类型添加两个data值来画百分比圆环,动态修改data中的值。

God's asylum的博客 1631

【学习系列】SAP RAP 3:添加多层级的子节点

本文详细介绍了在SAP ABAP RAP开发中如何创建多层级业务对象。主要内容包括:1)创建明细和计划行层级的数据库表及CDS视图;2)使用association和composition关键字建立父子关联关系;3)创建各层级的投影视图并设置层级关系;4)更新行为定义,添加关联、操作权限等控制;5)更新服务定义公开新增视图;6)创建元数据扩展优化UI展示。通过这一系列步骤,实现了从抬头到明细再到计划行的完整业务对象层级结构,为后续UI功能扩展奠定了基础。

DeveloperMrMeng的博客 588

元胞自动机模拟病毒传染(SEIR模型)(Python代码实现)

元胞自动机(Cellular Automaton,简称CA)是一种离散的动力学模型,由现代计算机的创始人之一冯·诺依曼在20世纪50年代提出,用于模拟生物细胞的自我复制。元胞自动机由网格、元胞、邻居、边界和规则等要素构成,其中网格定义了元胞的空间分布,元胞是模型的基本单元,邻居定义了元胞之间的相互作用范围,边界限定了模拟的空间范围,而规则则决定了元胞状态的变化。

qq_58146006的博客 691

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

元胞自动机建模指南:从生命游戏到森林火灾模拟

元胞自动机是一种基于离散空间、时间和状态的动态系统建模框架,其核心原理是通过定义大量简单个体(元胞)的局部互动规则,模拟出全局的复杂行为。这一技术价值在于为复杂系统研究提供了一种自底向上、计算高效的范式,尤其适用于模拟具有空间局部相互作用的现象,如交通流、传染病传播和生态演化。在工程实践中,元胞自动机常被用于构建直观且易于实现的仿真模型,例如通过定义元胞状态、邻居关系和演化规则来模拟森林火灾蔓延或城市扩张。本文以森林火灾模型为例,深入探讨了如何将环境因素(如风向)和随机性融入规则设计,并强调了使用双缓冲区技

weixin_30608503的博客 512

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: Flask开发服务器警告?3种WSGI服务器快速切换方案(附代码对比)
下一篇: Android 12开机动画DIY全攻略:从制作到替换(MT管理器+ADB双方案)
algae
博客等级 码龄19年 1380粉丝 1719原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值