考虑一个布尔数组a[n]
,其中每个元素都是一个单元格。如果一个且仅一个相邻单元处于活动状态,则单元在下一代中变为活动(设置为true
),否则它将变为死区(设置为false
)。第一个和最后一个单元格被认为是邻居。
给定a[n]
,数组大小n
和正整数t
,我希望在生成进化后计算a[n]
,但不使用t
上的任何迭代算法,可能非常大。
我观察到的内容:如果我们将S_k(a[n])
定义为a[n]
的{{1>} 循环移位,则k
元素。也就是说,如果a[0]
,a[k]
在一个班次后变为0 <= k < n
。将a[n] ^ b[n]
定义为两个布尔数组之间的元素xor运算。如果w[n]
是布尔数组,则下一代可以用
r(w[n]) = S_{-1}(w[n]) ^ S_1(w[n])
xor运算符^
是关联的和可交换的。使用此属性,可以通过
w[n]
r^2(w[n]) = ( S_{-2}(w[n]) ^ S_0(w[n]) ) ^ ( S_0(w[n]) ^ S_2(w[n]) )
= S_{-2}(w[n]) ^ S_2(w[n])
如果我们让s_j = S_{-j}(w[n]) ^ S_j(w[n])
,则有一种模式
r(w[n]) = s_1
r^2(w[n]) = s_2
r^3(w[n]) = s_3 ^ s_1
r^4(w[n]) = s_4
...
r(s_m) = s_{m-1} ^ s_{m+1}
此外,s_n = 0
(零数组)因为完整的循环移位是原始数组。如何使用它来导出r^t(w[n])
的非迭代表达式?
编辑:模式是
[1]
[2]
[1,3]
[4]
[3,5]
[2,6]
[1,3,5,7]
[8]
答案 0 :(得分:1)
让我们将您的输入表示为Z / 2Z元素大小为a_0
的列向量n
。
您可以使用矩阵乘法计算下一代向量a_1
:
a_1 = M.a_0 = |0 1 0 0 ... 0 0 0| |a_01|
|1 0 1 0 ... 0 0 0| |a_02|
|0 1 0 1 ... 0 0 0| |a_03|
....
|0 0 0 0 ... 0 1 0| |... |
|0 0 0 0 ... 1 0 1| |... |
|0 0 0 0 ... 0 1 0| |a_0n|
鉴于此递归关系,您可以使用以下公式计算t
时的生成:
a_t = M^t . a_0
您可以使用重复的平方轻松计算M^t
中的O(n^3.log(t))
。
答案 1 :(得分:0)
据我所知,正如here所述,没有非迭代的方法来解决这个游戏。即使是'Hashlife'算法也是迭代的,但有很多辅助记忆。
但你可以用一些方法来选择普通的迭代算法:
答案 2 :(得分:0)
我认为你需要发现更多的模式...
它会继续这样:
1
2
1 3
4
3 5
2 6
1 3 5 7
8
7 9
6 a
5 b
4 c
3 ??? d
2 e
1 3 5 7 9 b d f
g
如果是这样,最简单的方法似乎是计算最接近2的幂<= t,然后对余数(t&#39; = t-2 ^ n)等进行相同的计算,所以你&# 39; d下降到O(log(t))。如果???区域实际上是空的,你应该能够将步骤限制为3(通过计算之前的值来避免2 ^ n-1,然后再进行一步)。