前提条件:物体按价值重量比非递增排序
回溯法(循环迭代回溯)
方案一:
1.将物体装入背包(搜索此物体的左分支),直到第i个物体不能装入时(此时进入第i个物体的右分支搜索),试探下一个物体;
2.当试探完第n个物体时(即已到达空间树的叶子结点,搜索到一个可能解),将当前装入背包物体的总价值CP_Total与之前搜索到的可能解的总价值P_Total进行比较,P_Total = max(CP_Total,P_Total),更新可能解X[],向上回溯:沿着空间树的右分支向上搜索至左分支结点(更新当前重量CW_Total,当前价值CP_Total,搜索解Y[]),将此物体移出背包(搜索左分支结点即此物体的右分支树),试探下一个物体;
3.回溯到第0个物体时,已经搜索完整个空间树,搜索过程结束,此时的P_Total为最大价值。
结论:算法效率差,每次搜索时一定要搜索至叶子结点才结束此次搜索,即一定要到达叶子结点后才进行回溯。进入右分支搜索时,可以通过条件判断是继续试探下一个物体还是直接进行回溯(即结束本次搜索)。
方案二:
1.将物体装入背包(搜索此物体的左分支),直到第i个物体不能装入时,对P_est(如果进入右分支搜索可能获得的最大值,P_est = cleft*p[i]/w[i])和之前搜索到的可能解的总价值P_Total进行比较。
2.如果P_est > P_Total,即进入第i 个物体的右分支继续搜索,保存当前重量CW_Total,当前价值CP_Total,搜索解Y[]。如果没有搜索完第n个物体,则继续试探下一个物体。如果搜索完第n个物体(即已到达空间树的叶子结点,搜索到一个可能解),将当前价值CP_Total与之前搜索到的可能解的总价值P_Total进行比较,P_Total = max(CP_Total,P_Total),更新可能解X[],向上回溯:沿着空间树的右分支向上搜索至左分支结点(更新当前重量CW_Total,当前价值CP_Total,搜索解Y[]),将此物体移出背包(搜索左分支结点即此物体的右分支树),试探下一个物体。回溯到第0个物体时,已经搜索完整个空间树,搜索过程结束,此时的P_Total为最大价值;
3.如果P_est < P_Total,不进入第i 个物体的右分支继续搜索,直接向上回溯:沿着空间树的右分支向上搜索至左分支结点(更新当前重量CW_Total,当前价值CP_Total,搜索解Y[]),将此物体移出背包(搜索左分支结点即此物体的右分支树),试探下一个物体。回溯到第0个物体时,已经搜索完整个空间树,搜索过程结束,此时的P_Total为最大价值。
结论:较方案一效率提高,利用估计最大值P_est判断是否进入空间树的右分支进行搜索,减少了访问空间树的结点的个数,提高搜索效率。
回溯法(递归回溯)
void backtrace(int i) //递归搜索空间树
{
//递归出口
//如果搜索完第n个物体(即到达叶子结点)
//记录当前最优值,return
//如果能装入第i个物体
//装入第i个物体(搜索第i个物体的左分支)
//递归搜索第i+1个物体
//1.右分支的估计最大值小于当前最优值;2.搜索完第n个物体
//这两种情况都能停止递归,开始回溯
//回溯,移出第i个物体(搜索左分支结点即第i个物体的右分支树)
//1.如果第i个物体不能装入;2.回溯,移出第i个物体
//这两种情况均要试探搜索第i 个物体的右分支树
//如果沿着右分支搜索的可能最大值大于当前最优值
//递归搜索第i+1个物体(搜索第i 个物体的右分支)
}