剪枝搜索心得

前天在《编程之美》中读到一个“一摞烙饼排序”的问题,第一眼不会做,看了答案之后倒是让我明白了一年多之前不真正理解的剪枝搜索的内涵。记录一下,作为分享和温习之地。

剪枝搜索说白了还是搜索,就像动态规划说白了就是使用特殊的方法进行搜索以提高效率。剪枝搜索中涉及到很重要的概念:状态空间和搜索树。我觉得状态空间和搜索树之间是有绝对的关系的。剪枝搜索就是在一棵状态树上搜索想要的节点。然而和以前的树不同的是,这棵树中的节点并不是都在内存中的,而是到达该节点时该节点通过数组表示在内存中而其他节点并没有,通过改变数组内容来达到状态的改变。在程序中通过剪枝条件判断进行中断某条搜索路径转向其他路径,从而不必在无用的路径浪费时间,进而提高效率。在程序中,典型的是在一个循环中存在递归语句和辅助处理程序,在循环之外是判断终点的语句和进行剪枝的语句。判断终点的语句自然是为了停止递归,循环是为了在搜索树上进行横向扩展即遍历每一个状态节点的所有直接子节点,而递归则是为了纵向进行搜索达到DFS或者BFS。剪枝语句涉及到进行剪枝的条件或者说函数,这个函数涉及到搜索的效率,因为他决定了是否继续进行搜索,该状态是否已经不是最优的了。

提高剪枝搜索效率的关键在于改良搜索路径和条件函数。更加快速并且准确的判断状态进而判断是否继续进行搜索。

void CPrefixSorting::Search(int *pCakesArray, int step)

{

    ++searchCount;

    if (LowerBound(pCakesArray) + step >= reversesCount)

    {

       return;

    }

    if (IsSorted(pCakesArray) && step < reversesCount)

    {

       reversesCount = step;

       for (int i = 0; i < reversesCount; ++i)

       {

           cakesArrayReverse[i] = curCakesArrayReverse[i];

           cout << curCakesArrayReverse[i] << "  ";

       }

 cout << endl;

       return;

    }

 

    for (int i = 1; i < cakesCount; ++i)

    {

       int *cakesArrayTmp = new int[cakesCount];

       assert(NULL != cakesArrayTmp);

       for (int j = 0; j < cakesCount; ++j)

       {

           cakesArrayTmp[j] = pCakesArray[j];

       }

       Reverse(cakesArrayTmp, 0, i);

       curCakesArrayReverse[step] = i;

       Search(cakesArrayTmp, step + 1);

if (cakesArrayTmp)

        {

           delete [] cakesArrayTmp;

       }

    }

}



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值