- 1、本文档共19页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 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)