魔方如何自动求解?

                         

魔方如何自动求解?


  • zzwu
  • (未名)
  • 等 级:
  • 结帖率:
  • 10

    6

    8

楼主发表于:2005-06-13 15:44:11
我编了一个魔方游戏,可给大家玩,并要给玩家们打分,打分依据规则是: 

统计他玩魔方时,由魔方初始状态转动到6面清一色状态,一共用了几步,
步骤愈少分数愈多,步骤最少给全分,否则只给部分分数。 

为此,给分程序必须算出魔方由任意一种随机产生的初始状态出发,转动
到6面清一色状态,所需的最少步数。 

 
 


  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#1楼 得分:0回复于:2005-06-13 15:56:35
我给魔方的初始布局是用10-20步的随机转动产生,转动前的状态不确定。 

因每一步可以有12种选择(6个面,每面可正转或反转), 

这样最多可以有12的20次方可能, 

可行解数目很大,看来无法穷举。
 
  • NowCan用户头像
  • NowCan
  • (城市浪人)
  • 等 级:
#2楼 得分:0回复于:2005-06-13 18:23:02
魔方倒是有固定的解法,但最少步数解就不知道了。
 
  • mysword用户头像
  • mysword
  • (剑客无名)
  • 等 级:
#3楼 得分:0回复于:2005-06-13 19:18:51
启发式搜索吧
 
#4楼 得分:0回复于:2005-06-13 21:11:21
最少步数基本不会超过20步
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#5楼 得分:0回复于:2005-06-14 10:58:07
jerryy()   : 

  "最少步数基本不会超过20步 "的结论能证明吗?
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#6楼 得分:0回复于:2005-06-14 11:16:02
最少步数不超过20步?怀疑? 
个人认为求出最优解是几乎不可能的
 
  • NowCan用户头像
  • NowCan
  • (城市浪人)
  • 等 级:
#7楼 得分:0回复于:2005-06-14 13:14:53
http://cdtzx.swiki.net/35 
这里有一个解魔方的,Prolog语言的。
 
#8楼 得分:0回复于:2005-06-14 13:55:23
http://www.ws.binghamton.edu/fridrich/cube.html 
http://mf8.nease.net/index.htm 
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#9楼 得分:0回复于:2005-06-14 21:52:09
谢谢各位提供的信息,待我仔细去研究研究。 


我现在想到了一个办法,理论上看来是行的,但实际是否行还无法确定: 

1.预先找出所有状态的最优解的步数(即最少步数), 

2.将所有最优解排序后,用“状态-步数”的形式保存在一文件中; 

3.以后遇到玩家的具体状态时,只要查一下表就行了。 


找所有状态及其最优解的算法我已经想好了(不难)。 

现在的问题是:魔方的状态数目(N)总共有多大?如何估计其数量级的较确切的上限? 


 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#10楼 得分:0回复于:2005-06-14 22:07:06
我考虑,魔方6个面的中间一块相对位置不变,而 8  个角块和12 个边块则可以
任意改变位置, 这样可否用公式 
  
    N   =   8*12!
        =   40320  *  479001600   

来估算?其中8!代表8个角块的全排列,12!代表12个边块的全排列. 

如果这样,则  N  近似为20万亿,或20000G,   就实际不可行了。 

  
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#11楼 得分:0回复于:2005-06-15 07:16:31
呵呵,实际上上面状态应该只有1/6可以到达,我们可以除以6. 
但是除了状态以外,我们还要考虑状态之间转移的情况(也就是图中边的数目),
对于模仿来说,应该是每个状态可以转移到十几个其他状态吧,所以总共边的数
目需要在乘上十几这样看来,还行还行,也就100万亿左右,可能再过十数年计算
就可以穷举了:)
 
  • fxw用户头像
  • fxw
  • (漂来)
  • 等 级:
#12楼 得分:0回复于:2005-06-15 13:05:10
Finding   Optimal   Solutions   to   Rubik 's   Cube 
Using   Pattern   Databases 
Richard   E.   Korf 
Computer   Science   Department 
University   of   California,   Los   Angeles 
Los   Angeles,   Ca.   90095 

Rubik 's   Cube,   invented   in   the   late   1970s   by   Erno   Ru- 
bik   of   Hungary,   is   the   most   famous   combinatorial   puz- 
zle   of   its   time.   The   standard   version   
consists   of   a   3x3x3   cube,   with   different   colored   stick- 
ers   on   each   of   the   exposed   squares   of   the   subcubes,   or 
cubies.   Any   3x3x1   plane   of   the   cube   can   be   rotated 
or   twisted   90,   180,   or   270   degrees   relative   to   the   rest   of 
the   cube.   In   the   goal   state,   all   the   squares   on   each   side 
of   the   cube   are   the   same   color.   The   puzzle   is   scram- 
bled   by   making   a   number   of   random   twists,   and   the 
task   is   to   restore   the   cube   to   its   original   goal   state. 
The   problem   is   quite   diffcult.   That   there   are   billions   of 
combinations,   is   a   considerable   understatement.   In 
fact,   there   are   4.3252*10^19   different   states   that   can   be 
reached   from   any   given   configuration.   By   comparison, 
the   4x4   Fifteen   Puzzle   contains   10^13   states,   and   the 
5x5   Twenty-Four   Puzzle   generates   10^25   states. 
To   solve   Rubik 's   Cube,   one   needs   a   general   strategy, 
which   usually   consists   of   a   set   of   move   sequences,   or 
macro-operators,   that   correctly   position   individual   cu- 
bies   without   violating   previously   positioned   ones.   Such 
strategies   typically   require   50   to   100   moves   to   solve   a 
randomly   scrambled   cube.   It   is   believed,   however,   that 
any   cube   can   be   solved   in   no   more   than   20   moves. 
We   address   the   problem   of   finding   a   shortest   se- 
quence   of   moves   required   to   solve   a   given   problem 
instance.   As   far   as   we   have   been   able   to   determine, 
optimal   solutions   to   random   instances   have   not   been 
found   previously.   We   generated   ten   random   problem 
instances,   and   solved   them   all   optimally.   One   was 
solved   in   16   moves,   three   required   17   moves,   and   the 
remaining   six   were   solved   in   18   moves. 

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#13楼 得分:0回复于:2005-06-16 12:35:16
看来对魔方的了解还有不少问题,例如, 

*   状态总数的估算问题, 

*   最优解的最大步数问题, 

*   寻找最优解方法的实际可行性问题, 

