简单的规则,神奇的演化----演化类算法思想一瞥

    继续整理存货^_^,这个应该是很久前从某一个大牛的书中摘录出来的,规则、程序都很简单,记得当时调试正常,启动运行后,看着跃动的混沌的屏幕,逐渐的演化稳定,似乎顿悟了很多。

    如果你也对各种AI算法有兴趣,读各种资料的时候总感觉说的很空洞抽象,不妨找一个类似这样的小程序,用心挖掘一下它背后的深刻含义,比如初始状态、最终状态、初始状态对最终状态的影响、收敛性等等等等。

   不多说了,码农自然是多帖代码为宜,演化规则如下:

 

* 经典并且简单的人工生命游戏定义:

* 1.出生 : 如果一个死亡的细胞有三个或者的邻居,它就变成活的;

* 2.生存 : 如果一个活着的细胞有两个或者三个活的邻居,他就仍然活着;

* 3.死亡 : 其它情况下,该细胞(仍然)死亡.

 

    代码如下(摘录自一本书,忘记是哪本了,如有不妥请请及时联系我删除):

 

/**
 * description:
 * @date 2008-12-22 上午09:11:49
 * 经典并且简单的人工生命游戏定义:
 * 1.出生 : 如果一个死亡的细胞有三个或者的邻居,它就变成活的;
 * 2.生存 : 如果一个活着的细胞有两个或者三个活的邻居,他就仍然活着;
 * 3.死亡 : 其它情况下,该细胞(仍然)死亡.
 */
public class Life extends JApplet{

	public static void main(String[] args) {
		// 创建主窗口
		JFrame frame = new JFrame();
		// 设置标题栏
		frame.setTitle("Game of life");
		// 设置关闭
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 创建Life对象
		JApplet applet = new Life();
		// 初始化
		applet.init();
		// 添加life到frame内容窗格
		frame.getContentPane().add(applet);
		frame.pack();
		frame.setVisible(true);
	}
	
	// 重写初始化方法
	public void init(){
		JPanel panel = new LifePanel();
		getContentPane().add(panel);
		
	}
}

// 定义LifePanel类
class LifePanel extends JPanel implements ActionListener{

	int n = 30;	// 30 * 30
	boolean[][] cells1;
	boolean[][] cells2;
	
	public LifePanel(){
		setPreferredSize(new Dimension(400,400));
		setBackground(Color.white);
		cells1 = new boolean[n][n];
		cells2 = new boolean[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				cells1[i][j] = Math.random() < 0.2;
				cells2[i][j] = false;
			}
		}
		
		// 创建并启动Timer对象
		Timer timer = new Timer(1000, this);
		timer.start();
	}
	
	// 重写组件绘制方法
	@Override
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D)g;
		
		g2.setColor(Color.lightGray); //网格线的颜色
		
		int p = 0;
		int c = 16; // 两条线之间的间隔
		int len = c * n;
		// 绘制网格
		for (int i = 0; i <= n; i++) {
			g2.drawLine(0, p, len, p);
			g2.drawLine(p, 0, p, len);
			p += c;
		}
		g2.setColor(Color.black);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				// 如果当前细胞存活
				if(cells1[i][j]){
					int x = i * c;
					int y = j * c;
					// 画实心黑点
					g2.fillOval(x, y, c, c);
				}
			}
		}	
	}
	
	// 事件响应函数
	@Override
	public void actionPerformed(ActionEvent e) {
		
		// 当前细胞存活情况
		boolean[][] cells = cells1;
		
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				// 当前细胞存活情况记录到s2
				cells2[i][j] = cells[i][j];
				// 获取当前细胞近邻存活的个数
				int nb = neighbors(cells, i, j);
				// 近邻存活3个,自己存活
				if(3 == nb){
					cells2[i][j] = true;
				}
				// 近邻不是2个或3个,细胞死亡
				if(nb < 2 || nb > 3){
					cells2[i][j] = false;
				}
				// 近邻存活2个,维持自身情况
			}
		}
		
		// 更新当前状态
		cells1 = cells2;
		cells2 = cells;
		
		repaint();
	}
	
	// 获得当前细胞近邻的存活个数
	private int neighbors(boolean[][] cells, int x, int y){
		int x1 = (x > 0) ? x - 1 : x;
		int x2 = (x < n - 1) ? x + 1 : x;
		int y1 = (y > 0) ? y - 1 : y;
		int y2 = (y < n - 1) ? y + 1 : y;
		int count = 0;
		
		for (int i = x1; i <= x2; i++) {
			for (int j = y1; j <= y2; j++) {
				count +=((cells[i][j]) ? 1 : 0);
			}
		}
		
		// 自己存活的话,存活个数减去自己
		if(cells[x][y]){
			count--;
		}
		return count;
	}
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值