一维生命游戏的非迭代算法

时间:2017-02-19 02:31:01

标签: arrays algorithm iteration conways-game-of-life

考虑一个布尔数组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]

3 个答案:

答案 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'算法也是迭代的,但有很多辅助记忆。

但你可以用一些方法来选择普通的迭代算法:

  • 使用位而不是int数组:在某些情况下,这种方式可以节省大量内存并加快速度。
  • 存储几代比特:您可以轻松比较不同代的比特,以确定代之间是否存在一些重复模式,在这种情况下,不再需要进行计算。考虑到你只有一个维度,机会可能非常高。

答案 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,然后再进行一步)。