似乎都还没有结论。 


 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#14楼 得分:0回复于:2005-06-16 12:54:47
Richard   E.   Korf文章说,状态总数有 

    8!*3^8*12!*2^12/12   =   4315   200   2744   8985   6000 

其中   
          8!代表8个角块的全排列, 
          3^8(3的8次方)代表8个角块的3种朝向 
          12!代表12个边块的全排列. 
          2^12(2的12次方)代表12个边块的2种朝向 

也就是说,当魔方26个可见块中25块固定下来时,剩下的那块的朝向还不能确定! 

这种情况可能吗? 

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#15楼 得分:0回复于:2005-06-16 12:57:11
Richard   E.   Korf文章说,状态总数有 

    8!*3^8*12!*2^12/12   =   4315   2003   2744   8985   6000   (4315亿亿!) 

其中   
          8!代表8个角块的全排列, 
          3^8(3的8次方)代表8个角块的3种朝向 
          12!代表12个边块的全排列. 
          2^12(2的12次方)代表12个边块的2种朝向 

也就是说,当魔方26个可见块中25块固定下来时,剩下的那块的朝向还不能确定! 

这种情况可能吗? 


 
#16楼 得分:0回复于:2005-06-16 13:03:21
找最少次数的解恐怕不行,因为初始状态决定了最少解的数量 

前面提供的网站当中列举的也是最短时间解决问题的世界记录 

上面提供的多种解决方法,都是针对任意的情况的 

从方法到程序实现,要走的路太长了 

本人也曾经用dx7做了个3d魔方的游戏,太难玩了,没有考虑用程序实现自动求解。 
 
  • mmmcd用户头像
  • mmmcd
  • (超超)
  • 等 级:
#17楼 得分:0回复于:2005-06-16 14:38:20
这有自动求解的程序: 
http://notabdc.vip.sina.com/Solver/rubiccube.htm
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#18楼 得分:0回复于:2005-06-16 14:46:57
happy__888([顾问团]寻开心)   : 

我也和你同感,玩软件魔方没有玩真魔方来的不便。 

如何改进人机界面,这看来是一个值得进一步深入研究的问题。 

 
#19楼 得分:0回复于:2005-06-16 15:55:33
呵呵,这个界面是太难做了。 
这个难不是实现一个三维浏览难,主要是操作上的那种感觉不对 

