搜索剪枝(魔方为例)精选.pptx

  1. 1、本文档共19页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
搜索剪枝(魔方为例)精选

搜索(剪枝打表);;1、最朴素的实现 首先可以发现,极限情况下,最多旋转7次,次数很小,可以考虑用穷举,或者说,DFS的方法来实现。其次考虑,对当前的魔方状态,有多少种单次转动的行为可以 转成另一种状态: ;计算对应关系 以下约定: 前面指6、7、12、13这一面,左面指4、5、10、11这一面,上面指0、1、2、3这一面。 a→b表示原来在a位置的数旋转后移动到b位置 前面的旋转中顺时针旋转对应关系:;(1)前面旋转对应关系:;(2)上面旋转对应关系:;(3)左面旋转对应关系:;2、剪枝第一次 首先可以注意到,相对运动的特点,上面顺时针旋转等效于下面逆时针旋转,上面逆时针旋转等效于下面顺时针旋转,等等。 也就是说,在上述列举的12种基本操作中有6对操作两两等效。 换言之,可以去除其中重复的6种操作,剩下6种操作:;减少代码量 首先可以预见,对每一种??转方法,我们需要写出这种旋转方法操作后某个位置的色块移动到的区域。换言之,我们需要预先计算出6种对应关系,对每种对应关系写出相应的表示旋转操作的数组——需要6个24个元素的一维数组。24*6=144,要写的量比较大,非常容易出错。 可以注意到,逆时针旋转1次等效于顺时针旋转3次 也就是说,具体实现中,可以只预先计算顺时针旋转的3个操作的对应关系,在实现逆时针旋转的时候,用3次顺时针旋转来替代。(当然也可以先算好逆时针实现,顺时针旋转时调用3次逆时针旋转);//剪枝第一次 // 12种基本操作中有6对操作两两等效 //逆时针旋转1次等效于顺时针旋转3次 int?current[12][24]; void?turnup(int?depth) { ? ??for(int?i=0;i24;i++) ? ? ? ??current[depth][i]=current[depth-1][up[i]]; //根据up对应关系 } void?turnleft(int?depth) { ? ??for(int?i=0;i24;i++) ? ? ? ??current[depth][i]=current[depth-1][left[i]]; } void?turnfront(int?depth) { ? ??for(int?i=0;i24;i++) ? ? ? ??current[depth][i]=current[depth-1][front[i]]; } ;3、剪枝第二次 注意到在题目要求中提到: 在N步操作以内(包括N步)最多能使几个面的4个块的颜色相同。 也就是说,可以0步,可以1步,可以2步,只要小于等于N步即可,不一定恰好N步。 也就是说,如果进行DFS,那么,每次DFS都要先对当前魔方状态进行检查,记录最大4块同色的面数。 换句话说,如果对先顺时针转了上面,在逆时针转了上面,在这一题中,没有任何意义,还平白无故减少了2次操作。 那这样,我们可以想到,上一次做过A操作,那本次就不应该进行一个等效于撤销A操作的操作。而对上述6个操作中的每一个,有且仅有1个操作与此操作作用刚好相互抵消, 也就是,第一次旋转有6种选择,之后每次旋转有5种选择。 那这样,极限情况下,需要的基本运算次数为6*(5^6)*24= 2250000,相比第一次剪枝,理论上时间减少了约2/3.;//第二次剪枝:判断是否做了上次操作的逆操作? if(pre!=2) { ? ? ? ??turnup(depth); ? ? ? ??dfs(depth+1,1); } if(pre!=1) { ? ? //先模拟连续逆时针旋转了3次的操作? ? ? turnup(depth); ? ? turnup(depth+1); ? ? turnup(depth+2); ? ? //再把最后结果拿回来,当做顺时针旋转1次的操作? ? ? for(int?i=0;i24;i++) ? ? ? current[depth][i]=current[depth+2][i]; ? ? dfs(depth+1,2); } if(pre!=4) { ? ? turnleft(depth); ? ? dfs(depth+1,3); } ??;4、剪枝第三次 其实上述两次剪枝的优化效果已经非常好了,但是我们还可以考虑再追求极致一下。 当某一次旋转之后6个面的4个小块的颜色都相同的时候,这个魔方已经还原,不可能再有更多面同色了,也就是说,答案确定是6了,不需要再进行枚举旋转操作了。 理论上这个剪枝能有一定的优化效果,但效果很有限。;void?dfs(int?depth,int?pre) //depth-正在做第几

文档评论(0)

pfenejiarz + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档