python-3.x - SymPy 排列组奇偶校验未按预期工作
问题描述
我已经使用元组的排列实现了一个魔方。没有变化的立方体表示为 (0, 1, 2, ... , 45, 46, 47)。
为了对立方体应用“转”,数字被打乱了。我已经非常全面地测试了我所有的轮次,以至于我相当确定没有错别字。
我一直在尝试实现一种检查多维数据集是否有效的方法,因为 (1, 2, ... 47, 48) 的 12 个随机排列中只有 1 个是有效的多维数据集。要使排列成为有效的魔方,它必须满足 3 个要求。这在这个 SO 线程中有很好的记录:https ://math.stackexchange.com/questions/127577/how-to-tell-if-a-rubiks-cube-is-solvable
这 3 个步骤是: 边缘方向:边缘翻转的数量必须是偶数。拐角方向:拐角扭曲的数量必须能被 3 整除。排列奇偶校验:这是我遇到麻烦的地方。排列奇偶校验必须是偶数,这意味着角奇偶校验必须匹配边缘奇偶校验。
SymPy 库为我提供了一种处理许多排列组属性的好方法,因此我将它包含在我计算排列奇偶性的尝试中。
它应该成功时失败的最简单的测试输入是立方体的后转,表示为 B。
这是代码:
def check_permutation_parity(cube):
corners = cube[:24]
edges = cube[24:]
edges = [e - 24 for e in edges]
corner_perms = corner_perms_only(corners)
edge_perms = edge_perms_only(edges)
normalized_corners = [int(c/3) for c in corner_perms]
normalized_edges = [int(e/2) for e in edge_perms]
sympy_corners = Permutation(list(normalized_corners))
sympy_edges = Permutation(list(normalized_edges))
corners_perm_parity = Permutation(list(normalized_corners)).parity()
edges_perm_parity = Permutation(list(normalized_edges)).parity()
if corners_perm_parity != edges_perm_parity:
return False
return True
使用一堆打印语句,我概述了整个代码中发生的情况:
这是初始状态。这是立方体的 B 排列,看起来和预期的一样。
cube:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 20, 12, 13, 14, 21, 22, 23, 15, 16, 17, 24, 25, 26, 27, 30, 31, 28, 29, 32, 33, 36, 37, 34, 35, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47)
接下来我们看看角落和边缘。请记住,每个边缘都减去了 24。这对于最终转换为 SymPy 排列是必要的。
corners, edges
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 20, 12, 13, 14, 21, 22, 23, 15, 16, 17)
[0, 1, 2, 3, 6, 7, 4, 5, 8, 9, 12, 13, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
然后我们只提取每 3 个角和每 2 个边。这让我们只看每个部分的排列,因为我们不关心方向。
corner_perms_only, edges_perms_only
(0, 3, 6, 9, 18, 12, 21, 15)
(0, 2, 6, 4, 8, 12, 10, 14, 16, 18, 20, 22)
然后我们按 2 或 3 占卜以转换为 SymPy
normalized_corners, edges
[0, 1, 2, 3, 6, 4, 7, 5]
[0, 1, 3, 2, 4, 6, 5, 7, 8, 9, 10, 11]
转换为 SymPy 后,角落看起来像这样:
sympy corners
(4 6 7 5)
[(4, 5), (4, 7), (4, 6)]
[[0], [1], [2], [3], [4, 6, 7, 5]]
边缘看起来像这样:
sympy edges
(11)(2 3)(5 6)
[(2, 3), (5, 6)]
[[0], [1], [2, 3], [4], [5, 6], [7], [8], [9], [10], [11]]
给我们这个奇偶校验,因为角由 3 个周期组成,边缘由 2 个周期组成:
角、边等价
1
0
因为奇偶校验不同,所以函数返回 false。
B:错误
我们知道奇偶校验应该匹配,但我无法得到这个结果,而且我有点迷失在哪里进行进一步的调试。所有代码都可以在我的 GitHub 上找到:https ://github.com/elliotmartin/RubikLite/blob/master/Rubik.py
解决方案
我的问题与 SymPy 和排列奇偶校验无关。为了检查这一点,我实现了自己的循环分解算法,然后检查了奇偶校验。最后,问题与我如何为每一步设置排列有关。
我想我已经学到了很多关于测试的知识——如果你的测试没有测试正确的东西,那么它们就没有那么有用了。
推荐阅读
- scala - 使用 Scalatest 测试 ScalikeJDBC Publisher
- php - 是否可以使用 EntityManagerInterface 类基于两个外键创建查询?
- java - 特定位置的recycleview setadapter
- pypy - 在 Windows 10 Enterprise 上运行 PyPy3 的问题
- json - 为什么我的 JSON 函数无法识别我的 .createElement 按钮?
- sql - SQL 存在于 TableA 或 TableB 中
- r - 具有多个类的 pivot_longer 会导致错误(“No common type”)
- python - IMDbPy:如何捕捉 IMDbDataAccessError?
- excel - 从一个表复制到另一个表 (VBA)
- javascript - 如何获取 PHP 日期和当前 JS 日期之间经过的时间