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

#include

using namespace std;

class Object;

template

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

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

Typep>

Typep Knap

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

Typep>

void Knap

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<

constrain of the bag:";

cin>>c;

cout<

kinds of goods:";

cin>>n;

if(n <= 0 || c <= 0)

{

cout<

arguments"<

return 0;

}

cout<

"<

weight of goods:"<

w = new int[n + 1];

w[0] = 0;

for(i = 1; i <= n; i++)

{

cin>>w[i];

}

cout<

"<

value of goods:"<

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<

"<

delete w;

delete v;

return 0;

}

template

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 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;

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值