0-1背包问题简单实例(回溯法求解…

    使用了不太需要的模板来写,而且,因为没有能够找到能在ISO标准下的g++中实现friend函数的方法,结果只能很无奈地全部public了,叹一个~

bag2.cpp

#include <iostream>
using namespace std;

class Object;

template <class Typew, class Typep>
Typep Knapsack(Typep *p, Typew *w, Typew c, int n);

void MergeSort(Object *, int);

class Object
{
public:
int operator <= (Object a)const
{
return (d >= a.d);
}
int ID;
float d;
};

template <class Typew, class Typep>
class Knap
{
public:
Typep Bound(int);
void Backtrack(int );
Typew c;//weight constrain of the bag
int n;//number of kinds of goods
Typew *w;//weiht of goods
Typep *p;//value of goods
Typew cw;//current weight of the bag
Typep cp;//current value of the bag
Typep bestp;//current optimal value of the bag
};


template <class Typew, class Typep>
Typep Knap<Typew, Typep>::Bound(int i)
{
Typew cleft = c - cw;//weight left of the bag
Typep b = cp;
//add the weight of goods in decreasing order
while(i <= n && w[i] <= cleft)
{
cleft -= w[i];
b += p[i];
i ++;
}
if(i <= n)
{
b += p[i] * cleft / w[i];
}
return b;
}
template <class Typew, class Typep>
void Knap<Typew, Typep>::Backtrack(int i)
{
if(i > n)
{
                  //这里可以解释一下,因为首先遍历左子树,所以,一定是能装的都装了
                //而由于对性价比排了序,所以,先装进去的肯定具有更高的价值,从而
                //如果遇到了一个叶节点,意味着前面的叶节点都没有符合约束要求,后
                //的叶节点都不可能得到更优的解,故遇到叶节点即已经得到最优值
bestp = cp;
return ;
}
if(cw + w[i] <= c)
{
//enter the left subtree
cw += w[i];
cp += p[i];
Backtrack(i + 1);
cw -= w[i];
cp -= p[i];
}
if(Bound(i + 1) > bestp)
{
Backtrack(i + 1);
}
}

int main()
{
//0-1 bag problem, using backtrack method

int c;//weight constrain of the bag
  int *w;//weight of goods
int *v;//value of goods
int n;//kinds of goods
int i, j;
cout<<"Please input weight constrain of the bag:";
cin>>c;
cout<<"Please input number of kinds of goods:";
cin>>n;
if(n <= 0 || c <= 0)
{
cout<<"invalid arguments"<<endl;
return 0;
}
cout<<"Please input "<<n<<" weight of goods:"<<endl;
w = new int[n + 1];
w[0] = 0;
for(i = 1; i <= n; i++)
{
cin>>w[i];
}
cout<<"Please input "<<n<<" value of goods:"<<endl;
v = new int[n + 1];
v[0] = 0;
for(i = 1; i <= n; i++)
{
cin>>v[i];
}
int temp = Knapsack(v, w, c, n);
cout<<"The optimal value is: "<<temp<<endl;
delete w;
delete v;
return 0;
}

template <class Typew, class Typep>
Typep Knapsack(Typep *p, Typew *w, Typew c, int n)
{
int i;
Typew W = 0;
Typep P = 0;
Object *Q = new Object[n + 1];
for(i = 1; i <= n; i++)
{
Q[i - 1].ID = i;
Q[i - 1].d = 1.0 * p[i] / w[i];
P += p[i];
W += w[i];
}
if(W <= c)
{
return P;
}
MergeSort(Q, n);
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.c = c;
K.n = n;
K.bestp = 0;
K.Backtrack(1);
delete []Q;
delete []K.w;
delete []K.p;
return K.bestp;
}

void MergeSort(Object *Q,int n)
{
for(int i = 0;i < n;i++)
{
int s = i;
for(int j = i + 1;j < n;j++)
if(Q[j].d > Q[s].d)
s = j;
Object temp=Q[i];
Q[i] = Q[s];
Q[s] = temp;
}
}

Makefile:

bag2:bag2.o
g++ -o bag2 bag2.o
bag2.o:bag2.cpp
g++ -c bag2.cpp

运行结果:

Please input weight constrain of the bag:10
Please input number of kinds of goods:5
Please input 5 weight of goods:
2
2
6
5
4
Please input 5 value of goods:
6
3
5
4
6
The optimal value is: 15

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值