一个基本的,purePython魔方解算器

rubik-cube的Python项目详细描述


概述

这是一个(3x3)魔方解算器的Python3实现。在

它包含:

  • 立方体的简单实现
  • 遵循固定算法的解算器
  • 一种非智能解序列优化器
  • 一组像样的测试用例

安装

包托管在PyPI上。在

pip install rubik-cube

rubik包导入

^{pr2}$

实施

这个实现的基石是Piece类。一件装两件 信息条:

  1. 一个整数position向量{},其中每个分量都在{-1,0, 1} 公司名称:

    • (0, 0, 0)是立方体的中心
    • 正x轴指向右侧
    • 正y轴指向上表面
    • 正z轴指向前面
  2. 一个colors向量(cx, cy, cz),给出每个贴纸的颜色 轴心国。当工件的边少于三个时,就放空值。为 例如,带有colors=('Orange', None, 'Red')的片段是具有 'Orange'面向x方向的贴纸和面向 z方向。工件不知道或不关心x轴的哪个方向 'Orange'贴纸是面向的,只是它面向x方向 不是y或z方向。在

使用positioncolor向量的组合使 通过其绝对位置或其独特的 颜色。在

一个工件提供了一个方法Piece.rotate(matrix),它接受(90度) 旋转矩阵。矩阵向量乘法是用来更新工件的 position向量。然后我们更新colors向量,只需交换两个 colors向量中的条目:

  • 例如,一个角落有三个不同颜色的贴纸。之后 旋转90度,一个贴纸保持朝下不变 轴,而其他两个贴纸交换轴。这对应于交换 工件colors向量中两个条目的位置。在
  • 对于一个边或面片,论证与上面相同,尽管我们可以 交换一个或多个空项。在

立方体

Cube类建立在Piece类之上。多维数据集存储 为翻转立方体的切片提供了很好的方法,以及 查询当前状态的方法。(我遵循标准Rubik's Cube notation

因为Piece类封装了所有的旋转逻辑,实现了 Cube类中的旋转非常简单-只要应用适当的 旋转矩阵到所有涉及旋转的工件。例如:到 执行Cube.L()-左表面顺时针旋转-执行 以下内容:

  1. x = -1平面。在
  2. 选择满足position.x == -1的所有工件。在
  3. 将旋转矩阵应用于每个片段。在

实现Cube.X()-整个立方体围绕 正x轴-只需对存储在 立方体。在

解算器

求解器实现所描述的算法 herehere。它是一个 逐层解决方案。首先求解前面(即z = 1平面), 然后是中间层(z = 0),最后是底层(z = -1)。什么时候? 解算器完成,Solver.moves是表示解决方案的列表 顺序。在

我的第一个正确的解决方案实现平均每252.5步 135000个随机生成的立方体的解序列(没有失败)。 实现一个哑优化器将平均移动次数减少到192.7 67000个随机生成的立方体。优化器执行以下操作:

  1. 通过“取消旋转”移动(Z U L D Zi变成 L D R)
  2. 消除后接倒数的移动(R R Ri Ri消失)在
  3. 将重复三次的动作换成相反的单圈 方向(R R R R变成Ri)

解算器不是特别快。在我的机器(4.0 Ghz i7)上,需要 在CPython上,每次解算大约0.06秒,大约是16.7次解算/秒。 在PyPy上,每次解题时间减少到大约0.013秒,或者大约76秒 解数/秒。在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Hibernate:jpamodelgen生成java而不是类   java如何在第二次活动结束后显示广告?   javascript如何在linux或windows上将java导出到jar   java One ArrayList添加了2个不同的选项   AmazonWeb服务如何在java中使用AWS Textract检索pdf中存在的表   java为什么RecycleView中的水平项在单击时不起作用?   java计算如果存在映射   java在捕获的组上应用正则表达式   如何使用Java在MySQL的同一个表中插入来自不同类的值   java字符串中最常见的字母(大写和小写)   Spring SessionBean实例正在由java中的多个用户共享   使用Spring Boot将@WebInitParam中的值外部化   java一创建线程就开始执行(多线程)   java是安卓所需的系统权限。意图行动给你打电话?