玩魔方实物的时候,不仅仅有视觉,还有手上的触觉 
通过手上的感觉可以快速的转过去,调整一个下,再转回来 
而在软件当中,只能凭借视觉,经常转几下后需要换方向看,结果一换方向原来
的感觉都没有   :( 

当时借助我们自己开发的三维游戏引擎,可以快速的看到魔方的每个面,有快捷
键可以快速定位到某个面上,也在各个面用不同的色以及文字做了标注,但是玩
起来,三转两转还是找不到方向,自己看着都晕。 
初始化状态用软件实现到是简单,各个方向随机的旋转几十次就混乱了(ps   当
时投机取巧,记录这个旋转顺序,以及用户的旋转次序,所以很容易的复原;但
是没有考虑自动复原的方法)
 
  • NowCan用户头像
  • NowCan
  • (城市浪人)
  • 等 级:
#20楼 得分:0回复于:2005-06-16 18:30:14
回复人:   mmmcd(超超)   (   )   信誉:124     2005-06-16   14:38:00     得分:   0     
  
  
      这有自动求解的程序: 
http://notabdc.vip.sina.com/Solver/rubiccube.htm 
    
  
==求解程序是有,源码也见过。但是没证明那就是最少步数解,这个要求可不容易。
 
  • fxw用户头像
  • fxw
  • (漂来)
  • 等 级:
#21楼 得分:0回复于:2005-06-16 18:52:55
to   zzwu(未名)   : 

> >   Richard   E.   Korf文章说,状态总数有 
> >   
> >       8!*3^8*12!*2^12/12   =   4315   2003   2744   8985   6000   (4315亿亿!) 
> >   
> >   其中   
> >             8!代表8个角块的全排列, 
> >             3^8(3的8次方)代表8个角块的3种朝向 
> >             12!代表12个边块的全排列. 
> >             2^12(2的12次方)代表12个边块的2种朝向 
> >   
> >   也就是说,当魔方26个可见块中25块固定下来时,剩下的那块的朝向还不能确定! 
> >   
> >   这种情况可能吗? 


当然不可能,玩过魔方的都知道,所以他除了个   12   啊!!!! 

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#22楼 得分:0回复于:2005-06-17 15:27:41
fxw(漂来): 
  谢谢你的提示,漏看了分母12 
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#23楼 得分:0回复于:2005-06-17 15:30:06
文章后面也提到了这一点。
 
#24楼 得分:0回复于:2005-06-19 21:03:51
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#25楼 得分:0回复于:2005-06-21 09:02:43
Richard   E.   Korf的文章所介绍的算法不能保证得到最优解,因为,它把整个
优化过程分成三阶段来完成:先是调整8个角块的位置和朝向,这时它不考虑
边块的位置和朝向。然后是分2次,每次6块,来调整总共为12个边块的位置
和朝向。这样的过程使本来完全无法寻找最优解的问题可以寻找了,但所得
结果通常只能是子优解,而不可能是一个最优解。 

我现在决定不采用这种方法,而是采用我上面提到的能保证获得最优解的方
法,我的方法的缺点是不可能对任意状态确定其最优解所需的步数,但可以
保证为至少需要N步能解出的所有状
态快速寻找最优解。N究竟有多大还不清楚,我估计N=10是可能的。这样的
状态总数已经非常大了(12^10数量级),我可以从其中随机找一些状态作为
初始状态,要求玩者来人工寻求将魔方复原的最优解,这样已经是够难够有
趣的了。 


 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#26楼 得分:0回复于:2005-06-21 09:32:18
我原来也是采用happy__888的办法:在旋转魔方时,记录其旋转过程及步数,然后, 

  *   若用户完成时的步数达到我用的步数时就给满分, 
  *   若用户完成时的步数大于我用的步数就给部份分数, 
  *   而用户完成时的步数小于我用的步数就给超额的分数, 

计算公式是 

            n   *(我用的步数/用户完成时的步数), 

其中n为基本分,和题目难度有关。 

这种方法对于人工精心设计的题目是可行的,但用随机产生的状态就很不合适,因为很可
能出现极容易超分的求解状态。
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#27楼 得分:0回复于:2005-06-21 10:03:43
happy__888:“但是玩起来,三转两转还是找不到方向,自己看着都晕”, 

我所用的办法是: 

*   用4个方向键来控制魔方的整体旋转, 

*   用I键(Initial)快速恢复到原始视角, 

*   用V键(View)来实行2d-3d视图切换 

我在网上看到有人用镜面反射的方法来显示3个隐藏面,这样就用不到整体转动魔方了。 
但看到反射状态不是很习惯,另外,加了3个反射镜后,软件的画面形状显得有点乱。 

也有人把2d和3d的视图同时在窗体中画出来,但同样有上面所说的一些缺点。 


 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#28楼 得分:0回复于:2005-06-21 11:05:44
能否利用鼠标而不是键盘控制魔方的转动? 
利用键盘方向键控制也可以,比如可以要求用户按下一个方向的键不放,然后魔方在那里慢
慢的转动(速度不能太快,不然会眼花的),用户释放了键,魔方就停止转动.   主要是魔方的转
动要慢,而且能否产生动画效果,而不是直接从一个方向变化成另一个方向,那样用户肯定很
不适应的. 

用户对魔方变化的操作你用的是什么方法呢,总共有12种操作呀
 
  • fxw用户头像
  • fxw
  • (漂来)
  • 等 级:
#29楼 得分:0回复于:2005-06-21 17:49:54

zzwu(未名)   : 

> >   每一步可以有12种选择(6个面,每面可正转或反转) 
> >   我估计N=10是可能的。这样的状态总数已经非常大了(12^10数量级) 


我认为使用“每面可正转或反转”的模型是不妥的 

设   
        F     为某层正转(顺时针转动90度) 
        F '   为某层反转(逆时针转动90度) 
则 
        F   F '   对魔方状态是没有影响的, 
        F '   与   F   F   F   是等价的。 
        所以使用这种模型对10次转动来说, 
        首先状态数并不是   12^10, 
        其次随机生成状态则比较麻烦: 
        如果不管上边提到的情况,则程序就失去了严密性, 
        使随机生成的状态有可能根本就是原始状态... 


我建议使用一种通用的模型: 
        设某面(层)为F 
        F可以“顺时针转动90度”(记为F)、“逆时针转动90度”(记为F ')和“转动180度”(记为F2) 
        这样对一个转动序列来说,两个相邻的转动在不同的面上进行 
        对于生成随机序列来说要方便得多 
        同时也不难算出这样的   10   次转动,存在的状态数为: 
        6   *   5^9   *   3^10   =   691980468750 


 
#30楼 得分:0回复于:2005-06-21 18:07:29
在理论上来说,最优——最少步骤的解一定是存在的 
前面已经讨论了魔方的不同状态到底有多少 
我们如果从转到的可行性方向来考虑的时候,可以把所有的状态用一个数据结构——图来表示 

假定用图来表达魔方的所有的状态(每个状态下,魔方的姿态可以是任意的), 
我们可以看到的是,每个状态下有27种不同的转动方式: 
      三个转轴(不看6个面,都可以分解到这三个转轴上进行) 
      每个转轴上可以转动三个不同的层 
      每个层可以转动3个不同的角度; 
这样就是说图的每个节点上有27条路径(不重复的),连接到其他的结点 

按照图的理论,任意的一个初始状态,都可以找到对应的终止状态的最优路径的——图上两点之间的最短路径。 

有解到求解的过程太艰巨:   构造这个完整的图的空间太庞大了 
 
  • fxw用户头像
  • fxw
  • (漂来)
  • 等 级:
#31楼 得分:0回复于:2005-06-21 18:09:09

这样 
第一步有   6*3   =   18   种选择,以后各步有   (6-1)   *   3   =   15   种选择 
则   10   步的状态数也可表示为 
18   *   15^9 
 
#32楼 得分:0回复于:2005-06-21 18:40:36
按照27叉树的理论,如果最短解决方案需要n步骤 
那么搜索的长度就是27^N步骤 

如果n=100,   那么需要的计算量是大概是   
    100*lg27   近似   145   也就是10^145   次计算 

尽管计算量很大,但是可以构造出非递归的算法来实现 

因为每个状态上只有27种不同的操作,那么可以用一个32位的整数来表示操作的类型 
假定需要100步 
那么做一个长度是100的32位整数的数组就可以记录每次的操作顺序了 
写一个遍历的算法,可以完成所有的步骤的枚举 

我们可以从初始的状态6个面全部合理的时候出发,开始搜索,结束的条件就是经过了n步骤后,结果和我们目前的状态一致。 
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#33楼 得分:0回复于:2005-06-22 09:11:49
10^145是个不可能完成的任务. 
让我们考虑一下整个宇宙的尺度,现在已知范围大概在100亿光年的范围. 
100亿光年是 
100*10^8*365.24*24*3600   秒*3*10^8   米/秒=9.467*10^25米=9.467*10^35纳米 
所以整个宇宙体积大概为8.4848*10^107立方纳米 

假设每个立方纳米的空间都有一个原子(好密呀:)   ), 
现在所有的原子都开工工作,工作频率都是10G(每秒10^9次),每个时钟周期完成一个计算, 
所以1秒钟,宇宙所有的原子总共完成了8.4848*10^116个计算,要完成10^145个计算,需要 
1.1786*10^28秒=3.7348*10^20年就是将近4亿亿年 
而现在地球的寿命也仅仅40亿年,上面时间是现在地球寿命的一千万倍:) 
 
