简单的规则,神奇的演化----演化类算法思想一瞥
? ? 继续整理存货^_^,这个应该是很久前从某一个大牛的书中摘录出来的,规则、程序都很简单,记得当时调试正常,启动运行后,看着跃动的混沌的屏幕,逐渐的演化稳定,似乎顿悟了很多。
? ? 如果你也对各种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 * 30boolean[][] 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();}// 重写组件绘制方法@Overridepublic 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);}}}}// 事件响应函数@Overridepublic void actionPerformed(ActionEvent e) {// 当前细胞存活情况boolean[][] cells = cells1;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {// 当前细胞存活情况记录到s2cells2[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;}}?