`

细胞自动机初探之生命游戏

 
阅读更多

细胞自动机初探——生命游戏

细胞自动机(Cellular Automaton),简单说就是能在生成许多自行演变的“小细胞”的程序,是一种很强大的人工智能实现,强大到几乎可以用来仿真研究社会和自然科学各个领域的问题,比如:构建模拟人群研究经济危机爆发过程,构建模拟生物群落研究生态系统演变,构建微观粒子群研究物理化学问题,构建“军队”模拟军事战场等等。由它引申出了数量地理学等学科,它更是分布式计算中的重要工具。。。。嘿嘿,是不是听起来很高端?想深入了解么?鄙人不才,今天带大家初步了解一下元胞自动机背后的故事。

1950年,计算机之父冯·诺伊曼写了一段程序用来模拟细胞复制过程,这就是最早的细胞自动机,只不过连冯诺伊曼本人也没太重视,所以这项研究很快就沉了。。。直到20年后的1970年,剑桥大学约翰·何顿·康威设计了一个名为生命游戏Life)的电脑游戏,细胞自动机才进入了科学家们的视野。后来,又有了模拟蚂蚁行为的兰顿蚂蚁(Langton ant)、模拟二极管电子逻辑的线世界(Wire world),再有史蒂芬·沃尔夫勒姆对初等细胞机256种规则所产生的模型进行了深入研究,并用来描述其演化行为,将细胞自动机分为平稳型、周期型、混沌型和复杂型,以至于今天应用到各个领域问题的研究……当然这是后话了,今天我们就以《生命游戏》为起点,揭开细胞自动机的神秘面纱。

生命游戏是一段很经典的仿真程序,我在网上可以找到很多实现代码,在Matlab上也有自带的demo。今天我就带大家从Matlabdemo入手,用java重写一个生命游戏。

首先我们运行Matlab中自带的demo文件我也传到了附件中 (MATLAB\R2010b\toolbox\matlab\demos\life.m),运行结果如下:



 

 

屏幕中每个蓝点即所谓的“细胞”,当程序跑起来,你会看到很多神奇的现象,如某些区域出现像核爆一样的“细胞爆发”,然后归于沉寂,只剩零星的固定细胞,或者有像小飞船一样的细胞“小飞船”在平移;但是经过几十秒后,整个画面几乎都沉寂了:只有个别区域还有稳定存在的小细胞团。



 

 

事实上,这个程序中的“细胞”只遵循以下几个简单的规则:

         1、当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)

         2、当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟人口稀少)

         3、当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。

         4、当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟过度拥挤)

   

可以把最初的细胞结构定义为种子,当所有种子中的细胞同时被以上规则处理后, 可以得到第一代细胞图。按规则继续处理当前的细胞图,可以得到下一代的细胞图,周而复始,我们就看到了屏幕中的神奇的效果。

怎么样,是不是迫不及待了?下面我们就可以动手用java再现一个这样的生命游戏。

 

这个程序用到四个类:



 

MainUI:主窗体类,用来画出图形

Earth:地球(想不出更好的比喻了),承载细胞的容器,里面的land数组模拟地面上的细胞分布情况

LifeThread:用来不断更新数组以及执行重绘操作的线程类

MyListener:按钮监听器类,实现界面上startstop按钮的功能

程序的逻辑其实很简单:用二维数组模拟地面空间的细胞图,1代表存活,0代表死亡,不断地遍历数组,根据上述规则更新数组,然后重绘,就实现了生命游戏。当然这里涉及到了线程的简单应用,很想我另一篇文章中的彩蛋程序,具体细节我就不再赘述了。

运行效果如下:



 

 

下面直接贴源代码:

 

 

MainUI类
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainUI extends JFrame{
	//地球
	private Earth earth;
	//窗体组件
	private JButton jb_start,jb_stop;
	private JPanel jp_center,jp_west;
	//初始化程序的方法
	public void init(){
		this.initEarth();
		this.showUI();
	}
	//显示界面的方法
	public void showUI(){
		this.setTitle("生命游戏");
		this.setSize(500,500);
		this.setDefaultCloseOperation(3);
		this.setLocationRelativeTo(null);
		this.jb_start = new JButton("start");
		this.jb_stop = new JButton("stop");
		
		this.jp_west = new JPanel();
		this.jp_west.setPreferredSize(new Dimension(80,100));
		this.jp_west.add(jb_start);
		this.jp_west.add(jb_stop);
		//this.jp_west.setBackground(Color.green);
		this.add(jp_west,BorderLayout.WEST);
		
		this.jp_center = new JPanel();
		//this.jp_center.setBackground(Color.red);
		this.add(jp_center,BorderLayout.CENTER);
		
		MyListener ml = new MyListener(this);
		this.jb_start.addActionListener(ml);
		this.jb_stop.addActionListener(ml);
		
		this.setVisible(true);
		Graphics g = this.jp_center.getGraphics();
		this.earth.setG(g);
		this.repaint();
	}
	//初始化大地的方法
	public void initEarth(){
		this.earth = new Earth();
		this.earth.initLand();
		this.repaint();
	}
	//重绘方法
	public void repaint(Graphics g){
		super.repaint();
		//System.out.println("在重绘");
		earth.drawCells();
	}
	public static void main(String [] args){
		new MainUI().init();
	}
	public Earth getEarth() {
		return this.earth;
	}
}

 

Earth类
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;

public class Earth {
	//表示地面的数组
	private int[][] land;
	//图像处理类
	private Graphics g;
	public void setG(Graphics g){
		this.g = g;
	}
	public Graphics getG() {
		return g;
	}
	//初始化大地的方法(增加边缘方便后面判断)
	public void initLand(){
		this.land = new int [102][102];
		for(int ii = 0;ii<102;ii++){
			for (int jj = 0;jj < 102;jj++){
				land[ii][jj] = 0;
			}
		}//初值为0
		//生成种子细胞
		System.out.println("生成种子之前:");
		printLand();
		this.setSeeds();
	}
	//生成种子细胞的方法
	public void setSeeds(){
		Random rand = new Random();
		int count = rand.nextInt(2000)+1000;//生成种子数
		//随机创建细胞种子
		int x=  0,y = 0;
		for (int ii = 0;ii < count;ii++){
			x = rand.nextInt(100)+1;
			y = rand.nextInt(100)+1;
			land[x][y] = 1;
		}
		System.out.println("生成种子之后:");
		printLand();
	}
	//更新地面数组的方法
	public void updataLand(){
		//创建临时数组,避免之前的改动影响后面
		int [][] tland = new int [102][102];
		for(int ii = 0;ii < 102;ii++){
			for(int jj = 0;jj< 102;jj++){
				tland[ii][jj] = land[ii][jj];
			}
		}
		//根据规则更新临时数组
		for(int ii = 1;ii<= 100;ii++){
			for(int jj = 1;jj <= 100;jj++){
				//计算周围存活数
				int neighbor = this.countNeighbors(jj, ii);
				//执行规则
				//规则1:	当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。
				if(land[ii][jj] == 0 && neighbor == 3){
					tland[ii][jj] = 1;
				}
				//规则2.当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟人口稀少)
				if(land[ii][jj] == 1 && neighbor < 2){
					tland[ii][jj] = 0;
				}
				//规则3.当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
				if(land[ii][jj] == 1 && (neighbor == 2 || neighbor == 3)){
					tland[ii][jj] = 1;
				}
				//规则4.当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟过度拥挤)
				if(land[ii][jj] == 1 && neighbor > 3){
					tland[ii][jj] = 0;
				}
			}
		}
		//最后替换以更新数组
		this.land = tland;
	}
	//计数细胞周围细胞数的方法
	public int countNeighbors(int x,int y){
		int count = 0;
		if(land[x-1][y] == 1){
			count++;
		}
		if(land[x+1][y] == 1){
			count++;
		}
		if(land[x][y-1] == 1){
			count++;		
		}
		if(land[x][y+1] == 1){
			count++;
		}
		if(land[x-1][y-1] == 1){
			count++;
		}
		if(land[x-1][y+1] == 1){
			count++;
		}
		if(land[x+1][y-1] == 1){
			count++;
		}
		if(land[x+1][y+1] == 1){
			count++;
		}
		return count;
	}
	//画出细胞的方法
	public void drawCells(){
		for(int ii  = 1;ii <= 100;ii++){
			for(int jj = 1;jj<= 100;jj++){
				if(land[ii][jj] == 1){
					g.setColor(Color.BLUE);
					g.drawRect(4*jj, 4*ii, 4, 4);
				}
			}
		}
	}
	//打印land数组的方法
	public void printLand(){
		for(int ii = 0;ii< 102;ii++){
			for(int jj = 0;jj < 102;jj++){
				System.out.print(land[jj][ii]+" ");
			}
			System.out.println();
		}
	}
}

 

LifeThread类
public class LifeThread extends Thread{
	private boolean running = true;
	private Earth earth;
	private MainUI mainUI;
	//传入窗体对象
	public LifeThread(MainUI mainUI){
		this.mainUI = mainUI;
		this.earth = mainUI.getEarth();
	}
	public void run(){
		while(running){
			earth.updataLand();
			mainUI.repaint(earth.getG());
			//earth.printLand();
			try {
				sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		mainUI.init();
	}
	public void setRunning(boolean running) {
		this.running = running;
	}
}

 

MyListener类
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MyListener implements ActionListener{
	private LifeThread life;
	private MainUI mainUI;
	boolean pressstart = false;
	//传入窗体对象
	public MyListener(MainUI mainUI){
		this.mainUI = mainUI;
	}
	//监听方法
	public void actionPerformed(ActionEvent e) {
		String com = e.getActionCommand();
		if(com.equals("start")){
			System.out.println("点击了start!");
			if(!pressstart){
				pressstart = true;
				life = new LifeThread(this.mainUI);
				life.start();
			}
		}
		if(com.equals("stop")){
			System.out.println("点击了stop");
			if(this.life != null){
				this.life.setRunning(false);
				this.pressstart = false;
			}
		}
	}
}

 

 

 

 

 

  • 大小: 11.4 KB
  • 大小: 3.5 KB
  • 大小: 10.6 KB
  • 大小: 3.5 KB
  • 大小: 6.8 KB
1
1
分享到:
评论

相关推荐

    生命游戏 细胞自动机 元胞自动机 Game Of Life

    《生命游戏:细胞自动机与元胞自动机的探索》 生命游戏,全称为“Game Of Life”,是由英国数学家约翰·康威(John Horton Conway)在1970年提出的一种简单的模拟生物演化的计算模型,它是细胞自动机的一个经典实例...

    生命游戏Golly(元胞自动机)

    《生命游戏Golly:探索细胞自动机与人工生命的奇妙世界》 生命游戏,全称“康威的生命游戏”,是由英国数学家约翰·何顿·康威在1970年提出的一种简单的计算机模拟系统,它是细胞自动机的一个经典实例。细胞自动机...

    细胞自动机的java实现

    最著名的细胞自动机之一是康威的生命游戏,它通过“生”、“死”规则模拟细胞状态的变化,展现了复杂的行为。在本项目中,细胞自动机可能也采用了类似规则,但具体规则需要查看源代码来了解。 2. **Java实现**:...

    生命游戏 细胞自动机 源代码

    在生命游戏中,我们通常使用二维网格,细胞可以处于两种状态:活(1)或死(0)。 游戏的规则非常简洁: 1. 死亡:如果一个活细胞周围(8个相邻格子)的活细胞数少于2个,则该细胞在下一次迭代中死亡(因孤独而死亡...

    BigWork_俄罗斯方块_细胞自动机_

    而在这个项目中,我们探索了一种新颖的实现方式——利用细胞自动机(Cellular Automaton)理论来构建游戏逻辑。细胞自动机是一种数学模型,由一维、二维或更高维度的离散单元组成,每个单元都有有限的状态,并根据...

    细胞自动机理论及其在密码中的应用

    细胞自动机理论是一种复杂系统的研究方法,由美国数学家史蒂文·沃尔夫勒姆在20世纪80年代提出。这一理论的核心是通过简单的规则和局部交互来模拟复杂的动态行为,具有高度的并行性和自组织性。细胞自动机理论在多个...

    win32 api 开发的 细胞自动机分裂过程

    例如,最著名的二维细胞自动机是康威的生命游戏。你需要实现这些规则,根据细胞的邻居状态来决定其生死。 7. **单元格分裂**:在细胞自动机中,单元格分裂可能表示为状态的突变或新的单元格的生成。你需要设计一种...

    Lifes原细胞自动机

    **Lifes原细胞自动机**,也称为生命游戏,是由英国数学家约翰·康威(John Horton Conway)在1970年设计的一种简单的计算模型,它属于细胞自动机的一个经典例子。在这个游戏里,虚拟的二维空间由一系列的单元格构成...

    细胞自动机 (源码)

    细胞自动机(Cellular Automata,简称CA)是一种在计算理论和复杂系统研究中非常重要的概念,它由一串状态可变的简单单元组成,这些单元遵循统一的局部规则进行更新。在这个项目中,我们看到的是一个利用细胞自动机...

    生命游戏-JAVA语言代码-细胞自动机-毕业论文

    并且在生命游戏的基础上进行了一定的扩展,增加了系统复杂性,给定了简单的初始状态以此进一步研究细胞自动机在复杂系统中所表现的能力,为细胞自动机及生命游戏的后续研究奠定基础。结论:计算机实现的细胞自动机在...

    java细胞自动机(大量注释) 浙江大学翁恺老师

    细胞自动机(Cellular Automata,CA)是一种计算模型,由一串状态可变的单元格构成,每个单元格遵循相同的一组局部规则与相邻单元格互动,从而更新自己的状态。在Java编程语言中实现细胞自动机,可以让我们深入理解...

    基于细胞自动机的生命活力模拟的实现论文.doc

    生命游戏是细胞自动机的一个经典实例,通过简单的规则就能展示出生命系统般的行为,如繁殖、竞争和死亡。 第三章中,作者将基于已有的理论知识,亲自设计并实现细胞自动机,进行实验操作。通过观察和分析细胞自动机...

    混沌细胞自动机的数字水印技术实现

    【混沌细胞自动机的数字水印技术实现】 在信息技术领域,数字水印是一种重要的版权保护技术,它通过在数字媒体(如图像、音频或视频)中嵌入不可见的标识,来证明作品的所有权和防止非法复制。混沌细胞自动机...

    细胞自动机

    细胞自动机

    元胞自动机,生命游戏 java

    "生命游戏"(Conway's Game of Life)是元胞自动机中最著名的例子,由英国数学家约翰·康威在1970年提出。 生命游戏是由一个二维网格构成,每个格子可以是"活"或"死"两种状态。游戏规则如下: 1. **繁殖规则**:...

    shengmingyouxi.rar_细胞自动_细胞自动机

    "shengmingyouxi.rar"是一个包含细胞自动机实现的压缩包,重点在于模拟“生命游戏”。 生命游戏是细胞自动机的一个经典例子,由约翰·康威在1970年设计。游戏在一个二维网格上进行,每个格子可以处于两种状态:存活...

    JAVA模拟细胞自动机

    ### JAVA模拟细胞自动机 #### 一、细胞自动机概览 细胞自动机(Cellular Automata, CA)是一种基于离散时间和空间的数学模型,最初由计算机科学领域的先驱约翰·冯·诺伊曼(John von Neumann)在20世纪40年代末...

Global site tag (gtag.js) - Google Analytics