#34楼 得分:0回复于:2005-06-22 11:57:19
呵呵,只要是有限的步骤可以完成任务就还是符合算法的定义的,   :( 

对于这个图的结构可以采用先广的方法来搜索,如果最少的步骤是n步 
那么搜索需要的计算量就是27^N步 

即便N=10,   那总的量也是   10   ^   15   左右 

这个问题本来就是难解,在那个魔方吧上提供的5种解法都是机械式的
 
  • Tranquillo用户头像
  • Tranquillo
  • (晚起的鸟儿找虫吃)
  • 等 级:
#35楼 得分:0回复于:2005-06-22 14:30:40
我觉得这个问题要求最优解不容易,比楼主关心的魔方初始状态数目更难,但是用遗传算法
应该可以得到较满意的解
如果楼主找到了求最优解的方法,那可以对每一种初始状态即时求解呀,用不着预先把所有
的解都求出来。能介绍一下你求最优解的方法吗?
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#36楼 得分:0回复于:2005-06-22 14:34:30

to   mathe:   

“让魔方慢慢转动” 

   我原来用方向键控制整体转动时,如果按住不放开魔方也就连续转动,我一次旋转角度不是 
   很大,但也不是很小,太小怕受不了,太快怕弄糊涂,采用了一次转45度的折衷办法, 

  "能否利用鼠标而不是键盘控制魔方的转动? " 

          我也考虑过,应该没问题,但用什么方式还值的研究。例如 

            *   可以在魔方的图形上操作。 
                这种方式比解直观,缺点是操作起来相当别扭:因为点击一处不能表示转动方向,必须 
                点击2个点或进行拖动,这就麻烦了点; 

            *   设置一些代表转动类型的图标,让用户电击图标来操作魔方。 
                这种方式不够直观,但操作方便,只要点一次,且可以让鼠标-键盘2种操作同时起作用。

            我看到网上的魔方游戏种2种操作类型都有,我更倾向于后面那种。 


“对魔方变化的操作你用的是什么方法“ 

   我用 
    
             Top,Bottom,Left,Right,Front,bAck 
    
      6个单字的中那个大写字母X代表6个面的正向转动,而用复合键alt-X代表对应的逆向转动, 
   这样,转动一次只需要用到一个键。我看到有的软件用T+,T-等2个键,这意义比较清楚,但 
   操作比较麻烦。 


   

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#37楼 得分:0回复于:2005-06-22 15:16:07

to   fxw(漂来)   : 

“每面可正转或反转的模型不妥”, 

“随机生成的状态有可能根本就是原始状态”... 
  
      我知道F+F '等于空操作,FFF=F ',   等等, 

      随机旋转10次所得的状态,可以用0-10次中任意某个次数达到, 

      就是为了避免这种情况,所以我要为随即产生的状态寻找最优解,也就是最短次数。 


“状态数并不是12^10” 
      
  我仅仅用它来作为估计转动10次可能产生的状态数的一个上界,不是一个上确界。     
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#38楼 得分:0回复于:2005-06-22 15:18:01
我觉得可以使用Richard   E.   Korf的文章作为评分的依据. 
对于任意一个可行的状态,使用次文章的方法可以得到一个较优的方法,此方法的步数 
为X, 
而用户总共使用了Y步,我们可以将X/Y*100作为用户的得分
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#39楼 得分:0回复于:2005-06-22 15:40:55
使用happy的计数方法好,可以尽量将一些重复的状态先过滤掉的.(比如FF 'F=F) 
首先总共存在三个方向,分别记为方向X,Y,Z 
每个方向有15种旋转方式,分别记为 
X(u,d),   Y(u,d),   Z(u,d),   0 <=u <=3,0 <=d <=3,但是u,d不同时为0. 
所以总共有45种组合而不是27种组合. 

我们知道,所有连续的X都可以合并,同样,连续的Y,连续的Z都可以合并 
所以我们可以首先产生一个连续的X,Y,Z序列,序列中相邻的两个字母必然不同 
所以长度为N的序列中,总共可以有3*2^(N-1)种序列. 
然后对于每个字母,我们可以有15种不同的旋转方案,所以 
搜索N层总共需要搜索 
3*2^(N-1)*15^N=45*30^(N-1)个状态 
在N=5时,已经需要搜索36,450,000个状态了,基本上无法继续看更多的状态了. 
而对于N=4,需要搜索1,215,000个状态,对于现在的计算机问题不大. 

可以采用双向搜索来增加效率. 
比如对于目标状态(6个单色面的状态),先使用一个长度为10的随机序列打乱魔方, 
得到一个用户初始状态,这个状态最多只需要10步操作可以达到目标状态. 
我们首先搜索所有从目标状态开始的5步之内可以达到的状态,并且保存,这样需要保存 
36.45M个状态在内存中(使用Hash函数) 
然后从用户初始状态开始,同样搜索5步,对于每个形成的状态,同上面36.45M个状态进行比较 
由于使用了Hash函数,可以很快找到是否有相同的状态已经出现 
在搜索了所有状态后,我们必然能够找到最优的解.当然前提是已知这个状态在不超过10步内可解. 
而其中从目标状态开始,使用5步可以达到的状态,可以事先计算出来
 
  • heluqing用户头像
  • heluqing
  • (鉴之小河〖挣大钱娶美女〗)(越)
  • 等 级:
#40楼 得分:0回复于:2005-06-22 15:52:32
老大能不能给出个试玩版的魔方游戏,我想玩玩看,然后会对你的界面和操作
提些建议的,也许你能用的到的...
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#41楼 得分:0回复于:2005-06-22 15:52:57
我这种方法的一步基本上等同于zzwu的一步半(可能同时包含了上下两个面的信息了) 
所以估计只用搜索双向4层就可以超过zzwu上面使用的10步的状态了. 
如果真如jerry所说,20步可以解决,估计双向搜索各8步以内应该能够解决问题 
需要的时间空间复杂度为45*30^7=984,150,000,000=984G,呵呵,估计几年后的计算
机差不多可以覆盖大部分状态了:)
 
#42楼 得分:0回复于:2005-06-22 16:48:11
魔方每次只能围绕三个转轴当中的一个进行旋转,围绕每个轴只有三个可旋转层(同时
转动2层和反向旋转另外一个层是等价的),每层只能旋转三个角度(90,180,270),
这样的计算结果是27种状态 

45种是如何来的?
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#43楼 得分:0回复于:2005-06-22 16:50:52
to   Tranquillo(影子)   : 

"用遗传算法应该可以得到较满意的解 " 

  --     我也考虑过,但如何估算当前状态与目标的距离是一个问题。 

  --     或许可以得到较满意的解,但我需要的必须是最优解。
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#44楼 得分:0回复于:2005-06-22 16:56:08
to   happy__888: 

"每个状态下有27种不同的转动方式: 
      三个转轴(不看6个面,都可以分解到这三个转轴上进行) 
      每个转轴上可以转动三个不同的层 
      每个层可以转动3个不同的角度; " 


用这27种转动作为基本操作虽然不比12种基本转动方式产生更多状态,但效率无疑提高了不少,
本来需要2步的一些操作可以合并一步来完成。应该说是比较合理的,但有2个问题值的注意: 

    1.   和人工操作不太对应。人工很难对中间层进行转动;180度的旋转也通常是分2次90度旋转来完成的。 

    2.   机器模拟时,用按键(按钮)来表示比较困难,因为很难找到适当的单字来表达这27种
不同的操作,如果在魔方图形上操作是可以的,但为此就会遇到我前面提到的问题:每个转
动操作要点击2次,或进行很别。 
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#45楼 得分:0回复于:2005-06-22 16:57:12
..或进行很别扭的拖动操作。
 
#46楼 得分:0回复于:2005-06-22 17:01:59
我当时是用6个快捷键,快速的定位正面,然后用鼠标左键选择层和托拽控制角度 
右键自由旋转鼠标的
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#47楼 得分:0回复于:2005-06-22 17:11:10
to   heluqing: 

 “能不能给出个试玩版的魔方游戏” 

      --   可以,你留下地址,我就发给你,希望你多提意见。
 
  • heluqing用户头像
  • heluqing
  • (鉴之小河〖挣大钱娶美女〗)(越)
  • 等 级:
#48楼 得分:0回复于:2005-06-22 17:19:47
heluqing@sina.com 
谢谢...
 
  • fxw用户头像
  • fxw
  • (漂来)
  • 等 级:
#49楼 得分:0回复于:2005-06-22 17:22:37
魔方是一个群 

用群论来解更合适 

要寻找优化解或最优解是耗费时间的事情,在游戏中不合适 

其实楼主已经提出了合适的解决办法,可以结了 
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#50楼 得分:0回复于:2005-06-22 18:42:36
heluqing(鉴之小河〖挣大钱娶美女〗): 

  魔方游戏已经发送了。
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#51楼 得分:0回复于:2005-06-22 18:50:26
有的功能因临时试验未改正,和Help中的说明可能不一致了, 

如New操作说明中为随机作10-20次旋转,实际进行了200次。 

我用的调色版在windows下已经被改了一点。
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#52楼 得分:0回复于:2005-06-22 19:07:03
to   Tranquillo(影子)   : 

我的办法的步骤如下: 

    1.预先找出所有状态的最优解(即最少步数解)的步数; 

    2.将所有最优解排序后,用“状态-步数”的形式保存在一文件中; 

    3.以后遇到玩家的具体状态时,只要查一下表就行了。 

这一算法理论上看来是行的,但要找全部状态不可能(mathe前面已经估算工作量惊人),所 

以改为寻找最优解步数不超过N的所有魔方状态,作为初始状态。 

详细的算法描述待我整理一下再来说明,基本上就是用BFS。 


 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#53楼 得分:0回复于:2005-06-22 21:54:47
to   happy__888: 

mathe的45种基本操作是指: 

1.转动轴:分   x,y,z   3种; 

2.转动角:分   0,   90,180,270   4种; 

3.每一转轴同时考虑顶与底(左与右、前与后)两个面的组合转动,但不包括二者都不转的情况。   

所以一共是   3*(4*4-1)=45种 

看来也有道理。 
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#54楼 得分:0回复于:2005-06-23 08:19:18
这种转动组合的好处是: 

1.和人的手工转动相似:人用双手一起操纵2个面,使它们相对对于夹层的转轴位置同时变化; 

2.效率提高了:是单边转动的一倍; 

3.不包含对中间层的操纵:但仍然可以达到完全相同的效果。 


缺点则是: 

动作集的表示更加困难了,无论用鼠标或用键盘都一样; 

如果直接对魔方操作,实际上仍然要化为2次单边的转动; 

操作的纪录数目虽然可以少一半,但纪录的长度(字节数)恰要相应增加一倍:枚举12种转动只需要半字节,而45种就得用1字节才行。 

 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#55楼 得分:0回复于:2005-06-23 09:32:57
我觉得可以完全用鼠标拖拉来控制魔方的视角和旋转. 
比如用右键的拖拉来控制魔方视角的变化,左键的拖拉控制对魔方某层的旋转. 

改变视角比较简单,永远固定魔方中心的位置,   可以看成魔方中心的坐标是固定在屏幕 
中心后面某处,比如屏幕(鼠标将在屏幕上移动)方程为Z=0,-1 <=X <=1,-1 <=Y <=1 
我们可以认为魔方中心坐标为Z=-1,X=Y=0. 
然后对于鼠标的移动,其方向同魔方中心构成一个同魔方相交的平面,这时,让魔方在相应 
平面上面转动,转动角度正好为鼠标绕魔方中心装动的角度(或者是倍数).通过这个方法可以改变魔方的视角. 

控制魔方某层的转动,要求用户按下左键时,鼠标停留在此层被显示的某个方块上,而且鼠标移动 
的方向要求大致同这个层的方向平行. 


 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#56楼 得分:0回复于:2005-06-23 09:36:06
最重要的是无论改变视角,还是旋转,都要显示中间过程. 
对于旋转,很可能会出现某层旋转了一半(不到90度),用户就释放了鼠标. 
这时,如果旋转角度不到45度,我们可以让魔方自动转回(同样显示动画过程);如果超过 
45度,那么就自动旋转到90度的位置(同样显示动画),这样看起来就会感觉同真实的魔方很像
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#57楼 得分:0回复于:2005-06-23 09:47:38
我上面的45种表达方法主要是让计算机内部使用的,不应该让用户直接使用:) 
而比如对于中间层的操作,如果在计算机上面,允许用户直接操作中间层还是比较方便的, 
但是计算机内部没有必要给予表达,直接使用上下两层的同时变化来替换就可以了:) 
内部这种表达方式的好处是可以去除一些没有必要的状态,从而增加搜索的速度. 

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#58楼 得分:0回复于:2005-06-23 15:06:21
"最重要的是无论改变视角,还是旋转,都要显示中间过程....这样看起来就会感觉同真实的魔方很像 " 

