加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

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

(2011-12-07 15:35:11)
标签:

节点

最优值

左子树

utf-8

回溯

杂谈

    使用了不太需要的模板来写,而且,因为没有能够找到能在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

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有