元胞自动机算法似乎不起作用
Cellular Automata algorithm doesn't seem to work
我目前正在使用 Python 和 libTCOD(只是为了 "render" 电路板)开发电子仿真软件(非常基础的东西)。
所以,我有一个 78x47 的 2D 列表,它存储电路板信息(单元类型、ID、状态、坐标......)和一个模拟电线的简单算法(wireworld)。
一切似乎都很顺利,除了一件事:"electrons" 只向电线的左侧移动。所以我认为这可能与它 运行 算法的方式有关。
WireWorld 电线具有三种可能的状态:导体、尾部或头部。
- Head:状态“2”,下一步变为Tail
- Tail:状态“1”,下一步变为Conductor
- 导体:状态“0”,是默认状态,如果在 1 个单元格范围内有任何头部,则更改为头部
模拟应该如何进行(H 表示头部,t 表示尾部,- 表示电线):
- 第一步:----H----
- 第 2 步:---HtH---
- 第 3 步:--Ht-tH--
- 第四步:-Ht---tH-
- 第五步:Ht-----tH
- 第 6 步:t------t
- 第 7 步:--------
但这是目前发生的事情:
- 第一步:----H----
- 第 2 步:---Ht----
- 第 3 步:--Ht-----
- 第 4 步:-Ht------
- 第五步:Ht------
- 第 6 步:t--------
- 第 7 步:--------
看到了吗?电子头只向导线左侧移动
这是我当前的算法代码:
def run(self):
for DX, DY in ((-1,-1), (-1,+0), (-1,+1), (+0,-1), (+0,+1), (+1,-1), (+1,+0), (+1,+1)):
if BOARD[self.Y+DY][self.X+DX].STATE == 2 and self.STATE == 0:
self.STATE = 2
return True
if self.STATE == 2:
self.STATE = 1
elif self.STATE == 1:
self.STATE = 0
这就是我 运行 模拟步骤的方式:
for y in range(BOARD_HEIGHT):
for x in range(BOARD_WIDTH):
BOARD[y][x].run()
是否需要在独立线程中模拟每个单元格?
不需要多线程,您只需要确保在每个模拟步骤中都可以进行多个“-> H”转换。
我从您的代码开始编写了一个最小示例(但 class 布局略有不同):
class Simul(object):
def __init__(self, width, height):
board_1 = [[None for _ in range(width)] for _ in range(height)]
board_2 = [[None for _ in range(width)] for _ in range(height)]
self.boards = [board_1, board_2]
self.current = 0
self.pretty = {None: ' ', 0: '-', 1: 't', 2: 'H'}
self.w = width
self.h = height
def print_board(self):
for row in self.boards[self.current]:
for cell in row:
print(self.pretty[cell], end='')
print()
def run(self):
BOARD = self.boards[self.current]
other_board = self.boards[- self.current + 1]
for row in range(self.h):
for col in range(self.w):
cur_cell = BOARD[row][col]
set_h = False
for DX, DY in ((-1,-1), (-1,+0), (-1,+1), (+0,-1), (+0,+1), (+1,-1), (+1,+0), (+1,+1)):
try:
if BOARD[row+DY][col+DX] == 2 and cur_cell == 0:
other_board[row][col] = 2
set_h = True
break
except IndexError:
pass
if set_h:
continue
if cur_cell == 2:
other_board[row][col] = 1
elif cur_cell == 1:
other_board[row][col] = 0
elif cur_cell == 0:
other_board[row][col] = 0
self.current = - self.current + 1
if __name__ == '__main__':
simul = Simul(10, 5)
for col in range(10):
simul.boards[0][3][col] = 0
for row in range(3):
simul.boards[0][row][4] = 0
simul.boards[0][3][4] = 2
simul.print_board()
simul.run()
simul.print_board()
输出:
-
-
-
----H-----
-
-
H
---HtH----
我目前正在使用 Python 和 libTCOD(只是为了 "render" 电路板)开发电子仿真软件(非常基础的东西)。 所以,我有一个 78x47 的 2D 列表,它存储电路板信息(单元类型、ID、状态、坐标......)和一个模拟电线的简单算法(wireworld)。 一切似乎都很顺利,除了一件事:"electrons" 只向电线的左侧移动。所以我认为这可能与它 运行 算法的方式有关。
WireWorld 电线具有三种可能的状态:导体、尾部或头部。
- Head:状态“2”,下一步变为Tail
- Tail:状态“1”,下一步变为Conductor
- 导体:状态“0”,是默认状态,如果在 1 个单元格范围内有任何头部,则更改为头部
模拟应该如何进行(H 表示头部,t 表示尾部,- 表示电线):
- 第一步:----H----
- 第 2 步:---HtH---
- 第 3 步:--Ht-tH--
- 第四步:-Ht---tH-
- 第五步:Ht-----tH
- 第 6 步:t------t
- 第 7 步:--------
但这是目前发生的事情:
- 第一步:----H----
- 第 2 步:---Ht----
- 第 3 步:--Ht-----
- 第 4 步:-Ht------
- 第五步:Ht------
- 第 6 步:t--------
- 第 7 步:--------
看到了吗?电子头只向导线左侧移动
这是我当前的算法代码:
def run(self):
for DX, DY in ((-1,-1), (-1,+0), (-1,+1), (+0,-1), (+0,+1), (+1,-1), (+1,+0), (+1,+1)):
if BOARD[self.Y+DY][self.X+DX].STATE == 2 and self.STATE == 0:
self.STATE = 2
return True
if self.STATE == 2:
self.STATE = 1
elif self.STATE == 1:
self.STATE = 0
这就是我 运行 模拟步骤的方式:
for y in range(BOARD_HEIGHT):
for x in range(BOARD_WIDTH):
BOARD[y][x].run()
是否需要在独立线程中模拟每个单元格?
不需要多线程,您只需要确保在每个模拟步骤中都可以进行多个“-> H”转换。
我从您的代码开始编写了一个最小示例(但 class 布局略有不同):
class Simul(object):
def __init__(self, width, height):
board_1 = [[None for _ in range(width)] for _ in range(height)]
board_2 = [[None for _ in range(width)] for _ in range(height)]
self.boards = [board_1, board_2]
self.current = 0
self.pretty = {None: ' ', 0: '-', 1: 't', 2: 'H'}
self.w = width
self.h = height
def print_board(self):
for row in self.boards[self.current]:
for cell in row:
print(self.pretty[cell], end='')
print()
def run(self):
BOARD = self.boards[self.current]
other_board = self.boards[- self.current + 1]
for row in range(self.h):
for col in range(self.w):
cur_cell = BOARD[row][col]
set_h = False
for DX, DY in ((-1,-1), (-1,+0), (-1,+1), (+0,-1), (+0,+1), (+1,-1), (+1,+0), (+1,+1)):
try:
if BOARD[row+DY][col+DX] == 2 and cur_cell == 0:
other_board[row][col] = 2
set_h = True
break
except IndexError:
pass
if set_h:
continue
if cur_cell == 2:
other_board[row][col] = 1
elif cur_cell == 1:
other_board[row][col] = 0
elif cur_cell == 0:
other_board[row][col] = 0
self.current = - self.current + 1
if __name__ == '__main__':
simul = Simul(10, 5)
for col in range(10):
simul.boards[0][3][col] = 0
for row in range(3):
simul.boards[0][row][4] = 0
simul.boards[0][3][4] = 2
simul.print_board()
simul.run()
simul.print_board()
输出:
-
-
-
----H-----
-
-
H
---HtH----