CellularAutomation(细胞自己主动机)

细胞自己主动机(英语:Cellular automaton)。又称格状自己主动机、元胞自己主动机,是一种离散模型,在可算性理论、数学及理论生物学都有相关研究。它是由无限个有规律、坚硬的方格组成。每格均处于一种有限状态。整个格网能够是不论什么有限维的。同一时候也是离散的。每格于t时的态由 t-1时的一集有限格(这集叫那格的邻域)的态决定。 每一格的“邻居”都是已被固定的。(一格能够是自己的邻居。)每次演进时。每格均遵从同一规矩一齐演进。

就形式而言,细胞自己主动机有三个特征:

平行计算(parallel computation):每一个细胞个体都同一时候同步的改变
局部的(local):细胞的状态变化仅仅受周遭细胞的影响。

一致性的(homogeneous):全部细胞均受相同的规则所支配

生命游戏

生命游戏中,对于随意细胞,规则例如以下:
每一个细胞有两种状态-存活或死亡,每一个细胞与以自身为中心的周围八格细胞产生互动。(如图,黑色为存活,白色为死亡)

当前细胞为存活状态时。当周围低于2个(不包括2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
当前细胞为存活状态时。当周围有2个或3个存活细胞时, 该细胞保持原样。

当前细胞为存活状态时。当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
当前细胞为死亡状态时。当周围有3个存活细胞时。该细胞变成存活状态。 (模拟生殖)
能够把最初的细胞结构定义为种子。当全部在种子中的细胞同一时候被以上规则处理后, 能够得到第一代细胞图。按规则继续处理当前的细胞图,能够得到下一代的细胞图。周而复始。

在这个游戏中。还能够设定一些更加复杂的规则。比如当前方格的状况不仅由父一代决定。并且还考虑祖父一代的情况。玩家还能够作为这个世界的“上帝”,随意设定某个方格细胞的死活。以观察对世界的影响。

在游戏的进行中,杂乱无序的细胞会逐渐演化出各种精致、有形的结构;这些结构往往有非常好的对称性。并且每一代都在变化形状。

一些形状已经锁定。不会逐代变化。有时。一些已经成形的结构会由于一些无序细胞的“入侵”而被破坏。可是形状和秩序经常能从杂乱中产生出来。

有个能够直接玩这个游戏的链接 - Game of Life

以下用Unity自己写一下。

using UnityEngine;
using System.Collections; public enum State{
Died,
Living
}; public class Cell
{
public State currentState;
} public class Earth : MonoBehaviour {
public int width;
public int height; public string seed;
public bool useRandomSeed; public float updateInterval = 1.0f;
float refreshTime = -1f; [Range(0, 100)]
public int randomFillPercent; Cell[,] map;
Cell[,] mapTmp; // Use this for initialization
void Start () {
map = new Cell[width,height];
mapTmp = new Cell[width, height]; for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
{
map[i,j] = new Cell();
map[i, j].currentState = State.Died; mapTmp[i, j] = new Cell();
mapTmp[i, j].currentState = State.Died;
}
initEarth();
} // Update is called once per frame
void Update () {
if(Time.time - refreshTime > updateInterval)
{
UpdateEarth();
refreshTime = Time.time;
}
} void UpdateEarth()
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
mapTmp[x, y].currentState = map[x, y].currentState;
int neighbourLiveCells = GetSurroundingLiveCells(x, y);
if (map[x, y].currentState == State.Died && neighbourLiveCells == 3)
{
mapTmp[x, y].currentState = State.Living;
}
if (map[x, y].currentState == State.Living)
{
if(neighbourLiveCells < 2)
{
mapTmp[x, y].currentState = State.Died;
}else if( neighbourLiveCells > 3)
{
mapTmp[x, y].currentState = State.Died;
}
else
{
mapTmp[x, y].currentState = State.Living;
}
}
}
} for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
{
map[x, y].currentState = mapTmp[x, y].currentState;
}
} int GetSurroundingLiveCells(int gridX, int gridY)
{
int count = 0;
for (int neighbourX = gridX - 1; neighbourX <= gridX + 1; neighbourX++)
{
for (int neighbourY = gridY - 1; neighbourY <= gridY + 1; neighbourY++)
{
if (neighbourX >= 0 && neighbourX < width && neighbourY >= 0 && neighbourY < height)
{
if (neighbourX != gridX || neighbourY != gridY)
{
count += map[neighbourX, neighbourY].currentState == State.Living? 1 : 0;
}
}
}
} return count;
} void initEarth()
{
if (useRandomSeed)
{
seed = Time.time.ToString();
} System.Random pseudoRandom = new System.Random(seed.GetHashCode()); for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
{
map[x, y].currentState = State.Living;
}
else
{
map[x, y].currentState = (pseudoRandom.Next(0, 100) < randomFillPercent) ? State.Living : State.Died;
}
}
} } void OnDrawGizmos()
{
if (map != null)
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (map[x, y] != null)
{
Gizmos.color = (map[x, y].currentState == State.Living) ? Color.black : Color.white;
Vector3 pos = new Vector3(-width / 2 + x + .5f, 0, -height / 2 + y + .5f);
Gizmos.DrawCube(pos, Vector3.one);
}
}
}
}
}
}

