首页 / 知识
关于算法:优化Conway的“生命游戏”
2023-04-14 00:00:00

Optimizing Conway's 'Game of Life'为了进行试验,我(很久以前)实现了Conway的《人生游戏》(而且我知道这个相关问题!)。 我的实现通过保留2个布尔数组来表示"最后状态"和"状态正在更新"(每次迭代都交换2个数组)而工作。 尽管这相当快,但我经常想知道如何优化它。 例如,一种想法是在迭代N处预先计算可以在迭代(N + 1)时修改的区域(这样,如果一个单元格不属于该区域,则甚至不考虑在该区域进行修改) 迭代(N + 1))。 我知道这很模糊,而且我从来没有花时间去研究细节…… 您对如何优化(速度)生命游戏迭代有任何想法(或经验!)? 我要引用另一个问题的答案,因为我提到的章节有一些非常有趣且经过微调的解决方案。是的,一些实现细节是用c和/或汇编语言编写的,是的,但是在大多数情况下,算法可以在任何语言下工作:
有一些超快速的实现(从内存中)将8个或更多相邻正方形的单元表示为位模式,并使用它作为一大批预先计算的值的索引,以在单个机器指令中确定单元是活的还是死的。 在这里查看: http://dotat.at/prog/life/life.html 还有XLife: http://linux.maruhn.com/sec/xlife.html 您应该研究Hashlife,这是最终的优化。它使用了skinp提到的四叉树方法。 最有效的算法主要取决于初始状态。 如果大多数单元格已耗尽,则可以跳过空白部分而不用逐个单元地计算填充物,从而节省大量CPU时间。 我认为,当您的初始状态是"随机的,但生命机会低于5%"时,首先检查完全死的空间是有意义的。 我只是将矩阵分为两半,然后首先开始检查较大的矩阵。 因此,如果您的字段为10,000 * 10,000,则首先要累加左上四分之一状态5,000 * 5,000。 如果第一季度的状态总和为零,则您现在可以完全忽略第一季度的状态,然后检查右上角5,000 * 5,000的下一个生命。 如果其状态总和> 0,则现在将第二个四分之一再次分成4个部分-并对每个子空间重复此检查寿命。 您现在可以查看8 * 8或10 * 10的子帧(不确定在这里最有意义的子帧)。 只要找到生命,就将这些子空间标记为"具有生命"。 仅将"拥有生命"的空间划分为较小的子空间-可以跳过空的子空间。 当您为所有可能的子空间分配完"具有生命"属性后,最终将得到一个子空间列表,您现在只需将其向每个方向加+1即可扩展(带有空单元格)并执行常规(或修改后的)游戏他们的生活规则。 您可能会认为将10,000 * 10,000的空间划分为8 * 8的子空间是很多任务-但是累加它们的状态值实际上要比对每个单元格及其8个邻居执行GoL算法要少得多比较数字并将网络迭代的新状态存储在某处... 但是就像我上面说的,对于人口为30%的随机初始化状态,这没有多大意义,因为将找不到很多完全死掉的8 * 8子空间(仅留下死掉的256 * 256个子空间) 当然,完美优化的方式将持续但并非最不依赖于您的语言。 -110 该算法本身具有固有的可并行性。在未经优化的CUDA内核中使用相同的双缓冲方法,在4096x4096封装的世界中,我每代的时间大约为25ms。 两个想法: (1)许多配置大多是空白空间。保留活动单元的链接列表(不一定要按顺序进行,这会花费更多时间),并且在更新期间,仅在活动单元周围进行更新(这与您含糊的建议OysterD相似) (2)保留一个额外的数组,该数组在3个位置(左-中-右)的每一行中存储活细胞数。现在,当您计算一个单元格的新的失效/有效值时,您仅需要4个读操作(顶部/底部行和中心位置)和4个写入操作(更新3个受影响的行摘要值,以及Dead /新单元格的实时价值)。假设写入速度不慢于读取速度,则与8次读取和1次写入相比,这是一个轻微的改进。我猜您可能会更聪明地使用此类配置,并在这些方面实现更好的改进。 正如Arbash的《黑皮书》中提到的那样,获得巨大加速的最简单直接的方法之一就是保留更改列表。 不必每次都遍历整个单元格网格,而保留所有更改单元格的副本。 这样可以缩小每次迭代中要做的工作。 我在C#中实现了这一点: 所有单元格都有一个位置,一个邻居计数,一个状态以及对规则的访问。 邻居。 优点: 缺点: 对于活跃的细胞。 可能的改进: 在当前报价中更新,从而消除了对数组B的需求,如上所述 单元格没有,那些检查规则B0。 有表驱动的解决方案,可以解决每个表查找中的多个单元格。谷歌查询应该给你一些例子。 这是一个二维自动机,因此您可能可以查找优化技术。您的想法似乎与压缩每个步骤需要检查的单元格数量有关。由于您只需要检查被占用的单元格或与之相邻的单元格,也许您可??以保留所有此类单元格的缓冲区,并在处理每个单元格时在每个步骤进行更新。 如果您的字段最初为空,则速度会更快。您可能会发现一些平衡点,在这个平衡点上,维护缓冲区要比处理所有单元格花费更多。 不完全知道该怎么做,但是我记得我的一些朋友不得不用四叉树来代表游戏的网格。我猜这对于优化网格的空间确实很有用,因为您基本上只代表占用的单元格。我不知道执行速度。 Javascript中最短的实现之一:) 126字节的生活游戏引擎演示
|
最新内容
相关内容
linux创建数组命令?
linux创建数组命令?,地址,工作,系统,信息,命令,代码,目录,情况,标准,文件,Linux命令linux系统常用操作命令如下:ls:全拼list,功能是列出目录的内Python迭代器是什么?如何使用?
Python迭代器是什么?如何使用?,数据,异常,对象,工作,培训,概念,方法,关键字,之前,数据类型,迭代是重复反馈过程的活动,其目的通常是为了逼近所Python3实现旋转数组的3种算法
Python3实现旋转数组的3种算法,位置,代码,时间,培训,算法,数组,解法,结果,长度,索引,下面是Python3实现的旋转数组的3种算法。一、题目给定一Python算法是什么?有哪几类?
Python算法是什么?有哪几类?,数据,数字,时间,算法,系统,策略,位置,有限,标准,培训,了解Python的人应该都听说过Python算法,但是它们的类型和定义如何优化 Python
如何优化 Python,代码,项目,情况,在线,技术,电脑,大规模,合法,策略,培训,我最喜欢Python的一点就是它可以让你一步一步地优化你的代码。比如对数组使用Python For循环
对数组使用Python For循环,名称,培训,代码,健康,水牛,数组,元素,有用,下面,以上,您可以使用for循环从数组中获取特定元素。假设您有一组水牛b优化 Python 程序的内存占用
优化 Python 程序的内存占用,代码,数据,情况,培训,对象,字典,内存,垃圾,程序,机制,Python的垃圾回收机制通过引用计数来决定一个对象要不要被如何提速优化python代码?
如何提速优化python代码?,代码,时间,数据,新增,写法,包装,情况,下来,面临,工作,Python是一种脚本语言,相比C/C++这样的编译语言,在效率和性能方使用Python删除排序数组中的重复项
使用Python删除排序数组中的重复项,代码,培训,数组,元素,长度,示例,序数,函数,原地,后面,问题描述:给定一个排序数组,你需要在原地删除重复出现Python编程中3个常用的数据结构和
Python编程中3个常用的数据结构和算法,代码,电话号码,销售额,有限,情况,分解,异常,名称,平均,位置,python内置了许多非常有用的数据结构,比如Python机器学习之AdaBoost算法
Python机器学习之AdaBoost算法,数据,综合,失衡,时间,培训,算法,样本,权重,模型,机器,算法概述AdaBoost是英文AdaptiveBoosting(自适应增强)的Python的迭代和遍历
Python的迭代和遍历,代码,培训,数字,流程,语句,函数,元素,也就是,上面,以上,什么是迭代?迭代就是重复运行一段代码语句块的能力。分为两种方