尝试优化我当前使用Wolfram Numbering生成元胞自动机的程序实现。在计算每个元胞的邻居后,我在将规则应用到棋盘上时遇到了问题。当前示例使用2个状态,与Conway的Game of Life相同,但我的程序可以处理任意数量的状态。十进制224以如下方式对应于CGOL的规则集:[0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0]基本上,每个状态(0 - 8)有18个位置或9个可能的邻域总和。如果当前单元格为1,则按以下方式索引到规则中:
>>> [0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0][1::2]
[0, 0, 1, 1, 0, 0, 0, 0, 0]
1是单元格的值,2是状态数。如图所示,如果状态为1,则如果有2或3个相邻单元格,则该单元格生存,否则将死亡。在此基础上,您可以索引w/该单元格的邻域和,以获得该单元格的实际更新值。因此,要在每代更新单元格,您需要:规则[状态值::总状态][邻居的总和]。例如,
>>> [0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0][1::2][2]
1
现在,我有了一个所有单元格的网格,叫做world,形状是任意的,另一个形状相同的numpy数组,它有每个单元格的所有邻居的总和,使用scipy的卷积计算--称之为nbrs--,还有前面提到的规则列表--是否可以更新world中每个单元格的值,同时避免for循环?
例如:world = rule [像元值::状态总数][nbrs中给定像元的相邻像元总和]
1条答案
按热度按时间jmo0nnb31#
你没有给我们很多代码,所以这里有一个最小的想法,它如何工作。
首先,创建一个数组,您可以使用当前状态索引该数组以获取规则:
现在,您可以使用当前状态来获取每个单元格的规则:
为了得到新的世界状态,我们可以使用索引迭代器。在这里,我使用一个包含所有世界索引的数组来首先得到(展平的)当前单元格邻域和,然后使用这些得到(展平的)新状态。在赋值中,我再次将其展平为世界形状。(可能有更简单的方法来做到这一点...)
要避免使用大型
cur_cell_rules
数组,您也可以采用另一种方法: