银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::

S(n, m) 的定义

对于推箱子,我们定义函数 S(n, m) 表示大小为 (n + 2) x (m + 2) 的可解的最复杂的只有一个箱子的关卡的最佳答案的步数。这里最复杂的意思是使最佳答案的步数最大。

S(x, 2) 的情况

S(1, 2) S(2, 2)

  1. S(1, 2) = 0
  2. S(2, 2) = 0

这应该是毫无疑问的吧。

S(x, 3) 的情况

S(1, 3) S(2, 3) S(3, 3)

  1. S(1, 3) = 1 : D
  2. S(2, 3) = 5 : ruulD
  3. S(3, 3) = 10 : drruulDrdL

这也很容易证明。

S(x, 4) 的情况

S(1, 4) S(2, 4) S(3, 4) S(4, 4)

  1. S(1, 4) = 2 : DD
  2. S(2, 4) = 7 : uruulDD
  3. S(3, 4) ≥ 13 : drruulDrdLulD
  4. S(4, 4) ≥ 19 : uuurrDrddlUruLLulDD

稍微有点复杂了。

S(x, 5) 的情况

S(1, 5) S(2, 5) S(3, 5) S(4, 5) S(5, 5)

  1. S(1, 5) = 3 : DDD
  2. S(2, 5) = 10 : luuruulDDD
  3. S(3, 5) ≥ 15 : ulluuurDDrdLulD
  4. S(4, 5) ≥ 35 : rddddrruuuLrdddlluuluurDDDuurrdddlL
  5. S(5, 5) ≥ 41 : rddddrrruuuLLrrdddllluuluurDDDuurrrdddllL

这已经相当复杂了。

S(x, 6) 的情况

S(1, 6) S(2, 6) S(3, 6) S(4, 6) S(5, 6) S(6, 6)

  1. S(1, 6) = 4 : DDDD
  2. S(2, 6) = 12 : luuuruulDDDD
  3. S(3, 6) ≥ 25 : lluuuuurDlddddrruuuLulDDD
  4. S(4, 6) ≥ 44 : rddddrruuuLrdddlluuluurDDDuurrddddllluRRdrUU
  5. S(5, 6) ≥ 58 : lddddllluuruRlldddrrruuruulDDDuullldddrrdrruLLLrruuulllddD
  6. S(6, 6) ≥ 77 : llulluuurrurrddlDuruullllddddrrdrruLLLrruuruulllldddlddrUUUddrrruuruullllldRR

这就更加复杂了,充满不确定性。

B(n, m) 的定义

我们定义一个函数 B(n, m) 如下:

  • B(1, m) = m - 2,      when m > 0
  • B(n, m) = B(m, n),   when m > 0, n > m
  • B(n, m) = B(n - 1, m - 1) + B(n - 1, m),  when m > 1, n > 1, n ≤ m

于是我们有以下的表格:

B(n, m)
n\m123456
1 -1 0 1 2 3 4
2   -1 1 3 5 7
3     0 4 8 12
4       4 12 20
5         16 32
6           48
 
S(n, m)
n\m123456
1 X 0 1 2 3 4
2   0 5 7 10 12
3     10 ≥13 ≥15 ≥25
4       ≥19 ≥35 ≥44
5         ≥41 ≥58
6           ≥77

SB猜想

观察上一小节的两个表格,我们有一个猜想:S(n, m) ≥ B(n, m),估且称之为SB猜想。

计算 B(n, m) 的 C# 程序

以下就是计算 B(n,m) 的 C# 程序 ComputeB.cs:

 1 using System;
 2 
 3 sealed class ComputeB
 4 {
 5   static void Main(string[] args)
 6   {
 7     var N = (args.Length > 0) ? int.Parse(args[0]) : 6;
 8     var M = (args.Length > 1) ? int.Parse(args[1]) : N;
 9     Console.WriteLine("B({0}, {1}) = {2:N0}", N, M, B(N, M));
10   }
11   
12   static long B(int N, int M)
13   {
14     if (N > M) Swap(ref N, ref M);
15     var b = new long[N + 1, M + 1];
16     for (var m = 1; m <= M; m++) b[1, m] = m - 2;
17     for (var n = 2; n <= N; n++)
18       for (var m = n; m <= M; m++)
19         b[n, m] = b[n - 1, m - 1] + b[n - 1, m];
20     return b[N, M];
21   }
22   
23   static void Swap<T>(ref T x, ref T y)
24   {
25     var t = x;
26     x = y;
27     y = t;
28   }
29 }

运行结果如下所示:

E:\work> ComputeB 4 5
B(4, 5) = 12
E:\work> ComputeB
B(6, 6) = 48
E:\work> ComputeB 23
B(23, 23) = 41,943,040

可见函数 B(n, m) 增长得非常快。

关于一个推箱子问题的悬赏

推箱子论坛的“关于一个推箱子问题的悬赏”中说:

在经典的推箱子游戏规则下,满足下面三个条件的关卡至今仍没有找到:
(1)大小在50x50以内,包括作为边界的墙体在内
(2)恰有1个箱子(当然也恰有1个目标)
(3)最佳答案大于或等于100000(十万)步,强调一下是最佳答案,即步数最少的答案。
问题:满足上面三个条件的推箱子关卡存在吗?
3. 解答者把自己研究得到的解答直接通过电子邮件发送至 yangchao0710@gmail.com 
若给出肯定的回答,只需提供xsb格式的关卡文件即可。
若给出否定的回答,则需要给出严格的证明。

如果上述SB猜想成立,则答案是肯定的。如果有人能够证明SB猜想,很可能无法提供xsb格式的关卡文件,从而无法领取悬赏。:(

进一步的话题

其实,B(n, m) 函数增长太快了一点,所以SB猜想不是很靠谱。更好的做法,是寻找一个增长不那么快的 C(n, m) 函数,然后提出一个更靠谱的SC猜想:S(n, m) ≥ C(n, m)。

S(n, m) 的值是客观存在的,但是我们只知道很少的几个 S(n, m) 的值,对于绝大多数 (n, m),我们只能给出 S(n, m) 的最小值,并且可以不断改进这个最小值。

如果我们定义一个函数 T(n) = S(n, n),那么,如果有一个富翁给出一个悬赏:

在 2099-12-31 之前求出 T(123456789) 的值并证明该值的正确性的个人和单位,奖励十亿元人民币。

那么,这笔奖金非常可能发不出去。

P(n, m, k)、Q(n, m, k) 和 R(n, m) 的定义

进一步,我们定义以下函数:

  • P(n, m, k) 表示大小为 (n + 2) x (m + 2) 的可解的最复杂的最多 k 个箱子的关卡的最佳答案的步数。
  • Q(n, m, k) 表示大小为 (n + 2) x (m + 2) 的可解的最复杂的刚好 k 个箱子的关卡的最佳答案的步数。
  • R(n, m) = P(n, m, n * m),表示大小为 (n + 2) x (m + 2) 的可解的最复杂的关卡的最佳答案的步数。
  • S(n, m) = Q(n, m, 1),表示大小为 (n + 2) x (m + 2) 的可解的最复杂的只有一个箱子的关卡的最佳答案的步数。

显然,R(n, m) ≥ S(n, m),也更值得研究。

参考资料

  1. 关于一个推箱子问题的悬赏
  2. HTML5 Sokoban
  3. XSB和LURD格式简介
  4. Ben's Home | Skyiv Studio
posted on 2012-04-15 00:10  银河  阅读(2792)  评论(2编辑  收藏  举报