代码事实上就是依照前面算法的描写叙述实现出来。

初始的细胞分布用了Unity自带的随机来生成,然后在OnDrawGizmos函数中绘制出来。

执行起来是这种:

能够将初始状态设置为经典的glider,改动 initEarth() 函数就能够了。

//Glider
map[20, 20].currentState = State.Living;
map[20, 21].currentState = State.Living;
map[20, 22].currentState = State.Living;
map[21, 22].currentState = State.Living;
map[22, 21].currentState = State.Living;

程序生成地形

程序生成有非常多中方法,利用细胞自己主动机主要用生成地牢等相似的地形,经常使用于Roguelike类的游戏。

基本的算法就是还是利用细胞生存的规则,比方如今规定仅仅要细胞周围有四个以上的细胞,该细胞就存活,否则死去。

for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int neighbourWallTiles = GetSurroundingWallCount(x, y); if (neighbourWallTiles > 4)
map[x, y] = 1;
else if (neighbourWallTiles < 4)
map[x, y] = 0; }
}

不断迭代,就能够得到一张地图。当然首先还是要在画布上随机分布一些细胞。迭代5次,终于生成地图例如以下

    

代码清单

using UnityEngine;
using System.Collections; public class MapGenerator : MonoBehaviour {
public int width;
public int height; public string seed;
public bool useRandomSeed; [Range(0, 100)]
public int randomFillPercent; int[,] map;
// Use this for initialization
void Start () {
GenerateMap();
} // Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown(0))
{
GenerateMap();
}
} void GenerateMap()
{
map = new int[width, height];
RandomFillMap(); for (int i = 0; i < 5; i++)
{
SmoothMap();
}
} void RandomFillMap()
{
if (useRandomSeed)
{
seed = Time.time.ToString();
} System.Random pseudoRandom = new System.Random(seed.GetHashCode()); for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
{
map[x, y] = 1;
}
else
{
map[x, y] = (pseudoRandom.Next(0, 100) < randomFillPercent) ? 1 : 0;
}
}
}
} void SmoothMap()
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int neighbourWallTiles = GetSurroundingWallCount(x, y); if (neighbourWallTiles > 4)
map[x, y] = 1;
else if (neighbourWallTiles < 4)
map[x, y] = 0; }
}
} int GetSurroundingWallCount(int gridX, int gridY)
{
int wallCount = 0;
for (int neighbourX = gridX - 1; neighbourX <= gridX + 1; neighbourX++)
{
for (int neighbourY = gridY - 1; neighbourY <= gridY + 1; neighbourY++)
{
if (neighbourX >= 0 && neighbourX < width && neighbourY >= 0 && neighbourY < height)
{
if (neighbourX != gridX || neighbourY != gridY)
{
wallCount += map[neighbourX, neighbourY];
}
}
else
{
wallCount++;
}
}
}
return wallCount;
} void OnDrawGizmos()
{
if (map != null)
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Gizmos.color = (map[x, y] == 1) ? Color.black : Color.white;
Vector3 pos = new Vector3(-width / 2 + x + .5f, 0, -height / 2 + y + .5f);
Gizmos.DrawCube(pos, Vector3.one);
}
}
}
}
}

