在python中识别和替换nxn数组中的元素,以生成元胞自动机



我一直在努力开始这项关于元胞自动机的大学作业。前提很简单,给定以下形式的数组,其中1表示黑色方块(或活细胞(,0表示白色方块(或死细胞(。

world1 = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
[0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
[0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
[0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0]
[0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
[0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
[0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

在时间的每一步("勾选"(,所有单元格同时发生以下转换:

任何相邻活细胞少于两个的活细胞都会死亡,就好像是由人口不足引起的。

任何有两个或三个活邻居的活细胞都会存活到下一代。

任何有三个以上邻居的活细胞都会死亡,就好像是由于人口过多。

任何一个只有三个活邻居的死细胞都会变成活细胞,就好像是通过繁殖一样。这里的邻居指的是围绕每个元素的8个正方形

现在,作为一名物理专业的学生,我可以看到数学相当简单,但我真的不知道如何构建代码,这样以后就可以把它变成动画。我还可以看到,边缘元素应该有一些例外。贝娄是我迄今为止的尝试。。。它运行但没有返回任何内容。我相信你可以告诉我,我在编程方面相当新!

import numpy as np
world1 = np.loadtxt('data/Pulsar.txt',dtype=np.int8) #loading data
def tick(world):
north = world[i,i-1] #defining neighboughs as se, ne , n etc ..
south = world[i,i+1]
west = world[i+1,i]
east = world[i-1,i]
se = world[i+1,i+1]
sw = world[i+1,i-1]
ne = world[i-1,i+1]
nw = world[i-1,i-1]
neibours = (north, south, west, east, se, sw, ne, nw) #list of neighbough values
np.where(world.all==0 and sum(neibours)==3, 1, world ) #replacing elements in array 
np.where(world.all==1 and sum(neibours)<=2, 0, world )
np.where(world.all==1 and sum(neibours)==2 or 3, 1, world )
np.where(world.all==1 and sum(neibours)>=4, 0, world )

print(tick(world1))

我认为主要问题是,在tick函数中,您将单个单元格和整个矩阵的处理混为一谈。

它一开始似乎是处理一个单元格(引用i,我认为它是"当前"单元格的索引,尽管在任何地方都没有真正定义…(,但随后您似乎试图使用一些numpy魔法将其作为矢量化操作应用于所有单元格。这可能是可能的,但为了简单起见,我会从更明确开始。

你可能应该考虑的其他几件事:

  • 您需要对矩阵的每个单元格执行一些计算-应该有一个循环迭代矩阵的所有单元格
  • 单元格在刻度后的状态可能不会影响相邻单元格在刻度前的计算——对于每个刻度,您都希望创建矩阵的新副本并用新状态填充它,而不是将更改写入适当位置,并允许矩阵处于刻度之间的"污染"状态

所以,非常粗略地(在伪python中(:

def tick(matrix):
new_state = np.array(X,Y) 
for i in range(X):
for j in range(Y):
# this is where most of your `tick` function comes in,
# adjusted to compute new state for a single given cell
new_state[i][j] = compute_cell_state(i,j,matrix) 
return new_state
for t in range(ticks):
matrix = tick(matrix)
print(matrix)

我认为我越来越接近了,但我认为我使用的一些数据类型存在问题,因此我目前收到错误"缩放器变量的无效索引">

def tick(matrix):
new_state = np.array((17,17))
for i in range(17):
for j in range(17):
north = matrix[i][j-1]
south = matrix[i][j+1]
west = matrix[i+1][j]
east = matrix[i-1][j]
se = matrix[i+1][j+1]
sw = matrix[i+1][j-1]
ne = matrix[i-1][j+1]
nw = matrix[i-1][j-1]
neibours = (north, south, west, east, se, sw, ne, nw)
if matrix[i][j] == 0 and sum(neibours)==3:
new_state [i][j] == 1
if matrix[i][j] == 1 and sum(neibours)<=2:
new_state [i][j] == 1
if matrix[i][j] == 1 and sum(neibours)>=4:
new_state [i][j] == 0
if matrix[i][j] == 1 and sum(neibours)==2 or 3:
new_state [i][j] == 1

return new_state
world1 = np.loadtxt('data/Pulsar.txt',dtype=np.int8)        
print(tick(world1))

最新更新