01 结论先行
最短解可以保证。
多项式运行时间,不能保证。
把棋盘边长记为 n,格子数记为 N = n²,普通黑白格数为 M,彩格数为 R,星星数为 K。输入是显式列出的整张棋盘,且 M + R = N、K ≤ N。以下复杂度讨论允许棋盘和星星数随输入增长;固定的 8×8 六星关卡只是有限实例。
| 问题 | 只在吃星时换手 | 困住时也可换手 |
|---|---|---|
| 是否有解 | NP 完全 | NP 困难,属于 PSPACE |
| 给出一组解或报告无解 | 至少 NP 困难;解有多项式长度上界 | 至少 NP 困难;完整状态搜索可解 |
| 总移动数最少 | NP 困难;BFS 保证最优 | NP 困难;0–1 BFS 保证最优 |
| ≤ L 步能否通关 | NP 完全(L 可二进制编码) | NP 困难,属于 PSPACE |
除非 P = NP,否则两种模式都不存在解决所有输入的多项式算法。这里没有证明允许困住换手的模式是 PSPACE 完全,也没有证明它不属于 NP。NP 困难本身不意味着必须耗时 2Ω(N);本文的指数算法是一个保证正确的通用上界,不能称为已证明运行时间最优的算法。
“最优”在本网页指返回的解移动总数最少。判定只需要可达性搜索;返回一组解要额外记录前驱;最短解则要求按累计移动代价搜索。三个任务共享同一个精确状态模型。
02 把棋盘变成状态
只记两颗棋子在哪里,还远远不够。
同样的两个位置,可能对应完全不同的道路。必须记录每个普通格当前的颜色。彩格位置固定,作为棋盘参数保存,不需要反复记录。
一步转移按以下顺序执行:检查相邻格是否合法 → 移动 → 普通格染色 → 若该格仍有星,收集并换手 → 若星星清空,游戏结束。初始棋子脚下的颜色保持输入值;脚下若有星,不自动收集,须离开后再进入。
彩格保持不变。到达星星的那一步立刻换手,不能继续走完预先指定的一段路径。
规则 A · 吃星换手
无合法移动且还有星星,就是死局。从开局出发,行动方由已收集星星数的奇偶性决定,因此理论上可省去 t;统一实现仍保留它。
规则 B · 困住可换手
仅当当前棋子没有任何合法的一步移动时,增加一条代价为 0 的换手边。“暂时走不到星星”并不算困住。有路时不能主动换手;两子都困住时,来回换手没有帮助。
03 精确求解
在状态之间找路,
而不是只在格子之间找路。
一个算法,回答三个问题
- 判定:搜索所有可达状态,首次遇到 U = ∅ 就回答有解;只有搜索空间完全耗尽,才能回答无解。
- 找一组解:每发现新状态,记录“来自哪个状态、走了哪一步”,到终点后逆序回溯。
- 找最短解:规则 A 用普通 BFS;规则 B 用 0–1 BFS,移动放队尾,免费换手放队首,并且只在距离变短时更新。
所有 dist = ∞; dist[start] = 0; deque = [start]
while deque 不为空:
s = 弹出队首
if s 的剩余星星为空: 回溯并返回
for (next, cost) in 合法后继(s):
# 移动 cost = 1;困住换手 cost = 0
if dist[s] + cost < dist[next]:
更新 dist[next] 和 predecessor[next]
cost == 0 ? 放队首(next) : 放队尾(next)
return 无解
正确性:每条图边都对应一次合法操作;每次合法操作也都出现在图中。因此,通关与终点状态可达等价。所有边权非负且为 0 或 1,0–1 BFS 按最短距离展开;目标首次被正确取出时,其距离就是最少移动数。前驱链给出可实际执行的解。
网页里的等价优化:压缩免费换手
当前棋子困住时,没有别的有效操作;若另一颗能走,就立即把这个唯一的 0 代价转移压缩掉,继续对“一步移动+必要换手”做单位权 BFS。若两颗都困住,直接丢弃这个封闭的零代价循环。解的记录仍保存每一次免费换手,因此可以按原规则播放。
找到终点:已找到且证明最短。穷尽可达状态:已证明无解。达到浏览器的时间或状态上限:尚未判定,不能显示成“无解”。交互搜索默认最多 80 万个状态或 30 秒;预设关卡的初始解使用已独立验证的证书,不受此限制。
进一步加速:哪些剪枝可靠?
全状态去重始终安全。可以用 A*,启发函数取“忽略格子颜色和碰撞后的最小剩余路程”。严格模式保留吃星后交替行动,宽松模式放宽为任一棋子都可选择下一颗星,得到的下界才安全。星星较少时可用子集动态规划计算这个下界。网页实际运行的是上述 BFS,避免把额外启发式当作未说明的正确性前提。
仅保存两子位置与星星集合会错误合并不同颜色的局面;只保留每个回合到星星的最短路径也不正确,因为绕路留下的颜色可能是后续通关所需。不能把经过普通格的回路一律删除。
04 复杂度上界
状态可能指数多,
严格模式的解却不必指数长。
两颗棋子不能重合,最多有 N(N−1) 种位置组合;普通格的颜色最多 2M 种,剩余星星集合最多 2K 种,行动方 2 种。因此状态数有统一上界:
每个状态最多 4 条移动边和 1 条免费换手边,所以完整 BFS / 0–1 BFS 的时间和存储状态数均为 O(Q)(把一个状态键视作常数个机器字时)。严谨按位计费,一个状态占 O(N) 位,可写成期望时间 O(NQ)、空间 O(NQ) 位,使用哈希去重;平衡树去重可给出额外 log Q 因子的确定性上界。
定理 1 · 严格模式属于 NP
从一颗星星到下一颗星星的过程中,另一颗棋子不动。行动棋子每进入一个普通异色格,就把它染成自身颜色,因此同一回合最多进入每个普通格一次。这样的进入最多有 M 次,把回合切成最多 M+1 段纯彩格行走。
在一段纯彩格行走中,可以删去所有不吃星的重复位置循环,因为它们不改变任何状态。唯一需要保留的首尾重复,是离开后回到初始脚下尚未收集的星星;这时取最短返回回路,仍至多有 R 次彩格进入。因此存在一个等效回合,长度至多 M + (M+1)R。共有至多 K 个回合,于是只要有解,就有长度满足下式的解:
逐步验证这条多项式长度的路径即可,故判定问题属于 NP。最短解也不会超过此上界,所以即使步数预算 L 用二进制表示,“≤ L 步能否通关”仍属于 NP。没有彩格时,上界进一步降为 KM。
定理 2 · 困住可换手模式属于 PSPACE
允许不吃星就换手后,回合数不再由 K 控制,所以上面的 NP 证明不再适用。有限状态图仍然只有 Q 个状态;如果终点可达,就有一条不重复状态、至多 Q−1 条边的路径。
只存当前状态和一个 log Q = O(N) 位的计数器,非确定地猜测下一步,就能以多项式空间判定可达性。由 Savitch 定理 NPSPACE = PSPACE,得到确定性多项式空间上界。带步数预算时再存累计移动数即可。这里的论证没有给出多项式时间,也没有给出多项式长度证书。[Savitch, 1970]
几个可以立即求解的特例
K=0:已经通关,答案 0 步。严格模式且 K=1:把异色格和彩格看作可通行格,另一颗棋子所在格看作障碍,做一次普通网格 BFS 即可,时间 O(N)。最短网格路径可取简单路径,因此途中染色不妨碍执行。若唯一星星恰在初始行动棋子脚下,则须单独找最短合法返回路径;脚下格必须可重新进入,可枚举第一步并在禁用起点内部通行的图中寻找返回,总计仍为 O(N)。不能把这个特例推广到多星局面。
参数 M+K 较小时,全状态搜索给出 2M+K·poly(N) 的参数化上界。星星数少本身并没有消掉颜色状态的指数因子;下文归约中的星星数随输入增长,并不证明“最多六星”的子问题也 NP 困难。
05 复杂度下界 · 完整构造
把一个经典难题,
藏进每一步都会吃星的棋盘。
起点是一般网格图的哈密顿环问题:能否沿上下左右的边走一个环,恰好访问每个顶点一次?这个问题已被证明 NP 完全。注意这里允许网格图有缺失的顶点,并不是完整矩形网格。下面的归约把“缺失顶点”编码成普通黑格,不引入任何额外的墙。[Itai、Papadimitriou、Szwarcfiter, 1982,定理 2.1]
第一步 · 把环的终点固定下来
设原图为 G,有 v 个顶点。若有顶点度数小于 2,直接输出一盘两子都困住、还有星星的无解棋盘。否则,选取 x+y 最小、并在并列者中 x 最小的顶点 t。它没有 x−1 或 y−1 方向的邻居,因此度数恰为 2;取它的一个邻居为 s。
在 t 左侧添加一个新顶点 u。它只与 t 相邻:(x−2, y)、(x−1, y−1) 的坐标和更小;(x−1, y+1) 的坐标和相同但 x 更小,也不属于原图。于是,从 s 出发遍历 G ∪ {u} 的哈密顿路径,必以叶子 u 结束;删去 u,再补上原图边 ts,就得到 G 的哈密顿环。反过来,把环的 ts 边断开,再接上 tu,也得到这条路径。
第二步 · 用颜色隔离两颗棋子
- 在黑色背景中,把 G ∪ {u} 的顶点格设为白色;仅起点 s 设为黑色并放黑子。其余每个顶点放一颗星,共 v 颗。
- 在远处放一条有 v 个黑格的直线走廊,每格放星。白子放在走廊首端外侧的一个白格上。走廊与白子四周用一圈白格包住。
- 让白色包围圈与原图之间至少隔着一整层黑色背景,补齐成方形棋盘。所有坐标与面积都只有多项式增长。
白格承载原图。每走一步,收一颗星,且无法回来。
右边 · 白子的时钟黑色直线走廊被白格包围。只能逐格向前,为黑子交还回合。
第 0 / 12 步 · 黑子从 s 出发隔离不变量:黑子无法迈入黑色背景,因此到不了白子的白色包围圈;白子无法迈入包围圈,因此到不了黑子所在区域。双方永远不能改动另一方所在区域的颜色。彩格并非归约所需;若要求三种颜色都出现,可以在双方都无法到达的背景深处加入一个孤立彩格。
第三步 · 证明“当且仅当”
如果原图有哈密顿环:黑子按上面得到的 s → … → t → u 路径前进,每一步都吃星;白子每次向前走一格、吃星并交还回合。恰好 2v 步收完全部星星。
如果棋盘可以通关:黑子必须收完自己区域的 v 颗星。普通白格进入后变黑,又没有白子前来重新染白,因此不能重复进入;黑子只能走一条覆盖 G ∪ {u} 的简单路径。叶子 u 必是终点,故这条路径给出原图的哈密顿环。
允许困住换手也不能绕过证明:黑子若在收完自己区域的星星之前困住,无论白子走多少次,都无法改变其区域的颜色或解除阻塞。白子提前走完走廊也只能交还回合,不能帮黑子通关。隔离不变量对任意次免费换手仍成立。
两种规则的判定问题均为 NP 困难。
这是从网格哈密顿环问题到棋盘通关问题的多项式多对一归约。结合严格模式的 NP 上界,其判定问题为 NP 完全。该构造的所有通关解恰好有 2v 步,所以设 L = 2v,同时得到带步数预算问题的 NP 困难性,进而得到最短解问题的 NP 困难性。
一个对任意输入都能在多项式时间内“返回解或报告无解”的算法,也能回答判定问题,因此同样不可能存在,除非 P = NP。这里的结论针对总求解器;不把“承诺一定有解,但在无解输入上可能永远不停止”的过程混为一谈。
06 关卡与复现
难度来自计算,
最短步数有可检查的证据。
预设关卡由固定随机种子生成,再通过变异筛选。每个棋盘都是 8×8,恰有 6 颗星。用 C++ 的完整单位权 BFS(压缩困住换手)筛选,再用网页的独立 JavaScript 实现重新求最短路,并逐步重放证书。此外,穷举了全部 31,104 个 2×2 初始局面与规则组合,用不压缩换手边的独立 0–1 最短路实现交叉校验;32 个小规模归约实例也通过了两种模式的核对。下表中的步数是精确最优值,不是人为标注的难度估计。
| 关卡 | 严格最短 | 困住可换手 | 严格搜索发现状态 |
|---|
“难题”仍然带有人类主观性。这里采用较长的精确最短路、多个换手阶段和不同模式下的解法差异作为筛选依据,没有声称这些是唯一解。可随时撤销、请求当前局面的最短解,或播放整条路径。
导入格式与边界行为
JSON 包含 size、rows、black、white、stars。rows 用 B / W / C 表示黑 / 白 / 彩,坐标均为从 0 开始的 [行, 列]。交互版允许边长 2–12、0–12 颗星;这是浏览器界面限制,理论算法适用于任意有限棋盘。初始脚下的星须离开后再进入;零星局面立即完成;收完最后一颗星即结束,不再要求继续移动。免费换手不计移动数,但保存在解的动作序列中。
参考资料与证明来源
Itai, Papadimitriou & Szwarcfiter. Hamilton Paths in Grid Graphs. SIAM Journal on Computing 11(4), 676–686, 1982. 提供网格哈密顿环 NP 完全性的起点。本文对本游戏的隔离走廊归约与长度上界是按本题规则给出的独立推导,原论文没有讨论本游戏。
Savitch. Relationships between Nondeterministic and Deterministic Tape Complexities. JCSS 4(2), 177–192, 1970. 用于从非确定性多项式空间得到 PSPACE 上界。