第八次作业元胞自动机NO.1

元胞自动机(Cellular Automata,简称CA,也有人译为细胞自动机、点格自动机或单元自动机等)。最初由数学家 Stanislaw M. Ulam(1909-1984)与 John von Neumann(1903-1957)于 1950 年代所提出,是时间和空间都离散的动力系统。

元胞自动机可用来研究很多一般现象,被广泛地应用到社会、经济、军事和科学研究的各个领域。例如,铁磁理论中的伊辛(Ising)模型、森林火灾传播、非线性的化学反应扩散、湍流、生物的色斑沉积模式、材料断裂、晶体生长、生物繁衍等,以及图像处理、计算机绘图、大规模并行计算、密码学以及艺术研究等。

细胞自动机是由一些特定规则的格子所组成,每个格子看做是一个细胞;每一个细胞可以具有一些状态,但是在某一时刻只能处一种状态之中。随着时间的变化(我们称作“迭代”过程),格子上的每一个细胞根据周围细胞的情形,按照相同的法则而改变状态,换句话说,一个细胞的状态是由上一个时刻所围绕的细胞的状态所决定。

著名的生命游戏(Game of Life)是二维的元胞自动机,由剑桥大学的数学家 John Horton Conway 于 1970 年所提出的。下面的例子是一个典型的生命游戏的动画(Gosper的"机枪"在产生"滑翔机",ref1,ref2)。

gosper

一维细胞自动机是由Stephen Wolfram 提出的。 细胞只能生存在一列紧连的方格里,每个细胞有左右两边的邻居,细胞在指定规则的迭代演算之后只能处于不同状态的其中之一,其中一组最简单的状态就是:「生」或「死」,存活的细胞我们在方格内涂上特定单一的颜色,而死亡的细胞我们则不涂色。为了有良好的二维视觉效果,我们把新一次迭代的结果画在前一代的下方,等到进行了足够的迭代次数之后,我们便可以“同时”看见细胞们每一次迭代的连续过程。

ca

下一次迭代时,单元的生死状态由上一次的状态决定,不同的规则会得到不同的模式(ref)。

本题选用一维元胞自动机的90规则。该规则说,如果在时刻(t-1)时,单元i的两个邻居(i-1)和(i+1)中有且仅有一个是“生”状态,则单元i在t时刻也是“生”状态;否则单元为“死”状态。

rule90

你可以用两个boolean数组来模拟一维元胞自动机的状态变化。如果对应的元胞为“生”,则cell[i]取true,否则取false。上一时刻的记录为old[]。规则90要求数组的长度为迭代步数N的两倍,下一时刻

cells[i] = old[i-1] ^ old[i+1];

初始状态是数组中央(即索引为N的那个元素)对应那个元胞是“生”状态,其它皆为“死”状态。

看看输出的结果是不是很熟悉?

输入:

一维元胞自动机迭代的次数N

输出:

对应的迭代图形

样例输入:

9

样例输出:

□□□□□□□□□*□□□□□□□□↵
□□□□□□□□**□□□□□□□↵
□□□□□□□*□□□*□□□□□□↵
□□□□□□****□□□□□↵
□□□□□*□□□□□□□*□□□□↵
□□□□**□□□□□**□□□↵
□□□*□□□*□□□*□□□*□□↵
□□********□↵
import java.util.Scanner;
/*
 * 元胞自动机
 * */
public class Main {
	//计算迭代
	public static void cellularAutomata(boolean[][] cells,int n){
		cells[0][n]=true;
		for(int i=1;i<n-1;i++){
			for(int j=1;j<n*2-1;j++){
				cells[i][j]=cells[i-1][j-1]^cells[i-1][j+1];
			}
		}
		print(cells,n);
	}
	//打印
	public static void print(boolean[][] cells,int n){
		for(int i=0;i<n-1;i++){
			for(int j=0;j<n*2;j++){
				if(cells[i][j]){
					System.out.print("*");
				}else{
					System.out.print(" ");
				}
			}
			System.out.println();
		}
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        boolean[][] cells = new boolean[n-1][n*2];
        for(int i=0;i<n-1;i++){
        	for(int j = 0;j<n*2;j++){
        		cells[i][j] = false;
        	}
        }
        cellularAutomata(cells,n);
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值