You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的初等元胞自动机按规则集无法显示正确图像?

问题分析与修复方案

核心问题1:原数组被实时修改,状态污染

你在计算每个细胞的下一代状态时,直接把新值写到gen[procces]里,后面的细胞计算时,用到的邻居状态已经是更新后的,不是最初的上一代状态——这直接打乱了元胞自动机的演化逻辑,只有规则2这种极简单的规则碰巧没出问题。

核心问题2:数组边界越界,读取随机值

处理第一个细胞(procces=0)时,procces-1是-1,访问gen[-1]属于数组越界,会读内存里的随机垃圾值;处理最后一个细胞时,procces+1超出数组长度,同样越界读随机值,这就是你看到随机输出的主要原因。

修复后的完整代码

#include <stdio.h>

// 初始状态,统一格式避免长度混乱
int gen[] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
// 示例规则集:规则30,可自行替换成其他规则
int ruleset[] = {0,0,0,1,1,1,1,0};
int size = sizeof(gen) / sizeof(gen[0]);
const int alive = 1;
const int dead = 0;

int rules(int a, int b, int c) {
    // 把三位邻居状态转成二进制索引,比一堆if简洁多了
    int index = (a << 2) | (b << 1) | c;
    // 反转索引对应你原来的if顺序(从111到000对应ruleset[0]到[7])
    return ruleset[7 - index];
}

int main(void) {
    // 用临时数组存下一代状态,避免修改原数组影响计算
    int next_gen[sizeof(gen)/sizeof(gen[0])];
    int iterations;
    int process;

    // 先打印初始状态,原来的代码直接跳过了这一步
    for (process = 0; process < size; process++) {
        printf(gen[process] == alive ? "@" : " ");
    }
    printf("\n");

    for (iterations = 0; iterations < 100; iterations++) {
        for (process = 0; process < size; process++) {
            // 循环边界处理:首尾细胞的邻居绕到数组另一端,符合初等元胞自动机常规设定
            int left = (process == 0) ? gen[size - 1] : gen[process - 1];
            int right = (process == size - 1) ? gen[0] : gen[process + 1];
            int cell = gen[process];

            next_gen[process] = rules(left, cell, right);
        }

        // 所有细胞计算完再更新原数组,同时打印当前代
        for (process = 0; process < size; process++) {
            gen[process] = next_gen[process];
            printf(gen[process] == alive ? "@" : " ");
        }
        printf("\n");
    }
    return 0;
}

关键修复点

  • 临时数组next_gen:先把所有细胞的下一代状态算完存到临时数组,再覆盖原数组,保证每一步都用上一代的完整状态计算。
  • 边界处理:用循环边界解决越界问题,让数组首尾相连,符合初等元胞自动机的标准行为。
  • 简化规则函数:用二进制转索引的方式替代一堆if,既高效又不容易写错。
  • 补全初始状态打印:原来的代码直接开始迭代,现在先输出初始状态,逻辑更完整。

内容的提问来源于stack exchange,提问作者Saw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:17:00