0-1 backpack - Backtracking

Algorithm Description:

0-1 knapsack backtracking, backtracking loaded with problems very similar. When searching for the solution space tree, as long as its left son node is a viable node, the search entered its left subtree. When the right sub-tree may contain only optimal solution into the right subtree search. Otherwise, the right subtree cut.

  Better right sub-tree algorithm calculates the community is:

    The remaining items sorted according to their value per unit weight, then successively charged articles, till the fit, and then charged with a portion of the article and filled with the backpack.

Algorithm:

  The upper bound of the current node is calculated by the function Bound.

  Recording data members Knap solution space tree node information, and to reduce the transmission parameters required for the recursive call stack space.

  At this extended solution space tree node, to enter only when the right subtree, bound only to calculate the upper bound, to determine whether the right subtree can be cut.

  No need to calculate upper bound into the left sub-tree, since it is the same as the upper boundary of its parent node.

Algorithm: (the code a little problem, being revised)

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
template <class Typew,class Typep>
class Knap{
        friend Typep Knapsack(Typep *,Typew *,Typew,int);
        private:
                Typep Bound(int i);
                void Backtrack(int i);
                Typew c;//背包容量
                int n;//物品数
                Typew * w;//物品重量数组
                Typep * p;//物品价值数组
                Typew cw;//当前重量
                Typep cp;//当前价值
                Typep bestp;//当前最优价值
};
template <class Typew,class Typep>
void Knap<Typew,Typep>::Backtrack(int i)
{
        if(i>n)//到达叶子
        {
                bestp = cp;
                return;
        }
        if(cw+w[i] <= c)//进入左子树
        {
                cw += w[i];
                cp += p[i];
                Backtrack(i+1);
                cw -= w[i];
                cp -= p[i];
        }
        if(Bound(i+1)>bestp)//进入右子树
                Backtrack(i+1);
}
template <class Typew,class Typep>
Typep Knap<Typew,Typep>::Bound(int i)//计算上界
{
        Typew cleft = c- cw;//剩余容量
        Typep b = cp;
        while(i<=n && w[i]<=cleft)//以物品单位重量价值递减序装入物品
        {
                cleft -= w[i];
                b += p[i];
                i++;
        }
        //装满背包
        if(i<=n)
                b+=p[i]*cleft/w[i];

        return b;
}
class Object
{
        friend int Knapsack(int *,int *,int,int);
public:
        int operator <= (Object a)const
        {
                return (d >= a.d);
        }
private:
        int ID;
        float d;
};
int compare (const void * a, const void * b) 
{ 
  return ( *(int*)a - *(int*)b );
}
template <class Typew,class Typep>
Typep Knapsack(Typep p[],Typew w[],Typew c,int n)
{
        int i;
        //初始化
        int W = 0;
        int P = 0;
        Object* Q = new Object[n];
        for(i=0;i<n;i++)
        {
        //        cout<<p[i]<<" "<<w[i]<<endl<<"-------------------------"<<endl;
                Q[i].ID = i;
                Q[i].d = 1.0*p[i]/w[i];
        //        cout<<Q[i].ID<<" "<<Q[i].d<<endl<<"----------------------"<<endl;
                P += p[i];
                W += w[i];
        //        cout<<P<<" "<<W<<endl<<endl; 
        }
        if(W<=c)
                return P;//装入所有物品
        //依物品单位重量价值排序
        qsort (Q,n, sizeof(int), compare);
        Knap<Typew,Typep> K;
        K.p = new Typep [n+1];
        K.w = new Typew [n+1];
        for(i =1;i<=n;i++)
        {
                K.p[i] = p[Q[i-1].ID];
                K.w[i] = w[Q[i-1].ID];
        }
        K.cp = 0;
        K.cw = 0;
        K.n = n;
        K.bestp = 0;
        K.Backtrack(1);
//        cout<<K.bestp<<endl;
        delete [] Q;
        delete [] K.w;
        delete [] K.p;

        
        return K.bestp;
}
int main()
{

        int p[4] = {9,10,7,4};
        int w[4]= {3,5,2,1};
        int num = Knapsack(p,w,7,4);
        cout<<num<<endl;
        return 0;
}

Reproduced in: https: //my.oschina.net/u/204616/blog/545079

Guess you like

Origin blog.csdn.net/weixin_34099526/article/details/91989753