这很重要,但要实时平滑转动,不容易,我的软件还没有做到这一点,我正好在设法解决中。 

我看到许多其他魔方软件都已经做到了,不知道是否利用了现成的3D引擎? 

 
#59楼 得分:0回复于:2005-06-23 15:39:16
显示中间过程不难,但是非常的麻烦 
要做关于时间插值的动画控制,没有一次旋转到位来得方便痛快 
没有办法预先做成大量的动画供你播放,只能是根据物理模型动态的控制,这个是需要时间和精力的 

关于45种状态的问题: 
    1.转动轴:分   x,y,z   3种;   
        okay 
    2.转动角:分   0,   90,180,270   4种 
      0度的转动是不存在,因为它就是当前的状态 
    3.每一转轴同时考虑顶与底(左与右、前与后)两个面的组合转动,但不包括二者都不转的情况。   
            转轴是指每次转动所围绕的旋转轴——垂直转动面的轴 
            不存在左右和前后的平行转轴的转法,因为那是对应到另外的垂直转轴上去的 
            另外上下两层的转动等价于中间层的反向转动 
简化旋转的状态有利于减少图的节点的数目 

有两个问题,如果可以解决,应该能够大幅度提高效率 

1   目前的模式当中,无法判别一个围绕同一个固定转轴的三层各自同方向旋转了同一个角度后的状态和初始状态是同一个状态。 
2   模式是图的模式,如果有办法可以砍断回归的链条,形成树的结构就会非常的有利 
    解决问题1是解决问题2的基础 

