Python实现Cellular Automata运行后平滑输出全为0问题求解
问题原因与修复方案
核心问题原因
- 邻居遍历的range参数错误:Python的range为左闭右开区间,原代码中
range(j-1,j+1)仅能遍历j-1、j两个值,range(k-1, k+1)仅能遍历k-1、k两个值,实际仅统计了2x2范围内的3个相邻格(排除自身),最大邻居墙数仅能达到3。而平滑规则设置为neighbor_wall_count > 3才设为1,该条件永远无法满足,导致所有格子被强制设为0,最终输出全是"."。 - 边界判断逻辑错误:原
inbounds函数判断x <= self.width、y <= self.height,但数组索引范围是0width-1、0height-1,该逻辑会导致访问数组越界。 - 临时数组浅拷贝问题:
temp_map = self.map是引用赋值,temp_map和self.map指向同一块内存空间,修改self.map时temp_map会同步更新,不符合元胞自动机需要基于上一状态全局同步更新的规则。
修复方案
1. 修改邻居遍历范围
将平滑函数中邻居遍历的range结束值从+1改为+2,覆盖3x3的全部邻域:
for y in range(j-1,j+2): for x in range(k-1, k+2):
2. 修正边界判断逻辑
调整inbounds函数的边界判断条件:
def inbounds(self,x,y): if (x >= 0 and x < self.width) and (y >=0 and y < self.height): return True else: return False
3. 替换为深拷贝生成临时数组
修改平滑函数中临时数组的赋值逻辑,独立保存上一状态的地图数据:
temp_map = [row.copy() for row in self.map]
修复后的完整smooth函数参考
def smooth(self,iterations): for i in range(iterations): # 深拷贝保存上一状态的地图 temp_map = [row.copy() for row in self.map] for j in range(self.height): for k in range(self.width): neighbor_wall_count = 0 # 遍历3x3邻域 for y in range(j-1,j+2): for x in range(k-1, k+2): if self.inbounds(x,y): # 排除自身 if y != j or x != k: if temp_map[y][x] == 1: neighbor_wall_count += 1 else: # 越界位置默认算墙 neighbor_wall_count += 1 if neighbor_wall_count > 3: self.map[j][k] = 1 else: self.map[j][k] = 0
修复后运行程序即可看到正常的平滑后元胞自动机图案。
内容的提问来源于stack exchange,提问作者4rmy
相关产品推荐
相关产品推荐

