提交 487c5506 编写于 作者: W wizardforcel

6.

上级 1a999c6d
......@@ -109,7 +109,7 @@ GoL中的稳定模式很难不被注意,特别是那些移动的模式。 将
对嘛?
好吧,不是那样。 我们认为“真实”的许多实体,也是规模较小的实体的持久图案。 飓风只是气流的图案,但我们给了他们个人名称。 而人就像滑翔机,随着时间的推移不是由相同细胞组成的。 但即使你更换了你体内的每一个细胞,我们也认为你是同一个人。
好吧,不是那样。 我们认为“真实”的许多实体,也是规模较小的实体的持久图案。 飓风只是气流的模式,但我们给了他们个人名称。 而人就像滑翔机,随着时间的推移不是由相同细胞组成的。 但即使你更换了你体内的每一个细胞,我们也认为你是同一个人。
这不是一个新观察 - 大约在 2500 年前,赫拉克利特(Heraclitus)指出你不能在同一条河流中两次 - 但是出现在生命游戏中的实体,是思考哲学现实主义的实用测试用例。
......@@ -140,3 +140,116 @@ SR4:
如果一个理论正确地描述了现实,那么这个理论就是真的,否则就是假。真实理论所假设的实体是真实的;其他不是。
SR4 非常强,可能是站不住脚的;通过这样一个严格的标准,几乎所有当前的理论都被认为是错误的。 大多数现实主义者会接受 SR1 和 SR3 之间的东西。
## 6.5 工具主义
但 SR1 很弱以至于它接近工具主义,这是一种观点,我们不能说理论是真是假,因为我们不知道理论是否符合现实。 理论是我们用于我们的目的的工具;在适用于其目的的程度上,理论是有用的,或者不是。
要看看你是否对工具主义感到满意,请考虑以下陈述:
“声明游戏中的实体并不是真实的;他们只是人们赋予可爱的名字的细胞图案。”
“飓风只是一种气流模式,但它是一种有用的描述,因为它可以让我们进行有关天气的预测和沟通。”
“像自我和超我这样的弗洛伊德实体并不是真实的,但它们是思考和交流心理学的有用工具(或者至少有些人是这么认为的)。”
“电磁场是我们最好的电磁理论中的假设实体,但它们并不真实。 我们可以构建其他理论,而不用场的假设,这也是一样有用的。”
“我们认为,世界上的许多物体都是像星座一样的任意集合。 例如,蘑菇只是真菌的子实体,其中大部分是在地下生长的,几乎不连续的细胞网络。 我们由于实际原因专注于蘑菇,如可见性和可爱。”
“有些物体边界清晰,但很多都是模糊的。 例如,哪些分子是你身体的一部分:你的肺里的空气? 你的胃里的食物? 你血液中的营养物质? 细胞中的营养物质? 细胞中的水? 细胞的结构部分? 头发? 死皮? 污垢? 你的皮肤上的细菌? 你的肠道细菌?线粒体? 当你称量自己时,你包含了多少这些分子? 根据离散对象构想世界是有用的,但我们确定的实体并不是真实的。”
对于每一个你同意的陈述,给自己一分。 如果你的分数超过 4 分,你可能会成为一名工具主义者!
如果你比其他人更喜欢这些陈述,那么问问你自己为什么。 这些情景中的哪些差异会影响你的反应? 你能否在他们之间做出原则性区分?
工具主义的更多信息,请参阅 <http://en.wikipedia.org/wiki/Instrumentalism>
## 6.6 实现
本章最后的练习要求你尝试和修改生命游戏,并实现其他二维元胞自动机。 本节介绍 GoL 的实现,您可以将其用作实验的起始位置。
为了表示细胞的状态,我使用类型为`uint8`的 NumPy 数组,它是一个 8 位无符号整数。 例如,下面这行创建一个 10 乘 10 的数组,并用 0 和 1 的随机值进行初始化。
```py
a = np.random.randint(2, size=(10, 10)).astype(np.uint8)
```
我们可以用几种方法计算 GoL 规则。 最简单的方法是使用`for`循环遍历数组的行和列:
```py
b = np.zeros_like(a)
rows, cols = a.shape
for i in range(1, rows-1):
for j in range(1, cols-1):
state = a[i, j]
neighbors = a[i-1:i+2, j-1:j+2]
k = np.sum(neighbors) - state
if state:
if k==2 or k==3:
b[i, j] = 1
else:
if k == 3:
b[i, j] = 1
```
最初,`b`是一个与`a`大小相同的零数组。 每次循环中,状态是中心细胞的条件,邻居是`3×3`的邻域。 `k`是活动邻居的数量(不包括中心细胞)。 嵌套的`if`语句评估 GoL 规则并相应地激活`b`中的细胞。
这个实现是规则的直接翻译,但它是冗长而缓慢的。 我们可以使用互相关做得更好,正如我们在第?节中看到的那样。 在那里,我们使用`np.correlate`来计算一维相关。 现在,为了计算二维相关,我们将使用`scipy.signal`中的`correlate2d`,它是一个 SciPy 模块,提供信号处理的相关函数:
```py
from scipy.signal import correlate2d
kernel = np.array([[1, 1, 1],
[1, 0, 1],
[1, 1, 1]])
c = correlate2d(a, kernel, mode='same')
```
在一维相关的背景下,我们称之为“窗口”的内容,在二维相关的背景下被称为“核”,但其想法是相同的:`correlate2d`将核和数组相乘来选择一个邻域,然后将结果加起来。 这会核选择中心细胞周围的 8 个邻居。
`correlate2d`将核应用于数组中的每个位置。 使用`mode ='same'`时,结果与`a`的大小相同。
现在我们可以使用逻辑运算符来计算规则:
```py
b = (c==3) | (c==2) & a
b = b.astype(np.uint8)
```
第一行计算了一个布尔数组,其中应该有活细胞的地方为`True`,其他地方为`False`。 然后,`astype`将布尔数组转换为整数数组。
这个版本更快,也许够好,但是我们可以通过修改核来简化它:
```py
kernel = np.array([[1, 1, 1],
[1,10, 1],
[1, 1, 1]])
c = correlate2d(a, kernel, mode='same')
b = (c==3) | (c==12) | (c==13)
b = b.astype(np.uint8)
```
这个版本核的包含中心单元并赋予其权重 10。如果中心单元为 0,则结果介于 0 和 8 之间; 如果中心单元为 1,则结果在 10 到 18 之间。使用这个核,我们可以简化逻辑运算,只选择值为 3,12 和 13 的细胞。
这看起来可能不是什么大的改进,但它允许进一步简化:使用这个核,我们可以使用一个表来查找细胞的值,就像我们在第?节中所做的那样。
```py
table = np.zeros(20, dtype=np.uint8)
table[[3, 12, 13]] = 1
c = correlate2d(a, kernel, mode='same')
b = table[c]
```
除了位置 3,12 和 13 以外,表格中的任何位置都为零。当我们使用`c`作为表格中的索引时,NumPy 执行逐元素查找;也就是说,它从`c`中获取每个值,在表中查找它并将结果放入`b`中。
这个版本比其他版本更快更简洁, 唯一的缺点是需要更多的解释。
包含在本书仓库中的`Life.py`提供了一个封装规则实现的`Life`类。 如果你执行`Life.py`,你应该看到一个“蒸汽火车”的动画,这是一种飞船,在其尾部留下一串碎屑。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册