你以为有 64 种操作?实际只有 30 种——矩阵 A 深度剖析
魔表05:矩阵解剖——当线性代数遇见齿轮传动
回顾
在上一篇文章中,我们用 6 个原型向量和三种对称变换 \(R\)、\(C\)、\(D\),生成了完整的 \(18 \times 64\) 矩阵 \(\mathbf{A}\)。这个矩阵的 64 列对应全部 64 种“按钮-拨轮”基本操作,18 行对应 18 个表盘指针位置。
上一篇文章的末尾写道:
"下一篇,我们将对 \(\mathbf{A}\) 进行深入的数学分析——秩、不变量、可达状态空间,真正理解这个 \(18 \times 64\) 矩阵背后的结构。"
这一篇,我们就来做这件事。而且我们将会看到,矩阵的代数结构恰好映射回了魔表的机械传动原理——数学和物理在这一刻互相印证。
一、64 列中有多少是真正不同的?
上一篇文章中,我们输出了矩阵 \(\mathbf{A}\) 的完整内容。仔细观察输出数据(在上一篇第四节可以查看),一个现象立刻跳了出来:
很多列,一模一样。
下图用不同颜色的矩形框框出了部分相同的列,这样重复的列还有很多,不难找到。

例如前四列(empty 按钮集 × UL/UR/DR/DL 四个拨轮),全部是同一个向量:
第 5~8 列(全按按钮集 × UL/UR/DR/DL 四个拨轮),也是完全相同的向量:
其他按钮集的情况类似——有些 4 列完全相同,有些呈 2+2 模式(其中两列相同,另外两列也相同)或者 1+3 模式。
我们写一段程序来精确统计。
# 统计 A 中唯一列的数量
unique_cols = {}
for col in range(64):
vec = tuple(A[:, col]) # 列向量转元组
if vec not in unique_cols:
unique_cols[vec] = col
print(f"64 列中, 唯一不同的列共有: {len(unique_cols)} 列")
运行结果:
64 列中, 唯一不同的列共有: 30 列
64 列中只有 30 个是不同的。 这意味着超过一半的列是重复的。不仅如此,按按钮集分组,每个组内 4 个拨轮的等价关系如下:
| 按钮集 | 组内等价分划 | 不同列数 |
|---|---|---|
| \(\varnothing\) | UL ≡ UR ≡ DR ≡ DL | 1 |
| \(\{\mathrm{UL},\mathrm{UR},\mathrm{DL},\mathrm{DR}\}\) | UL ≡ UR ≡ DR ≡ DL | 1 |
| \(\{\mathrm{UL}\}\) | UL | UR ≡ DR ≡ DL | 2 |
| \(\{\mathrm{UR}\}\) | UR | UL ≡ DR ≡ DL | 2 |
| \(\{\mathrm{DL}\}\) | DL | UL ≡ UR ≡ DR | 2 |
| \(\{\mathrm{DR}\}\) | DR | UL ≡ UR ≡ DL | 2 |
| \(\{\mathrm{UL},\mathrm{UR}\}\) | UL ≡ UR | DR ≡ DL | 2 |
| \(\{\mathrm{UL},\mathrm{DL}\}\) | UL ≡ DL | UR ≡ DR | 2 |
| \(\{\mathrm{UL},\mathrm{DR}\}\) | UL ≡ DR | UR ≡ DL | 2 |
| ……(补集遵循相同模式) |
规律非常清晰:
- 全空(\(\varnothing\))和全按(四个全按)时,4 个拨轮完全等效 → 各 1 种
- 其余 14 个按钮集,4 个拨轮分成 2 组,组内等效 → 各 2 种
总计:
64 种基本操作中,只有 30 种是不同的。
二、按钮与拨轮的联动规律
进一步观察,每个按钮集内部的等价分组有一条统一的规则:
\(\{\text{按下的按钮}\}\) 对应的拨轮彼此等价,\(\{\text{弹起的按钮}\}\) 对应的拨轮也彼此等价。
我们把这个规则称为 P/Q 联动。具体来说,对于任意按钮状态:
定义 \(P = \{\text{按下的按钮对应的拨轮}\}\),\(Q = \{\text{弹起的按钮对应的拨轮}\}\)(按钮与拨轮位置一一对应,共用 UL/UR/DR/DL 标签)。
转动 \(P\) 中的任一拨轮,效果完全相同;转动 \(Q\) 中的任一拨轮,效果完全相同。
用代码验证,所有 16 组均满足:
wheels = ["UL", "UR", "DR", "DL"]
for i, label in enumerate(ul_labels): # 遍历 16 种按钮集
# 解析出按下的按钮集合 P
P = {w for w in wheels if w in label} # e.g. {"UL","UR"}
Q = set(wheels) - P # e.g. {"DR","DL"}
# 取出该按钮集的 4 列 (对应 4 个拨轮)
cols = {w: A[:, i*4 + k] for k, w in enumerate(wheels)}
# 检查: P 内所有拨轮的列是否两两相等
p_cols = [cols[w] for w in P]
p_ok = all(np.array_equal(p_cols[0], c) for c in p_cols)
# 检查: Q 内所有拨轮的列是否两两相等
q_cols = [cols[w] for w in Q]
q_ok = all(np.array_equal(q_cols[0], c) for c in q_cols)
assert p_ok and q_ok, f"P/Q rule failed for {label}!"
验证结果:16 组全部通过。
举几个具体例子来看:
- \(S = \{\mathrm{UL}\}\):\(P = \{\mathrm{UL}\}\),\(Q = \{\mathrm{UR}, \mathrm{DR}, \mathrm{DL}\}\)。转 UL 独成一类;转 UR、DR、DL 三者效果相同。
- \(S = \{\mathrm{UL}, \mathrm{UR}\}\):\(P = \{\mathrm{UL}, \mathrm{UR}\}\),\(Q = \{\mathrm{DR}, \mathrm{DL}\}\)。转 UL 和 UR 等价;转 DR 和 DL 等价。
- \(S = \varnothing\):\(P = \varnothing\),\(Q = \{\mathrm{UL}, \mathrm{UR}, \mathrm{DR}, \mathrm{DL}\}\)。全部拨轮属于 \(Q\),四个全等 → 退化为 1 种。
- \(S = \{\mathrm{UL},\mathrm{UR},\mathrm{DR},\mathrm{DL}\}\):\(P = \{\mathrm{UL}, \mathrm{UR}, \mathrm{DR}, \mathrm{DL}\}\) ,\(Q = \varnothing\) 。四个拨轮全等 → 退化为 1 种。
三、对应机械结构:P/Q 联动
上一节总结的数学规律,是真的吗?拿出魔表实物来验证。
观察魔表的传动机制,你会发现:
- 按下的按钮会将对应的拨轮与一个共同的齿轮组连接起来。因此,转动 \(P\) 中任何一个拨轮,都会通过这个齿轮组驱动所有按下的按钮所对应的表盘,效果完全相同。
- 弹起的按钮则与另一个齿轮组相连。转动 \(Q\) 中任何一个拨轮,同样会通过该齿轮组统一传动。
于是,在一个固定的按钮状态下,四个拨轮被分成两个功能等价组。转动同一组内的任意拨轮,对表盘的影响完全一致。这就是矩阵中等价列的物理根源。
用魔表圈的术语,弹起按钮对应的拨轮称为 F 轮,按下按钮对应的拨轮称为 B 轮。本文后续将使用这一约定。
F 轮:弹起的按钮所对应的拨轮(\(Q\) 类)
B 轮:按下的按钮所对应的拨轮(\(P\) 类)
回顾上面的等价关系表,用 F/B 语言描述:
- \(\varnothing\)(全弹):全部是 F 轮,四个 F 轮等效 → 1 种操作
- \(\{\mathrm{UL},\mathrm{UR},\mathrm{DL},\mathrm{DR}\}\)(全按):全部是 B 轮,四个 B 轮等效 → 1 种操作
- 其余 14 组:既有 F 轮又有 B 轮,各 2 种
这一结论在网上的魔表研究中也得到了独立验证。blueten 在 《用矩阵探索魔表的复原》 一文中,直接从机械角度得出了完全一致的结论:
"16 种立柱状态中,除了 all 只有 B 轮、ALL 只有 F 轮以外,其他 14 种状态都同时存在 F 轮和 B 轮,因此外轮一共有 30 种转动方法。"
我们的分析路径是“先看矩阵数据 → 归纳数学规律 → 再对实物验证”,而 blueten 是“从机械原理直接推导”。两种不同的路径,得出了完全一致的结论——数学结构就是机械结构的忠实映射。
四、角部的硬连接
除了 P/Q 联动,矩阵中还隐藏着另一条简洁的规律。
我们固定一个拨轮(比如 UL),遍历全部 16 种按钮状态,检查该拨轮对四个角部位置的影响是否一致。换句话说:
只换按钮、不换拨轮,角部位置的值会不会变?
wheels = ["UL", "UR", "DR", "DL"]
# 定义四个角部位置:拨轮 k → (正面角索引, 反面角索引)
corner_map = {
"UL": ("F1", 0, "B3", 11), # k=0: F_1 在向量索引 0, B_3 在 11
"UR": ("F3", 2, "B1", 9), # k=1: F_3 在索引 2, B_1 在 9
"DR": ("F9", 8, "B7", 15), # k=2: F_9 在索引 8, B_7 在 15
"DL": ("F7", 6, "B9", 17), # k=3: F_7 在索引 6, B_9 在 17
}
for k, w in enumerate(wheels):
f_name, f_idx, b_name, b_idx = corner_map[w]
# 遍历 16 种按钮状态, 取该拨轮对应的列
f_vals = [A[f_idx, i*4 + k] for i in range(16)]
b_vals = [A[b_idx, i*4 + k] for i in range(16)]
# 全部应为 +1 (1) 和 -1 (11)
f_ok = all(v == 1 for v in f_vals)
b_ok = all(v == 11 for v in b_vals)
print(f"转 {w} 轮: {f_name}={f_ok}, {b_name}={b_ok}")
运行结果:
转 UL 轮: F1=True, B3=True
转 UR 轮: F3=True, B1=True
转 DR 轮: F9=True, B7=True
转 DL 轮: F7=True, B9=True
全部为 True。结论非常明确:
| 只要转的是 | 正面这个角一定是 | 反面这个角一定是 |
|---|---|---|
| UL 拨轮 | \(F_1 = +1\) | \(B_3 = -1\) |
| UR 拨轮 | \(F_3 = +1\) | \(B_1 = -1\) |
| DR 拨轮 | \(F_9 = +1\) | \(B_7 = -1\) |
| DL 拨轮 | \(F_7 = +1\) | \(B_9 = -1\) |
与按钮状态完全无关。 换句话说,角部指针与拨轮之间存在着固定的对应关系:顺时针转 UL 轮,\(F_1\) 一定 \(+1\)、\(B_3\) 一定 \(-1\)——无论按钮怎么按,这个对应关系都不会消失。当然,由于上一节讨论的 P/Q 联动,\(F_1\) 也可能在转动其他拨轮(与 UL 同属一个等价类的轮)时获得 \(+1\)。但 UL 轮对 \(F_1\) 的直接驱动始终存在,不会被按钮切断。
blueten 的文章中也写明了这一点:“角上的指针都是互相关联的,因此实际上我们只需要关注 14 个指针的变动。”——与我们的结论完全一致。
五、18 维空间的结构分解
综合以上分析,我们可以将 18 维状态空间做一个清晰的结构分解。
5.1 角部(8 维)
如上节所述,每个拨轮对特定的角部指针有固定的直接驱动关系(如 UL 轮 → \(F_1=+1,\;B_3=-1\)),这一关系始终成立、不受按钮状态影响。但角部指针的实际运动还受 P/Q 联动影响——它们也可能在同组其他轮转动时被间接带动。
而在这 8 维中还存在 4 个不变量。检查矩阵 \(\mathbf{A}\) 的所有 64 列,可以发现无论哪种操作,以下关系始终成立:
这四条约束把角部的 8 个自由度压缩到 4 个有效自由度。
5.2 非角部(10 维)
除去 8 个角部位置,剩余 10 个位置是真正随按钮状态变化的"可变分量":
我们从 30 个唯一列中抽出这 10 行,构成一个 \(10 \times 30\) 的子矩阵,计算它的秩:
# 从 30 个唯一列中抽取非角部 10 行
corner_idx = [0, 2, 6, 8, 9, 11, 15, 17] # 角部位置索引
non_corner_idx = [i for i in range(18) if i not in corner_idx]
M = A_unique[non_corner_idx, :] # 10 × 30 子矩阵
print(f"非角部子矩阵: {M.shape}, rank = {np.linalg.matrix_rank(M)}")
# 输出: 非角部子矩阵: (10, 30), rank = 10
秩 = 10 = 行数,这是满行秩。回顾线性代数的结论:
对于 \(M\mathbf{k} = \mathbf{y}\),其中 \(M\) 是 \(m \times n\) 矩阵,秩为 \(r\):
- 有解当且仅当 \(\mathbf{y}\) 落在 \(M\) 的列空间中。若 \(r = m\)(满行秩),则列空间 = 整个 \(\mathbb{R}^m\),任意 \(\mathbf{y}\) 都有解。
- 解唯一当且仅当核空间维数 \(n - r = 0\),即满列秩。这里 \(n = 30\)、\(r = 10\),核空间维数 = \(20\),所以解不唯一——有无穷多种操作组合能达到同一目标。
因此:
给定任意的 10 个目标值,总能找到操作组合精确实现它;而且解法远不止一种。非角部指针是"完全独立可控"的。
用随机目标验证:
for _ in range(5):
target = np.random.randint(0, 12, 10) # 随机目标状态
k = np.linalg.lstsq(M, target)[0] # 求操作系数
result = np.round(M @ k).astype(int) % 12
assert np.all(result == target) # 全部精确命中
5 次随机目标,5 次精准命中。
注:以上分析在实数域上进行。 \(\mathbb{Z}_{12}\) 不是域,秩满行不严格保证 \(\mathbb{Z}_{12}\) 上有解。但矩阵元素仅含 \(0, \pm 1\)、结构高度规整,随机验证也全部通过——经验上确认 \(\mathbb{Z}_{12}\) 中同样满秩。严格证明需要模论工具,此处不再展开。
5.3 总结图
矩阵 \(\mathbf{A}\) 的总秩 = \(4 + 10 = 14\)。
进一步,如果我们去掉背面四个角(\(B_1, B_3, B_7, B_9\)),只关注剩余的 14 个指针(全部正面 9 个 + 反面 5 个非角部),这 14 维子矩阵的秩同样是 14——满秩。这意味着:
这 14 个指针的任意排布都是可达的。 而背面四个角无需主动控制——它们被四个不变量锁死:\(B_1 = -F_3\)、\(B_3 = -F_1\)、\(B_7 = -F_9\)、\(B_9 = -F_7\)。只要把 14 个可控指针复原到位,背面四角自动归位。
这也解释了为什么 blueten 在机械分析中只关注 14 个指针——其余 4 个是冗余的,由不变量唯一确定。
5.4 简化后的矩阵 A

