回溯法:0-1背包问题

#include <iostream>
#include <algorithm>
using namespace std;

class Knap
{
    public:
        int c;         //最大容量
        int n;         //物品数量
        int w[6];      //重量数组
        int p[6];      //价值数组
        int cw;        //当前重量
        int cp;        //当前价值
        int bestp;     //当前最大价值
        int r;         //当前剩余的最大价值
        int x[6];      //解向量
        int bestx[6];  //最优解向量
        void Backtrack(int i);//回溯函数
        friend int Knapsack(int w[],int p[],int c,int n);//友元函数,初始化并计算
};

void Knap::Backtrack(int i)//对第i个物品进行操作
{
    if(i>n)//如果到叶子节点
    {
        if(cp>bestp)//并且当前价值大于已经求得的最优值,就更新最优解,包括bestx[]和bestp
        {
            for(int j=1;j<=n;j++)
                bestx[j]=x[j];
            bestp=cp;
        }
        return;
    }
    /*如果没有到叶子节点,就要对这个节点进行操作,即搜索它的子树,进入做左子树表示可以选第i个,进入右子树表示不能选第i个*/
    if(cw+w[i]<=c)//如果能够进入左子树
    {
        x[i]=1;//表明被选中
        cw+=w[i];//重量增加
        cp+=p[i];//价值增加
        Backtrack(i+1);//继续探索下一个
        cw-=w[i];//它的儿子们全部探索完了,应该恢复现场
        cp-=p[i];
    }
    /*如果要进入右子树,需要求出剩余物品的最大价值*/
    r-=p[i];//因此这里的r需要就去p[i]表示不选它之后,剩下物品的全部价值之和
    if(cp+r>bestp)//已有的价值加上剩下全部的价值之和都不能大于bestp的话就没有进入右子树的必要了,如果满足括号里的条件,说明还有机会再右子树里面找到最优解
    {
        x[i]=0;//进入右子树,说明第i个物品我不选,因此置0
        Backtrack(i+1);//再探索下一个物品
    }
    r+=p[i];//右子树探索完之后要恢复现场,因此r要恢复到原来的值
}

int Knapsack(int w[],int p[],int c,int n,int bestx[])
{
    Knap X;//定义一个对象
    /*初始化对象参数*/
    X.c=c;
    for(int i=1;i<=n;i++)
    {
        X.w[i]=w[i];
        X.p[i]=p[i];
        X.bestx[i]=bestx[i];
        X.x[i]=0;
    }
    X.n=n;
    X.bestp=0;
    X.cp=0;
    X.cw=0;
    /*初始化r*/
    X.r=0;
    for(int i=1;i<=n;i++)
        X.r+=p[i];
    /*调用递归函数*/
    X.Backtrack(1);
    /*返回最优解向量*/
    for(int i=1;i<=n;i++)
        bestx[i]=X.bestx[i];
    /*返回最优解*/
    return X.bestp;
}

int main()
{
    int w[6]={0,2,2,6,5,4},p[6]={0,6,3,5,4,6},bestx[6]={0},c=10,n=5;//测试参数
    cout<<"最优解为:"<<Knapsack(w,p,c,n,bestx)<<endl;
    cout<<"最优解向量为:";
    for(int i=1;i<=n;i++)
        cout<<bestx[i]<<" ";
}

《回溯法:0-1背包问题》

    原文作者:回溯法
    原文地址: https://blog.csdn.net/shijie97/article/details/78446280
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