java实现细胞自动机
来源:互联网 发布:java免费报表开发工具 编辑:程序博客网 时间:2024/05/17 08:07
细胞自动机的java实现
一丶
先说说这个题目吧,还是第一次接触这种类型的题目:生命游戏中,对于任意细胞,规则如下:
每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动。
当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)
可以把最初的细胞结构定义为种子,当所有在种子中的细胞同时被以上规则处理后, 可以得到第一代细胞图。按规则继续处理当前的细胞图,可以得到下一代的细胞图,周而复始。
二丶
1.看到这个题目的第一反应是将整个生命环境看作一个矩阵,其中的每一个细胞以二维坐标的形式存在于环境中,那么这个细胞类就有三个属性在生命游戏中的:x坐标,y坐标,生命状态。但是,这样做了以后发现两个问题:
1)环境边界处的细胞生命状态判断实现很难。
2)细胞之间的生命状态无法实现关联关系。
2.之后是将单个细胞单独做一个(BasicUnit类),还是以3*3九宫格的方式判段我们抽象出来的单元细胞的生命状态,再将其放入生命游戏沙盘(LifeGame类)中演变,当然,还是写一个细胞信息类(Cell类)将从BasicUnit类中判断得来的细胞生命状态和在LifeGame类中的坐标两个信息存储起来。
3.到此,整个生命游戏的实现逻辑就构建好了,接下来就是编码实现的事情了。
4.编码过程中遇到很多坑,这里就不多提了,碰到的坑都是为了以后少进坑做贡献。
5.下面讲这三个类代码贴出来(不能直接跑,用了单元测试,测试每个类的逻辑是否实现,要跑的话需要自己写一个run类)
BasicUnit类:
package org.coach.tdd.template;/** * Created by lzy on 17-6-3. *//** * BasicUnit类判断单元细胞的生命状态。 */public class BasicUnit { private static final int DEATH = 0; private static final int LIVE = 1; private int[][] testUnit = new int[3][3]; //将一个细胞及其周围相邻细胞看作一个基本单元 private int status = DEATH; public void setTestUnit(int[][] testUnit) { this.testUnit = testUnit; } /** * . * 获得单元细胞生命状态 * * @param basicUnit 该细胞周围细胞生命状态 * @return 该细胞生命状态 */ public int getUnitCelltatus(int[][] basicUnit) { int numberofcell = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (1 == basicUnit[i][j]) { if (1 == i && 1 == j) { } else { numberofcell += 1; } } } } if (3 == numberofcell) { return 1; } else if (2 == numberofcell) { return basicUnit[1][1]; } return 0; }}
Cell类:
package org.coach.tdd.template;/** * Created by lzy on 17-6-3. *//** * Cell类存储细胞的坐标,生命状态,周围细胞状态。 */public class Cell { private int location_x = 0; private int location_y = 0; private int cellStatus = 0; private int[][] aroundCells = new int[3][3]; /** * 构造方法的描述 * * @param location_x 细胞的x坐标 * @param location_y 细胞的y坐标 * @param cellStatus 细胞的状态 */ public Cell(int location_x, int location_y, int cellStatus) { this.location_x = location_x; this.location_y = location_y; this.cellStatus = cellStatus; } public int getLocation_x() { return location_x; } public int getLocation_y() { return location_y; } public int getCellStatus() { return cellStatus; } public void setCellStatus(int cellStatus) { this.cellStatus = cellStatus; } /** * 获取更新后的细胞状态 * * @return */ public int getAfterTurnCellStatus() { BasicUnit basicUnit = new BasicUnit(); this.setCellStatus(basicUnit.getUnitCelltatus(aroundCells)); return this.getCellStatus(); }}
LifeGame类:
package org.coach.tdd.template;/** * Created by lzy on 17-6-3. *//** * LifeGame类生命游戏具体操作类 */public class LifeGame { public static final int LEFTUP = 1; public static final int RIGHTUP = 2; public static final int LEFTDOWN = 3; public static final int RIGHTDOWN = 4; private int framesize = 0; //框架大小,表示为正方体框架的边长 private int[][] frame; private int[][] nextframe; public LifeGame(int framesize) { this.framesize = framesize; } public int[][] getNextframe() { return nextframe; } public void setFrame(int[][] frame) { this.frame = frame; } public void init() { frame = new int[framesize][framesize]; nextframe = new int[framesize][framesize]; } public void putCell(Cell cell) { frame[cell.getLocation_x()][cell.getLocation_y()] = cell.getCellStatus(); } public int locationIsCorner(int x, int y) { if (0 == x && 0 == y) { return LEFTUP; } else if (0 == x && framesize - 1 == y) { return RIGHTUP; } else if (framesize - 1 == x && 0 == y) { return LEFTDOWN; } else if (framesize - 1 == x && framesize - 1 == y) { return RIGHTDOWN; } return 0; } public int locationIsLine(int x, int y) { if (0 == x && 0 != y && framesize - 1 != y) { return 11; } else if (framesize - 1 == x && 0 != y && framesize - 1 != y) { return 12; } else if (0 == y && 0 != x && framesize - 1 != x) { return 13; } else if (framesize - 1 == y && 0 != x && framesize - 1 != x) { return 14; } return 0; } /** * 获取指定坐标细胞周围细胞状态 * * @param x cell_x坐标 * @param y cell_y坐标 * @return 指定坐标细胞周围细胞状态 */ public int[][] getAroundStatus(int x, int y) { //corner int[][] aroundUnit = new int[3][3]; int isCorner = locationIsCorner(x, y); int isLine = locationIsLine(x, y); if (isCorner != 0) { switch (isCorner) { case 1: { aroundUnit = new int[][]{{frame[x][y + 1], frame[x + 1][y], frame[x + 1][y + 1]}, {0, frame[x][y], 0}, {0, 0, 0}}; break; } case 2: { aroundUnit = new int[][]{{frame[x][y - 1], frame[x + 1][y - 1], frame[x + 1][y]}, {0, frame[x][y], 0}, {0, 0, 0}}; break; } case 3: { aroundUnit = new int[][]{{frame[x - 1][y], frame[x - 1][y + 1], frame[x][y + 1]}, {0, frame[x][y], 0}, {0, 0, 0}}; break; } case 4: { aroundUnit = new int[][]{{frame[x - 1][y], frame[x - 1][y - 1], frame[x][y - 1]}, {0, frame[x][y], 0}, {0, 0, 0}}; break; } default: break; } } //line else if (isLine != 0) { switch (isCorner) { case 11: { aroundUnit = new int[][]{{frame[x][y - 1], frame[x][y + 1], frame[x + 1][y - 1]}, {frame[x + 1][y], frame[x][y], frame[x + 1][y + 1]}, {0, 0, 0}}; break; } case 12: { aroundUnit = new int[][]{{frame[x - 1][y - 1], frame[x - 1][y], frame[x - 1][y + 1]}, {frame[x][y - 1], frame[x][y], frame[x][y + 1]}, {0, 0, 0}}; break; } case 13: { aroundUnit = new int[][]{{frame[x - 1][y], frame[x - 1][y + 1], frame[x][y + 1]}, {frame[x + 1][y], frame[x][y], frame[x + 1][y + 1]}, {0, 0, 0}}; break; } case 14: { aroundUnit = new int[][]{{frame[x - 1][y - 1], frame[x - 1][y], frame[x][y - 1]}, {frame[x + 1][y - 1], frame[x][y], frame[x + 1][y]}, {0, 0, 0}}; break; } default: break; } } else { aroundUnit = new int[][]{{frame[x - 1][y - 1], frame[x - 1][y], frame[x - 1][y + 1]}, {frame[x][y - 1], frame[x][y], frame[x][y + 1]}, {frame[x + 1][y - 1], frame[x + 1][y], frame[x + 1][y + 1]}}; } return aroundUnit; } /** * 更新环境中所有细胞生命状态 * * @return 环境中是否还在活着的细胞 */ public boolean isfreshFrame() {// boolean flag =false; boolean hasLife = false; BasicUnit basicUnit = new BasicUnit(); for (int i = 0; i < framesize; i++) { for (int j = 0; j < framesize; j++) { int[][] aroundUnit = getAroundStatus(i, j); int status = basicUnit.getUnitCelltatus(aroundUnit); nextframe[i][j] = status; } } for (int i = 0; i < framesize; i++) { for (int j = 0; j < framesize; j++) { System.out.print(frame[i][j]); } System.out.println(""); } System.out.println(""); for (int i = 0; i < framesize; i++) { for (int j = 0; j < framesize; j++) { if (1 == nextframe[i][j]) { hasLife = true; } System.out.print(nextframe[i][j]); } System.out.println(""); }// flag=true; return hasLife; } /** * 运行整个生命游戏 * * @param lifeGame 生命游戏的初始对象 * @return 运行成功 */ public boolean run(LifeGame lifeGame) { while (lifeGame.isfreshFrame()) { lifeGame.setFrame(lifeGame.getNextframe()); System.out.println(""); } return true; }}
最后附上该项目github地址:github地址
小结:博客为个人学习之余沉淀所学知识所用,有纠正之处,劳烦大家指出,共同进步。
- java实现细胞自动机
- 并行实现细胞自动机
- 细胞自动机
- 细胞元自动机
- UVA细胞自动机题解
- CellularAutomation(细胞自动机)
- neerc2006 细胞自动机
- UVa 457 线性细胞自动机
- 例题2.23 细胞自动机 LA3740
- 细胞自动机(生命游戏)源码
- 细胞
- 细胞
- 细胞
- 生命游戏和细胞自动机的学习笔记
- UVa 457 Linear Cellular Automata(线性细胞自动机)
- 矩阵快速幂(细胞自动机,LA 3704)
- 《大白书》156页,LA3704(UVa 1386) 细胞自动机
- java实现的有穷状态自动机(FA)
- 永久删除git库中的所有大文件或者机密文件
- 105. Construct Binary Tree from Preorder and Inorder Traversal
- 浅析重载、隐藏与覆盖
- 通过FileZilla连接VirtualBox 下的Centos7
- 605. Can Place Flowers
- java实现细胞自动机
- 106. Construct Binary Tree from Inorder and Postorder Traversal
- 利用Python进行数据分析.pdf
- 二叉树递归与非递归遍历
- java 回调机制
- java新特性——读写锁ReadWriteLock
- 第一百三十四天 : Puppet 的使用与进阶
- JavaSwing_1.6: CardLayout(卡片布局)
- MYSQL字符集与校对规则