经过简化,我们最终最简洁的矩阵 \(A\) 如图所示,矩阵大小 \(14 \times 30\)。这将大大简化我们的计算。
六、原型还能再简化吗?
在第三篇中,我们确立了 6 个原型——v0 到 v5。当时只有 \(R\)、\(C\)、\(D\) 三种对称变换,\(R\) 会改变拨轮(UL → UR → DR → DL),所以在固定 UL 拨轮的前提下,能用的生成手段只有 \(C\) 和 \(D\)。6 个原型在这个框架下两两之间无法互推,因此都是必需的。
但现在我们有了 P/Q 联动。它打通了一条新的推导路径:\(R\) 变换后的向量,有时也等于一个 UL 拨轮的向量。
6.1 v3 = R(v2)
以 v2 和 v3 为例。回顾第三篇中它们的定义:
现在对 v2 施加 \(R\) 变换:
这是 \(R\) 对称性的标准结论——按钮集和拨轮同时旋转。此时按钮集为 \(\{\mathrm{DR}\}\),P/Q 划分为 \(P = \{\mathrm{DR}\}\),\(Q = \{\mathrm{UL}, \mathrm{UR}, \mathrm{DL}\}\)。注意 UR 和 UL 同在 Q 中——由 P/Q 联动,转 UR 和转 UL 效果相同:
因此:
经代码验证,两者模 12 下完全相等,18 个分量一一吻合。
6.2 从 6 到 5
v3 既然可以从 v2 通过 \(R\) 推导出来,它就不再需要单独测量了。6 个原型缩减为 5 个:
6.3 总结
| 原始 | 简化后 | 依据 | |
|---|---|---|---|
| 基本操作 | 64 种 | 30 种不相同 | P/Q 联动:组内 F 轮等价、B 轮等价 |
| 独立指针 | 18 个 | 14 个(去掉背面四角) | 不变量:\(B_1=-F_3\) 等四个约束 |
| 原型数 | 6 个 | 5 个(v0, v1, v2, v4, v5) | v3 = R(v2),由 P/Q 联动打通 |
| 秩 | 14 | 14(不变) | 去重不改变列空间 |
数学模型没有”变小“——秩始终是 14。但我们搞清楚了哪些是冗余的、为什么冗余,同时与机械传动关系进行了相互印证。
七、结语
本文对 \(\mathbf{A}\) 矩阵做了系统分析,得出四条核心结论:
| 规律 | 数学发现 | 机械对应 |
|---|---|---|
| P/Q 联动 | 64 列去重为 30 列,每组内 F 轮等价、B 轮等价 | 按下/弹起按钮通过齿轮组联动对应拨轮 |
| 角部硬连接 | 拨轮对角部指针有固定驱动关系(如 UL→\(F_1\)=\(+1\), \(B_3\)=\(-1\)),始终成立 | 角部指针通过齿轮直接连在对应拨轮轴上 |
| 空间分解 | 14 维可控(全部正面 + 反面 5 个非角部),4 个背面角由不变量确定 | 14 维有效自由度 + 4 个自动归位的指针 |
| 原型简化 | 6 个原型减为 5 个(v3 = R(v2)),P/Q 联动打通了新的推导路径 | 同一对角位置的关系只需测一次即可 |
这四条规律,条条都是从矩阵数据出发归纳出来的,然后回到实物验证时精确吻合。这说明我们通过构建数学模型完美捕捉到了魔表物理结构的本质。
下一篇,我们将基于简化后的 14 维有效模型,讨论具体的求解算法——如何从给定的打乱状态出发,计算出一组可操作的基本操作序列。
参考资料
blueten,《用矩阵探索魔表的复原》,魔方吧·中文魔方俱乐部,2021.
链接:http://bbs.mf8-china.com/forum.php?mod=viewthread&tid=116206

本文对前文生成的 18×64 操作矩阵 A 进行系统分析。发现 P/Q 联动规律使 64 种操作去重为 30 种;角部指针与拨轮存在固定驱动关系;18 维状态空间中 14 维可控、4 维由不变量锁死。利用 P/Q 联动进一步将 6 个原型简化为 5 个。所有数学规律均与魔表机械传动结构一一印证。
浙公网安备 33010602011771号