Algorithm 如何实施Thistlethwaite';Haskell中的s算法?
我试图在Haskell中实现Thistlethwaite算法,遵循找到的描述,但遇到了困难 到目前为止,我已经成功地表示了立方体,让它随心所欲地移动,并在终端上显示它(二维表示),但当我试图将一个普通立方体简化为一个可以通过组中的移动(R、L、F、B、U2、D2)(如链接中所示的符号)从标准立方体中获得的立方体时,遇到了问题,因为有太多的情况需要考虑:上层有多少颜色方向错误,中间层有多少颜色错误,等等。这只是描述中的第一个阶段,但我发现我的代码已经很混乱,所以我一定错过了什么 由于我不确定上面的描述是否清楚,我在下面列出了相关代码,这些代码不正确,但指出了问题所在Algorithm 如何实施Thistlethwaite';Haskell中的s算法?,algorithm,haskell,Algorithm,Haskell,我试图在Haskell中实现Thistlethwaite算法,遵循找到的描述,但遇到了困难 到目前为止,我已经成功地表示了立方体,让它随心所欲地移动,并在终端上显示它(二维表示),但当我试图将一个普通立方体简化为一个可以通过组中的移动(R、L、F、B、U2、D2)(如链接中所示的符号)从标准立方体中获得的立方体时,遇到了问题,因为有太多的情况需要考虑:上层有多少颜色方向错误,中间层有多少颜色错误,等等。这只是描述中的第一个阶段,但我发现我的代码已经很混乱,所以我一定错过了什么 由于我不确定上面的
--To intersect lists, of which the sizes are not very large, I chose to import the Data.List
import Data.List
--Some type declarations
data Colors = R | B | W | Y | G | O
type R3 = (Int, Int, Int)
type Cube = R3 -> Colors
points :: [R3] --list of coordinates of facelets of a cube; there are 48 of them.
mU :: Cube -> Cube --and other 5 moves.
type Actions = [Cube -> Cube]
turn :: Cube -> Actions -> Cube --chains the actions and turns the cube.
edges :: [R3] --The edges of cubes
criterion :: Colors -> R3 -> Bool -- determine if the edges are mis-placed.
criterion co p@(x, y, z) = case co of --W and Y are up and down faces respectively.
R -> not (or [abs(x) == 3, abs(y) == 3])
B -> not (or [abs(y) == 3, abs(z) == 3])
O -> not (or [abs(x) == 3, abs(y) == 3])
G -> not (or [abs(y) == 3, abs(z) == 3])
_ -> True
stage1 :: Cube -> Cube
stage1 c = turn c opes where
wrongs = do
res <- [[]]
eg <- edges
if criterion (c eg) eg
then res
else res ++ [eg]
ups = filter (\(x, y, z) -> y == 3) points
downs = filter (\(x, y, z) -> y == -3) points
middles = filter (\(x, y, z) -> y == 0) points
opes = do
res <- [[]]
case length (intersect middles wrongs) of
0 -> case [length (intersect ups wrongs) == 0, length (intersect downs wrongs) == 0] of
[True, True] -> res
[True, False] -> [mD] --A quarter turn of the downside of the cube.
[False, True] -> [mU]
_ -> [mD, mU]
1 -> let [(x, y, z)] = intersect middles wrongs in
if x == 3 then case [length (intersect ups wrongs) == 0, length (intersect downs wrongs) == 0] of
[True, True] -> if z > 0 then [mR, mU] else [mR, mD]
[True, False] -> if z > 0 then [mD, mR, mU] else [mD, mR, mD]
[False, True] -> if z > 0 then [mU, mR, mU] else [mU, mR, mD]
_ -> if z > 0 then [mD, mU, mR, mU] else [mD, mU, mR, mD]
else []
——为了使列表相交(列表的大小不是很大),我选择导入数据。列表
导入数据。列表
--一些类型声明
数据颜色=R | B | W | Y | G | O
类型R3=(Int,Int,Int)
键入Cube=R3->Colors
点::[R3]——立方体的facelet坐标列表;其中有48个。
mU::Cube->Cube--和其他5个动作。
类型操作=[Cube->Cube]
turn::Cube->Actions->Cube--链接操作并旋转立方体。
边::[R3]--立方体的边
标准::颜色->R3->布尔--确定边缘是否放置错误。
标准co p@(x,y,z)=--W和y的情况co分别为上下两个面。
R->not(或[abs(x)==3,abs(y)==3])
B->not(或[abs(y)==3,abs(z)==3])
O->not(或[abs(x)==3,abs(y)==3])
G->not(或[abs(y)==3,abs(z)==3])
_->对
阶段1::多维数据集->多维数据集
第1阶段c=第c轮运营商,其中
错误=做
res y==-3)点
中间点=过滤器(\(x,y,z)->y==0)点
opes=do
res案例[长度(上下相交错误)==0,长度(上下相交错误)==0]
[对,对]->res
[True,False]->[mD]——立方体下侧的四分之一圈。
[假,真]->[mU]
_->[mD,mU]
1->让[(x,y,z)]=在
如果x==3,则案例[长度(向上相交错误)==0,长度(向下相交错误)==0]
[True,True]->如果z>0,则[mR,mU]else[mR,mD]
[True,False]->如果z>0,则[mD,mR,mU]否则[mD,mR,mD]
[假,真]->如果z>0,则[mU,mR,mU]否则[mU,mR,mD]
_->如果z>0,则[mD,mU,mR,mU]else[mD,mU,mR,mD]
其他[]
然后我意识到上面的代码是错误的,因为我不能简单地做四分之一的U或D,这使得正确的边(如果有的话)变得不正确,我将根据立方体三层上每层有多少错误边来讨论125=5*5*5的情况,我认为这不是“正确的”
所以我的问题是如何实现一个算法,能够以一种好的方式处理如此多的情况
如果描述不清楚,请告诉我,以便我能解释我在做什么,我的问题是什么
非常感谢您的任何想法和建议,非常感谢
另外,我原本想实现Korf或Kociemba的算法,但结果证明我甚至不能处理最简单的情况。一件事-这段代码:
wrongs = do
res <- [[]]
eg <- edges
if criterion (c eg) eg
then res
else res ++ [eg]
错误=do
res如果没有相应的类型声明,就很难理解发生了什么。@MathematicalOrchid是否有我忘记添加的内容,或者不清楚的内容?同样感谢您的关注。一般来说,您应该避免将==
与浮点运算结合使用。将所有坐标乘以2并使用整数运算。@user5402我已经更改了,谢谢你指出它。谢谢你的提示。你认为IDA*算法会起作用吗?