回溯法-子集树递归树-装载问题

回溯法

深度优先策略(回忆深度优先遍历二叉树思路)
解题步骤:

 1)针对所给问题,定义问题的解空间;例如,n个物品的0-1背包问题所对应的解空间树是一棵子集树。
 2)确定易于搜索的解空间结构;
 3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数(****约束函数除去不满足约束的子树,限界函数减去得不到最优解的子树**)**避免无效搜索

## 子集树和递归树

扩展结点:一个正在产生儿子的结点称为扩展结点。
活结点:一个自身已生成但其儿子还没有全部生成的节点称做活结点。
死结点:一个所有儿子已经产生的结点称做死结点。
1.当所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间称为子集树
0-1背包问题

//回溯法遍历子集树
void Traceback(int k)//k为扩展结点在解空间树中所处的层次
{
   
    if (k > n)//n标识问题的规模
        output(x);//存放当前解的一维数组
    if (constraint(k))//约束条件
    {
   
        //相关标识
        backtrack(k + 1);
        //相关标识的反操作---->从左子树退回,考虑从父节点的角度(场景复原)
    }
    if (bound(k))//限定函数
    {
   
        //相关标识
        backtrack(k + 1);
        //相关标识的反操作、、、、?
    }
    //或者:  
// //for (int i=0;i<=1;i++) {   //控制分支的数目,此处只有两个分支,0、1分别代表是否装入背包
	x[t] = i;
	if (constraint(t) && bound(t))
			// backtrack(t + 1); 
			//剪枝函数:约束函数+限界函数 ——> 递归
       }

       ————————————————
           版权声明:本文为CSDN博主「有梦想的小树」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。
           原文链接:https ://blog.csdn.net/m0_38109046/article/details/84844640
//}
}

2.当所给问题是确定n个元素满足某种性质的排列时,相应的解空间树称为 排列树

//回溯法遍历排列树
//void backtrack(int t)//扩展结点在解空间树中所处的层次
//{
   
//    if (t > n)//n:规模
//        output(x);//存放当前解的一维数组
//    else {
   
//        for (int i = t; i <= n; i++)
//一条12345路径,我们从1出发1->2->3->4->5 那我们backtrace(2)的时候会把2和345交换位置,就是为了获得1->3, 1->4, 1->5开头的路径。
//        {
   
//            swap(x[t], x[i]);              //实现两个位置的交换
//            if (constraint(t) && bound(t))   //约束函数与限定函数
//                backtrack(t + 1)                //递归
//            swap(x[t], x[i]);              //恢复原状

//全排列Perm算法同样用到该思路//回看前期文章
//        }
//    }
//}
// ZhuangZaiWenTi!.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

你可能感兴趣的:(算法,回溯法,c++,算法)