魔方吧 关注:511,561贴子:11,825,716

回复:魔方还原算法(二)科先巴的二阶段算法

只看楼主收藏回复

四、对称
魔方是一个高度对称的物体,我们可以利用对称性来减少时间空间上的开销。
对称的形式有 4 种基本情况,原本状态,只颜色变化,只位置变化,镜像。

它们都是等价的,如果我们能解决其中一个,就能解决其他的,只要在解法上加上相应的对称变化即可。
来看一个同位置不同颜色的例子,看看原状态经过怎样的变化后得到的一种等价状态:
假如对还原状态的魔方进行 A(一个转动序列) 操作得到如下状态:

我们要得到它的一个等价状态,进行如下操作,还原状态先绕 UD 轴逆时针转动 90°,再做 A 操作,最后绕 UD 轴顺时针转动 90°。

看到这大家有没有联想到什么,是不是很像矩阵的相似变换,有一些还原算法就是把魔方存成矩阵的形式,魔方变换就是相应的矩阵变换,道理都是相通的。
Ⅰ 对称变换
① 基本变换
上述的一些等价形式都是通过对称变换得来的,对于每个状态加上自己有 48 种变换形式,一般来说每个状态也就有 48 种等价形式,它们都是由 4 种“基本对称”组合而成:
1. S_U4:围绕 UD 这个轴转动 90°,4 种
2. S_F2:围绕 FD 这个轴转动 180°,2 种
3. S_URF3:围绕 URF 这个角块转动120°,3 种
4. S_LR2:关于 LR 层的镜像,2 种
合起来 4*2*3*2=48 种
具体怎么转动的我就不具体画图表示了(唉主要是变换的 3D 制图太难了,尝试了一下,效果不好,见谅),既然是变换操作,所以对称变换还是可以用状态的块层次来表示,具体来看 4 种基本对称变换的定义,从块的替代关系中应该就能理解具体是怎么变换的了。

48 种对称变换操作初始化也很容易,4 个 for 循环,调用 multiply 函数进行复合操作,得到的结果填到 symCube[48] 数组里面去,这里就不赘述重复操作了。
注意上面的镜像变换,定义角块方向变化全部加 3 ,也就是说镜像的角块方向取值为 [3,5]。
② 逆变换
上述为了得到等价状态做了两次对称变换,两种变换互为逆过程,群论里面叫做互为逆元,我们这需要为每一个对称变换找到它们对应的逆变换。
那怎么得到相应的逆变换?在群论里面互逆的两个元素复合操作等于幺元,也就是相当于乘法里面的互为倒数的两个数相乘为 1,而在魔方里面还原状态就是幺元就是那个 1 。所以我们只要对 48 个变换进行两两复合操作,看结果是否达到还原状态即可。

Ⅱ 等价

因此对于每种状态我们只需要记录属于哪一个集合(行号),所使用的对称变换(列号) ,这么一个集合我们称为等价类。如此一来就可以省下很多空间和时间,因为存的信息少了,搜索的状态空间也少了。在科先巴的二阶段算法里,保持了 UD 轴不动,所以只用到了 16 种对称变换。
加入一个状态属于等价类 y ,使用的对称变换为 i,那么我们就可以用新坐标 y*16+i 来描述原状态。但是并不是每个等价类里面都有不同的 16 种状态,也就是说不是每个状态都有 16 种不同对称状态。比如说有等价类 y y 和对称变换 i,j,y*16+i 与 y*16+j 是有可能描述的同一个状态的。这个在后面剪枝部分还会再说明
关键问题在于我们如何得知一个坐标它属于哪一个等价类,使用的是哪一个对称变换?直接来看伪码分析:

Ⅲ 对称变换表
上述的代码里面已经使用过了,类似前面的转动表,对称变换,转动都是变换操作,转动有转动表,对称变换也得有相应的变换表。比如定义以下的表:

具体的初始化操作同转动表,都是建立在状态的复合操作之上,以角块方向的对称变换表举例说明:

源程序里面命名用的是 conjugate 这个词,共轭,我这儿直接用的 Sym 来说明,私以为可能更直观一些。
这部分讲述对称性,根据篇一种计算的状态数我们知道,一个三阶魔方的状态数多到爆炸,但还好魔方是个高度对称的物体,我们可以使用对称性来减少计算量。下一部分算法核心:剪枝


IP属地:北京20楼2021-09-21 13:37
回复
    @哀木涕🔥 申请一个精品贴


    IP属地:北京来自Android客户端21楼2021-09-21 22:55
    回复
      直接膜


      IP属地:四川来自Android客户端22楼2021-09-22 09:53
      回复


        IP属地:上海来自Android客户端23楼2021-09-23 09:48
        回复


          IP属地:美国来自iPhone客户端24楼2021-09-23 17:59
          回复
            膜,建议加精


            IP属地:上海来自iPhone客户端25楼2021-09-24 17:30
            回复
              看不懂


              IP属地:山东来自Android客户端26楼2021-09-24 17:58
              回复


                IP属地:天津来自Android客户端27楼2021-10-05 11:56
                回复
                  6


                  IP属地:福建来自Android客户端28楼2021-10-31 22:50
                  回复


                    IP属地:广东来自Android客户端29楼2021-11-04 10:48
                    回复


                      IP属地:北京来自Android客户端32楼2021-12-03 21:28
                      回复
                        阿巴阿巴


                        IP属地:山东来自Android客户端33楼2021-12-05 11:13
                        回复
                          看傻了


                          来自Android客户端34楼2022-01-25 16:26
                          回复
                            还得学js是吧


                            IP属地:湖北来自Android客户端35楼2022-02-06 08:53
                            回复