如果能够展开成为树的模式,从树的任何一个节点作为根把树提起来,都可以找到从这个节点到达6面各自单颜色对应的叶子节点之间的最短路径——沿着树走下去就是了。
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#60楼 得分:0回复于:2005-06-23 17:39:13
to     happy__888: 

  "   显示中间过程不难,但是非常麻烦 " 

    --   我也感到了.   我需要实时随机转动,无法像演示程序那样,可以预先生成一大堆图像。 

          对于整体转动,我的问题是图像有闪动,想用现成的双页模式显示,但结果更不行! 
          现在正在考虑中。 
          面的转动则还要按各种不同方式把魔方拆成2块,也有一点繁,不过总可以解决的。 


  "   2.转动角:分   0,   90,180,270   4种 
      0度的转动是不存在,因为它就是当前的状态 " 
    
      --   作为组合转动模式,其中一个面可以为0,但不允许2个面同时为0; 
            当一个面为0,另一个面不为0时,等效于我的转动模式中的一次转动, 
            只有当2个面同时转动为0时才等效于不转动,所以应扣除这种转动模式。 

‘   顶与底(左与右、前与后)... 
      不存在左右和前后的平行转轴的转法,因为那是对应到另外的垂直转轴上去的“ 
      
      --   我是为了把mathe的记号“X(u,d),   Y(u,d),   Z(u,d)”中的(u,d)在不同轴上的 
            转动相对于观察者而言能区别开来,加上“顶与底(左与右、前与后)”的注释, 
            因为(u,d)只能理解为(上,下),对把X,Z轴对应的面说成(上,下)面就不易理解了. 
            确切一点,把(u,d)改为(n,f),即 "近侧 "和 "远侧 ",可能合适一点吧? 
  

 
#61楼 得分:0回复于:2005-06-23 18:10:37
哦 
我认为的三个转轴是x,y,z世界坐标系的坐标轴,他们是永远固定不变的,魔方的中心在世界坐标系的原点上。 
任何一个单一层的旋转动作,只能分解成为3*3*3这27种当中的一个,一次只能绕三个转轴当中的一个,3个层当中的一个,3个角度当中的一个来旋转。 
不存在同时把一个轴上的两个层,旋转不同角度的操作,那样的操作要分成两步来定义。 

每个转动可以用一个三态变量标志(Axe,Level,Angle), 
在搜索最短路径的时候,得到的一些列的转到操作当中, 
1   不能有三个相连的操作的axe数值都相同(对同一个轴的三次相同的转动可能是没有必要的可以被其他的优化的解所替代的) 
2   不能有两个以上的相连的操作的axe和level数值都相同,对同一轴的同一层做了两次转动转动(可合并成一次) 
这样可以避免状态的重叠   : 
        魔方整体绕一个轴转了一个角度后形成新的状态,这个状态和初始状态是相同的。 

 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#62楼 得分:0回复于:2005-06-29 12:14:49
----我的问题是图像有闪动 
这可能是因为你直接将图像向屏幕上画的原因 
处理的方法是创建一个MemDC(要一个矩形大小,可以覆盖整个原先的图像), 
然后在MemDC上画好新的图,然后将这个MemDC贴上去就可以了
 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#63楼 得分:0回复于:2005-06-29 12:18:03
Memory   Device   Contexts 
To   enable   applications   to   place   output   in   memory   rather   than   sending   it   to   an   actual   device,   use   a   special   device   context   for   bitmap   operations   called   a   memory   device   context.   A   memory   DC   enables   the   system   to   treat   a   portion   of   memory   as   a   virtual   device.   It   is   an   array   of   bits   in   memory   that   an   application   can   use   temporarily   to   store   the   color   data   for   bitmaps   created   on   a   normal   drawing   surface.   Because   the   bitmap   is   compatible   with   the   device,   a   memory   DC   is   also   sometimes   referred   to   as   a   compatible   device   context.   

The   memory   DC   stores   bitmap   images   for   a   particular   device.   An   application   can   create   a   memory   DC   by   calling   the   CreateCompatibleDC   function.   

The   original   bitmap   in   a   memory   DC   is   simply   a   placeholder.   Its   dimensions   are   one   pixel   by   one   pixel.   Before   an   application   can   begin   drawing,   it   must   select   a   bitmap   with   the   appropriate   width   and   height   into   the   DC   by   calling   the   SelectObject   function.   To   create   a   bitmap   of   the   appropriate   dimensions,   use   the   CreateBitmap,   CreateBitmapIndirect,   or   CreateCompatibleBitmap   function.   After   the   bitmap   is   selected   into   the   memory   DC,   the   system   replaces   the   single-bit   array   with   an   array   large   enough   to   store   color   information   for   the   specified   rectangle   of   pixels.   

When   an   application   passes   the   handle   returned   by   CreateCompatibleDC   to   one   of   the   drawing   functions,   the   requested   output   does   not   appear   on   a   device 's   drawing   surface.   Instead,   the   system   stores   the   color   information   for   the   resultant   line,   curve,   text,   or   region   in   the   array   of   bits.   The   application   can   copy   the   image   stored   in   memory   back   onto   a   drawing   surface   by   calling   the   BitBlt   function,   identifying   the   memory   DC   as   the   source   device   context   and   a   window   or   screen   DC   as   the   target   device   context.   

When   displaying   a   DIB   or   a   DDB   created   from   a   DIB   on   a   palette   device,   you   can   improve   the   speed   at   which   the   image   is   drawn   by   arranging   the   logical   palette   to   match   the   layout   of   the   system   palette.   To   do   this,   call   GetDeviceCaps   with   the   NUMRESERVED   value   to   get   the   number   of   reserved   colors   in   the   system.   Then   call   GetSystemPaletteEntries   and   fill   in   the   first   and   last   NUMRESERVED/2   entries   of   the   logical   palette   with   the   corresponding   system   colors.   For   example,   if   NUMRESERVED   is   20,   you   would   fill   in   the   first   and   last   10   entries   of   the   logical   palette   with   the   system   colors.   Then   fill   in   the   remaining   256-NUMRESERVED   colors   of   the   logical   palette   (in   our   example,   the   remaining   236   colors)   with   colors   from   the   DIB   and   set   the   PC_NOCOLLAPSE   flag   on   each   of   these   colors.   

