初等元胞自动机C++代码

本文介绍了使用C++编程实现初等元胞自动机的过程,探讨了不同规则对迭代数据的影响,并展示了110号规则生成的数据图像。作者分享了代码实现细节和优化建议。
摘要由CSDN通过智能技术生成

        翻到很早以前在看《复杂》一书时写的“初等元胞自动机”的C++代码,是关于在具有简单的规则和初始数据时,不同规则对之后迭代数据的影响,以及某些特别规则会使原本杂乱的数据组成的图像变得有序。当时觉得自己复现一下这部分内容应该会有更深刻的体会,当时实现方法有点笨,也没有尝试优化过,有很多不必要的繁杂的地方,请见谅,但确实也能看出效果,数据会输出到同目录下自动生成的 out文件 中,也方便看图像效果。如果用vscode打开out文件的话,右边的代码缩略图也能很方便的看出数据形成的图像。

        附下图,是其中一种规则形成的部分数据图像(110号规则),不同的规则效果会有不同,因为规则的本质是一组八位的二进制数据,所以共有2^8=256种规则,在代码中也有体现。在右边的缩略图中可以看到数据形成的图像迭代的过程。这里为了方便看清,所以在输出中我用实心和空心的方块代替了数字1和0。在代码中可以更改输出的模式。

#include <bits/stdc++.h>
using namespace std;

int test001(int l,int m,int r){//迭代规则001号 // 110规则
    if(l==0&&m==0&&r==0){return 0;}
    if(l==0&&m==0&&r==1){return 1;}
    if(l==0&&m==1&&r==0){return 1;}
    if(l==0&&m==1&&r==1){return 1;}
    if(l==1&&m==0&&r==0){return 0;}
    if(l==1&&m==0&&r==1){return 1;}
    if(l==1&&m==1&&r==0){return 1;}
    if(l==1&&m==1&&r==1){return 0;}
    return 0;
}

int test002(int l,int m,int r){//迭代规则002号 // 30规则
    if(l==0&&m==0&&r==0){return 0;}
    if(l==0&&m==0&&r==1){return 1;}
    if(l==0&&m==1&&r==0){return 1;}
    if(l==0&&m==1&&r==1){return 1;}
    if(l==1&&m==0&&r==0){return 1;}
    if(l==1&&m==0&&r==1){return 0;}
    if(l==1&&m==1&&r==0){return 0;}
    if(l==1&&m==1&&r==1){return 0;}
    return 0;
}

int test003(int l,int m,int r){//迭代规则003号 // 8规则
    if(l==0&&m==0&&r==0){return 0;}
    if(l==0&&m==0&&r==1){return 0;}
    if(l==0&&m==1&&r==0){return 0;}
    if(l==0&&m==1&&r==1){return 1;}
    if(l==1&&m==0&&r==0){return 0;}
    if(l==1&&m==0&&r==1){return 0;}
    if(l==1&&m==1&&r==0){return 0;}
    if(l==1&&m==1&&r==1){return 0;}
    return 0;
}

void test01(vector<vector<int>>&a,int hi,int le){//根据规则进行迭代
    for(int i=0;i<hi;i++){
        vector<int>b;
        for (int o = 0; o<le; o++) {
            if(o==0){
                b.push_back(test001(a[i][le-1],a[i][o],a[i][o+1]));
            }
            else if(o==le-1){
                b.push_back(test001(a[i][le-2],a[i][o],a[i][0]));
            }
            else{
                b.push_back(test001(a[i][o-1],a[i][o],a[i][o+1]));
            }
        }
        a.push_back(b);
    }
}

//随机组合共256;
//1,了解元胞自动机
//2,观察迭代后输出的内容
//3,加大数据量和迭代次数,并多次试验
//4,改规则

//初等元胞自动机: 即一排元胞(书中用黑格和白格的序列构成),在此用1代表黑格(表示开),0代表白格子(表示关)(例如1000010101001011110100101001010)
//              这一排元胞首尾相连,形成一个环状结构,元胞遵循规则:  3个相邻元胞共8可能状态组合(000,001,010,011,100,101,110,111)
//                                                           当其中的某个可能状态成立时(每次必有一个成立)中间元胞对应的下一步状态根据相应规则变换
//                                                           然后根据新生成好的一组序列再次按照相同规则生成下一组,不断迭代(规则如图)
//                                                           在此我们将所有的迭代过程记录,形成一张二维的时空图;

int main(){
    int le=100;                     // 用于修改(横向)数组长度;
    int hi=2000;                     // 用于修改(纵向)迭代次数;

    vector<vector<int>>a;           //用于记录 迭代过程 的数组
    vector<int>b;                   //记录 初始数据 的数组
    freopen("out", "w", stdout);    //输出到out文件中

    //------------------------------------------------------
    srand((unsigned int)(time(NULL)));
    for (int i = 0; i < le; i++){
        b.push_back(0+rand()%2);
        cout <<*(b.end()-1);
    }
    a.push_back(b);
    cout<<"  初始数据"<<endl;
                                    //随机生成一个初始数据数组
    //------------------------------------------------------

    test01(a,hi,le);                //将初始数据传入函数进行迭代

    //------------------------------------------------------
    for(int i=0;i<hi;i++){
        for(int o=0;o<le;o++){
            //cout<<a[i][o];
            //cout<<(a[i][o]==0?" ":"1");
            //cout<<(a[i][o]==0?"0":" ");
            cout<<(a[i][o]==0?"□":"■");
        }
        cout<<endl;
    }
                                    //将迭代过程输出到out文件
    //------------------------------------------------------

    fclose(stdout);//关闭文件

    return 0;
}

关于初始数据的生成和规则的调用,还有输出数据的形式,在代码中都有注释说明,也有注释较为详细的解释了什么是初等原胞自动机,如果哪部分不清楚的话可以留下言。如果想把代码简化的话可以把实现规则的函数部分重写,其实可以写成一个通用的函数的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值