0-1背包问题(回溯法)

用回溯发实现0-1背包问题,问题描述如下:

item

weights

values

A

50

200

B

30

180

C

45

225

D

25

200

E

5

50

提示:在使用回溯法解决0-1背包问题时,需要对物品进行一次排序,按照单位质量的价值从大到小进行,本实验由于给定数据,排序算法省略,直接使用排序后的结果

#include <iostream>
#include <stdlib.h>

using namespace std;

#define N 6
int W[N] = {0,5,25,30,45,50};
int P[N] = {0,50,200,180,225,200};
double BOUND(int p,int w,int k,int M)
//计算当前状态可以产生的最大价值 {
double b = p; int c = w; for(int i = k+1;i < N; i++) { c = c + W[i]; if(c < M) { b = b + P[i]; } else { return (b + (1-(c - M)/W[i])*P[i]); } } return b; } void BKNAP(int M,int n,int& fw,int& fp,int X[]) { int cw =0 , cp = 0;     //临时重量和临时价值 int k = 1;fp = -1;      //fp表示当前状态下0-1背包问题的最大值 int Y[N]; Y[0] = 0; while(true) { while(k <= n && cw + W[k] <= M) { cw = cw + W[k]; cp = cp + P[k]; Y[k] = 1; k = k + 1; } if(k > n)
     //此时已经得到一个满足条件的结果,所以将Y[]的值赋值给X[] { fp
= cp; fw = cw; k = n; for(int i = 1; i <= n; i++) X[i] = Y[i]; } else{ Y[k] = 0; } while(BOUND(cp,cw,k,M) <= fp) //如果当前状态下最大的价值情况都小于 fp ,就没有必要继续下去,回溯到最近没有遍历右孩子的节点去 { while(k != 0 && Y[k] != 1) k = k - 1; if(k == 0) return ; Y[k] = 0; cw = cw - W[k]; cp = cp - P[k]; } k = k+1; } } int main() { int X[N],result_p=0,result_w=0; BKNAP(100,N-1,result_w,result_p,X); cout<<result_w<<" "<<result_p<<endl; cout<<"("; for(int i =1; i< N; i++) { cout<<X[i]<<" "; } cout<<")"; return 0; }

结果输出:

posted on 2015-05-24 23:42  钟爱Code  阅读(471)  评论(0)    收藏  举报

导航