For   more   information   about   color   and   palettes,   see   Colors.   For   more   information   about   bitmaps   and   bitmap   operations,   see   Bitmaps.   

 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#64楼 得分:0回复于:2005-07-04 15:23:27
我家里有本解魔方的书,是分步进行的,针对的面均为外面(魔方分三层,两边的层) 

基本操作是 
1、转动一个面,参数:方向,转动次数(1-2) 
2、同向同次数转动相对的两个面(相当于反向转动内面) 

这两个操作可在200步内确定解决任意状态
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#65楼 得分:0回复于:2005-07-04 15:29:46
分步来解决 
1、计算一个表面的重整理 
这个应该有模式,通过模式找到最优化的方案 
2、计算1相邻内面的4个位置 
这个通过实验也能找到不改变1的成果的所有的排列 
3、计算1对应面的8个位置 
这个需要仔细考虑,基本操作是转动垂直于1的表面的内面+相对于1的底面的转动的组合,同样可以不改变1,2的结果
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#66楼 得分:0回复于:2005-07-04 15:36:35
定义:标准转动指预先定义的以一个表面做顶面的一系列有确定步骤的有先后顺序的转动,顶面可以是任意面 

上面每个步骤的状态数都是确定的 

关键是,有的状态1个标准转动就能解决,有的需要2-3个标准转动
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#67楼 得分:0回复于:2005-07-05 11:31:18
to   yaos:   谢谢, 

不过,为了合理打分,我不仅需要自动求解,而且需要求得最优解.   

魔方书中所讲的分步(分层)求解法一般不可能得到最优解的,即步骤最少的解法. 
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#68楼 得分:0回复于:2005-07-05 13:40:43
to   mathe()   : 

我开始时,因考虑到魔方需要颜色不多,已选择了我习惯使用的VESA16,GM=0图形 

模式(即800*600,16色的模式)来编写程序。这一工作很快完成了,但当后来需要 

加入各种动画效果时,发现了VESA16,GM=0模式有2个麻烦问题: 

1.一个象素的4个bit要分4个位平面(bit   plane)来存放。在内存中进行这种操作 

相当麻烦,如不用汇编,速度也就会成问题; 

2.只有一个页面,不能利用页面切换办法来实现动画功能。 


后来我改用了640*480,16色的标准VGA图形模式。按书本上讲,标准VGA有2个独立 

的640*480页面可用。如果是这样,我就可以用双页面方式来实现无闪动动画(双 

页面模式允许有一个页面用来作图,而不显示,其作用是和你介绍的内存DC一样 

),但后来也发现了问题:VGA的0,1两个页面不能正常工作。我把ActivePage设 

为1,VisualPage设为0,在ActivePage上画图时,竟然有相当大的一部分会在页 

面0上显示。不知道是机器(显卡)有毛病,还是我用的语言(BP7)有毛病,我已经 

试验了好几个程序,包括别人写的,都一样。这一问题我正在找更多的机器试验。 

 
  • mathe用户头像
  • mathe
  • (141031079451)
  • 等 级:
#69楼 得分:0回复于:2005-07-06 09:40:17
呵呵,你不是在Windows上面编程?   我还以为现在一般人都直接在Windows上编程了.使用Windows   API,就不应该有各种模式问题
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#70楼 得分:0回复于:2005-07-06 17:17:47
是啊,竟然连Borland   Pascal   7都掏出来了 
呵呵 

最优化的求解,目前来看不太现实 

只能追求优化的解了 

我倒想到了一个方法 

固定一个方位 

此时,所有面心颜色都是确定的 

那么,对任何边与角来说 

一定存在一个最短的路径把这个边和角从原始位置变换到现在的位置 

需要考虑的是不动变换阿 

就是除了目标外,影响其它边和角最小的变换 

这种变换应该有很多种
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#71楼 得分:0回复于:2005-07-06 17:24:46
不过,上边的太难处理了 

假如引入混乱度的概念 

从混乱状态倒推,选取混乱度降低的路径,可能比较好些 

问题是怎么定义混乱度 
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#72楼 得分:0回复于:2005-07-06 17:33:33
或者考虑定义一个偏移度的概念 
就是考虑位置偏移于原始位置的距离 

用队列考虑,则类似长短不同的队列 
如果有方法将队列补充整理成相同长度 
则......(不知道如何描述) 

备注: 
考虑随机的长度在10   以内的变换 
是否能得到一个结论,即不同位置的相同颜色的边(或者角,2种颜色的交界色块成为边,三种的叫角)是否能不动(不影响其它的色块)的交换,如果不是,则不同位置的相同颜色的边(或者角)在混乱魔方上的分布一定有一定的规律
 
  • 无心人用户头像
  • 无心人
  • (语言决定算法&孤独和寂寞交朋友)
  • 等 级:
#73楼 得分:0回复于:2005-07-06 17:47:41
实际上存在很多有用处的变换 

我曾经研究过,考虑采用变换的方法 
是现阶段比较可行的一种方法 

不知道大家有兴趣么?
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#74楼 得分:0回复于:2005-07-07 13:44:51
to   二   位: 

Borland   Pascal   7   是 "我的最爱 ",   这是纯Borland的产品,启动很快,编译也飞快,不象Delphi,建筑在Windows之上,启动太慢,编译也慢了一点,不过我的程序同时也在Delphi3上开发(不用更高版,也是为了起动能快一点).   但我希望2个版本都有同样的功能和外貌. 

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#75楼 得分:0回复于:2005-07-07 14:14:55
to   yao: 

"保持其他边和角不动或少动,然后来寻找最短的路径把一个边和角从原始位置变换到现在的位置 " 

是一种新的想法!   这在某种意义上可能会比Richard   E.   Korf文章介绍算法要好些,后者在优化角的方位时不考虑边的动与不动。但是,要注意两点, 

1。一个边角一个边角地进行优化,其结果通常比同时考虑所有角或多个边的同时优化结果要差;其最终效果是否一定会比Richard   E.   Korf的结果好也就不一定了。 