參考

细胞自己主动机wiki - https://zh.wikipedia.org/wiki/%E7%B4%B0%E8%83%9E%E8%87%AA%E5%8B%95%E6%A9%9F

Game of Life - http://www.bitstorm.org/gameoflife/

Procedural Cave Generation Project Icon - https://unity3d.com/learn/tutorials/projects/procedural-cave-generation-tutorial

CellularAutomation(细胞自己主动机)的更多相关文章

  1. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  2. hdu 2222 Keywords Search ac自己主动机

    点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

  3. 【UVA】1449-Dominating Patterns(AC自己主动机)

    AC自己主动机的模板题.须要注意的是,对于每一个字符串,须要利用map将它映射到一个结点上,这样才干按顺序输出结果. 14360841 1449 option=com_onlinejudge& ...

  4. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  5. HDU 2896 病毒侵袭 AC自己主动机题解

    本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...

  6. NYOJ 1085 数单词 (AC自己主动机模板题)

    数单词 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 为了可以顺利通过英语四六级考试,如今大家每天早上都会早起读英语. LYH本来以为自己在6月份的考试中能够通过六 ...

  7. hdu 4057 AC自己主动机+状态压缩dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...

  8. Keywords Search (ac 自己主动机)

    Keywords Search Problem Description In the modern time, Search engine came into the life of everybod ...

  9. HDU - 2825 Wireless Password(AC自己主动机+DP)

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

随机推荐

  1. nw335 debian sid x86-64 -- 5 使用xp的驱动

    nw335 debian sid x86-64 -- 5 使用xp的驱动

  2. 03004_Web开发

    1.Web开发中常见的概念 (1)B/S系统和C/S系统 ①Brower/Server:浏览器 服务器 系统------网站: ②Client/Server:客户端 服务器 系统------QQ.大型 ...

  3. js 加密混淆

    没有找到合适的加密算法就用的以下方式 拿webpack打包一遍,再拿uglify压缩一遍,再拿eval加密一遍 1. webpack ./init.js ./webpack/bundle.js -p ...

  4. 百度蜘蛛IP段分析

    大家进行网站日志分析的时候,常见到很多不同IP段的百度蜘蛛,为了方便大家更好的进行日志分析,下面列举了百度不同IP段常见蜘蛛的一些详情情况,及所谓的降权蜘蛛,沙盒蜘蛛,高权重蜘蛛等等 下面的百度蜘蛛I ...

  5. 面试准备——rpc面试题

    https://www.jianshu.com/p/28e48e5f9c73 1 什么是 RPC ? RPC (Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方 ...

  6. tensorflow 如何限制显存大小

    Python在用GPU跑模型的时候最好开多进程,因为很明显这种任务就是计算密集型的. 用进程池好管理,但是tensorflow默认情况会最大占用显存,尽管该任务并不需要这么多,因此我们可以设置显存的按 ...

  7. 信安实验-RC4加密算法

    RC4加密算法 算法具体就不介绍了,应信安老师要求整理及掌握. #include<bits/stdc++.h> using namespace std; const int N=256; ...

  8. 刷题总结——教主的魔法(bzoj3343)

    题目: Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. ...

  9. ElasticSearch中Filter和Query的异同

    如下例子,查找性别是女,所在的州是PA,过滤条件是年龄是39岁,balance大于等于10000的文档: { "query": { "bool": { &quo ...

  10. MysqL5.7在使用mysqldump命令备份数据库报错:mysqldump: [Warning] Using a password on the command line interface can be insecure.

    在阿里云服务器增加一个shell脚本定时备份数据库脚本执行任务时,测试性的执行了备份命令,如下 [root@iZ2ze503xw2q1fftv5rhboZ mysql_bak]# /usr/local ...