2。从理论上说,保持其他边和角不动或少动也不是最好的方法,理想情况应该是调整一个子时同时也使其他子能跟着动--使它们朝着目标变化。 

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#76楼 得分:0回复于:2005-07-07 14:30:02
举个例子:经过第一次转动,就有8小块改变了位置,显然,只要用一次相反的转动,就可以把所有边和角同时调整到原始状态!但如果要求调整一块时 "保持其他边和角不动 "就不堪设想了,呵呵
 
  • ihsgnep用户头像
  • ihsgnep
  • (石头->信心最重要 努力是王道)
  • 等 级:
#77楼 得分:0回复于:2005-07-07 18:26:49
Mark,太复杂啦,搞不懂
 
#78楼 得分:0回复于:2005-07-07 22:54:54
试试A*算法? 

用(已经转过的次数)+(与6面同色所需要改变的小格子颜色的次数)做判断依据?
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#79楼 得分:0回复于:2005-07-08 11:22:00
"与6面同色所需要改变的小格子颜色的次数 "   --   这可是一个难于捉摸的参数啊!
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#80楼 得分:0回复于:2005-07-08 13:48:30
我说过: 
考虑采用变换的方法 
是现阶段比较可行的一种方法 

变换不一定移动多少位置 

关键是一种模式 

重要的变换能反复的移动边或者角到正确位置而不影响其它位置或者很少影响
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#81楼 得分:0回复于:2005-07-08 13:50:51
比如 

左2   底2   左2 

将交换对角的3个位置
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#82楼 得分:0回复于:2005-07-10 14:30:58
to   yaos: 

    "左2   底2   左2 " 

是否代表 

    "左面转2次   +   底面转2次   +   左面转2次 "? 
  
我去试了后一串操作的效果,其结果是正面与反面底层中间的颜色做了对换,无法交换对角的3个位置 


我对你的 "变换 "的思想也不太了解,   旋转本身不就是一种变换吗?
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#83楼 得分:0回复于:2005-07-10 16:30:27
是,正好是旋转180度 

但你的结果不可能阿 

你想象一下 

左2:上左边   下左边   交换 
底2:上左边   下右边   交换 
左2:下左边   下右边   交换 

结果:上左边   下右边交换
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#84楼 得分:0回复于:2005-07-10 16:32:03
变换的   意思是   一系列的旋转步骤 

单个旋转也是
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#85楼 得分:0回复于:2005-07-13 09:39:50
你说的是对的,但我讲的也正确,实际上 

    "正面与反面底层中间的颜色做了对换 " 

是实现 

    "上左边   下右边交换 " 

时带来的 "副作用 ".
 
#86楼 得分:0回复于:2005-07-13 11:10:09
http://mf8.com.cn     魔方吧 

欢迎魔方爱好者加入,你将看到各种类型的魔方,里面内容包括了以快速复原为目的的、以研究魔方公式体系为目的的、以及魔方diy为目的的。你甚至可以拥有这些奇怪的魔方,版主长期代购各种魔方 

不好意思,打了个广告,不过魔方吧里面也有数学研究者,里面也有他们的关于魔方的理论体系
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#87楼 得分:0回复于:2005-07-13 11:29:11
to   yao: 

你前面讲的 "混乱度 "和 "偏移度 "是很有意义的,不知道有否深入考虑过用什么参数? 

我一开始时也曾经考虑过,我的程序曾利用: 

            nodc   =   不同色彩的小块数 

来代表偏移度,也就是新状态和原始状态颜色不同的小块数目.例如, 

原始状态:   nodc   =0, 

经过1次旋转,   nodc   =   12, 

经过2次旋转,nodc可以为24(只要2次转动没有公共的块), 

而最少可以是0(一次正转,一次反转), 

一般是22(如 '左转 '+ '顶转 '). 


但不管转动多少次,nodc最多只能为48,   即6个面所有边角的小面块(facet)都改了颜色, 

这一个参数只对开始几步有意义,转动次数多了,就没有意义,因为不是状态愈乱,nodc就愈大. 

 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#88楼 得分:0回复于:2005-07-15 08:13:33
我想,考虑每个方块四周的方块的异色数,比较合适
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#89楼 得分:0回复于:2005-07-15 09:13:07
这可能会好些,但也不能保证愈乱这个参数愈大.例如 

1.   左面转一次   -   异色数=4 

2.   再右面转一次   -   异色数=8 

3.   但如果接着做   

      顶面-底面-正面-背面-左面-右面 

一系列转动后,异色数反而见为   6   
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#90楼 得分:0回复于:2005-07-15 12:11:26
这可能会好些,但也不能保证愈乱这个参数愈大.例如 

1.   左面转一次   -   异色数=4 

2.   再右面转一次   -   异色数=8 

3.   但如果接着做   

      顶面-底面-正面-背面-左面-右面 

一系列转动后,异色数反而减少成为   6   

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#91楼 得分:0回复于:2005-07-17 12:11:27
魔方游戏搞了一半,不得不停下来,要去为 <人工智能用于游戏编程> 一书的最终出版事忙一段时间. 

剩下问题有一个变成了2个: 

1.找最优解-即最少步数解; 

2.平滑转动问题: 
    我已经做到能显示中间过程了,但不理想,有闪动, 
    

 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#92楼 得分:0回复于:2005-07-17 15:53:09
解决2个问题方法都已搞定,就缺动手编程了.
 
  • yaos用户头像
  • yaos
  • (算法已死|代码无效)
  • 等 级:
#93楼 得分:0回复于:2005-07-19 10:07:35
那可能需要考虑符号问题了 

另外,定义一个原始状态,考虑偏移, 
用原始状态到当前状态的直线距离表示 
 
  • zzwu用户头像
  • zzwu
  • (未名)
  • 等 级:
  • 10

    6

    8

#94楼 得分:0回复于:2005-07-19 12:35:50
to   yaos: 

1.   你说的 "符号 "是指什么?   

2.   你说的 "偏移 "又指什么?   

3.   你想的 "直线距离 "又指什么?   

你的 "直线距离 "看来就是我的 "最少转动数 "了,从原始状态到当前状态所需的最少转动数 

 
#95楼 得分:0回复于:2010-06-17 00:15:34
cube explorer
 
   
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zzwu/article/details/53327530
文章标签: 魔方自动求解问题
个人分类: 魔方自动求解
上一篇3D图形编程入门(1)- cubic
下一篇学勉中学
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