您的位置:首页 > 理论基础 > 数据结构算法

0 1背包问题

2015-10-13 17:35 363 查看
/***************************************/
/*     0/1背包问题(物体不可分割)     */
/*求装入背包的物体及其总价值           */
/***************************************/

#include<iostream>
#include<iomanip>
#define N  20    //最多物体个数
#define M  100  //最大背包载重量
using namespace std;

typedef struct{
float    w;			// 物体重量
float    p;			// 物体价值
float    v;			// 物体的价值重量比
} OBJECT;

int main(){
/*函数声明*/
void create_wuti(OBJECT T[], int t);
void bubble_sort(OBJECT A[], int n);
float knapsack_back(OBJECT ob[],float m,int n,bool x[]);

OBJECT	ob
;		//物体
float	m;			// 背包载重量
bool	x
;		// 可能的解向量

int n;
cout << "请输入物体个数n(不超过20)及背包载重量m(100)分别为:";
cin >> n >> m;

cout << "\n-----创建物体的重量及其价值-----";
create_wuti(ob,n);

int v = knapsack_back(ob,m,n,x);
cout << "\n背包中物体的最大价值为:" << v;
cout << "\n解向量为:";
for (int i = 0;i<n; i++)
cout << x[i] << " ";
cout<<endl<<endl;

system("pause");
return 0;
}

/*创建物体的重量及价值*/
void create_wuti(OBJECT T[], int t){
cout << "\n请输入物体的重量:";
for (int i = 0; i<t; i++)
cin >> T[i].w;

cout << "请输入物体的价值:";
for (int i = 0; i<t; i++)
cin >> T[i].p;
}

/*冒泡排序*/
void bubble_sort(OBJECT A[], int n){
OBJECT t;
for (int i = n - 1; i >0; i--){
for (int j = 0; j < i; j++){
if (A[j].v<A[j + 1].v){
t = A[j];
A[j] = A[j + 1];
A[j + 1] = t;
}
}
}
}

/*回溯法解0/1背包问题*/
float knapsack_back(OBJECT ob[ ], float m, int n,bool x[ ]){
float	p_est;		// 装入背包物体的估值
float	w_est;		// 装入背包物体的重量
float	p_total;	// 装入背包物体的价值上界
float	w_cur;		// 当前装入背包的物体的总重量
float	p_cur;		// 当前装入背包的物体的总价值
bool * y = new  bool[ n+1 ];
for (int j=0; j<n; j++) {		// 计算物体的价值重量比
ob[ j ].v = ob[ j ].p / ob[ j ].w;
y[ j ] = false;		// 当前的解向量初始化
}

bubble_sort(ob,n);		// 物体按价值重量比排序

int i,k = 0;
p_est=w_cur = p_cur = p_total = 0;		// 初始化
y
=false;

while (k >= 0){
w_est = w_cur;   p_est
4000
= p_cur;

for (i=k; i<n; i++){ 		// 计算最大估值
w_est = w_est + ob[ i ].w;
if (w_est < m)
p_est = p_est + ob[ i ].p;
else{
p_est+=((m-w_est+ob[ i ].w)/ob[ i ].w)*ob[i].p;
break;
}
}

if (p_est>p_total){ 		// 估计值大于上界
for (i=k; i<n; i++){
if (w_cur+ob[ i ].w <= m){ // 可装入第 i 个物体
w_cur = w_cur + ob[ i ].w;
p_cur = p_cur + ob[ i ].p;
y[ i ] = true;
}
else{
y[ i ] =false;   break;	// 不能装入第 i 个物体
}
}
if ( i >= n-1){ 			// n个物体已全部装入
if (p_cur > p_total){
p_total = p_cur;   k = n;    // 刷新当前上限
for (i=0; i<n; i++)
x[ i ] = y[ i ];        // 保存可行的解
}
}
else k = i + 1;			// 继续装入其余物体
}

else{ 		      // 估计价值小于当前上限,即if (p_est<=p_total)
while ((i >= 0)&&(y[ i ] == 0))	// 沿右分支回溯
i--;			      // 直到左分支结点
if (i<0)  break;		    // 已到达根结点,算法结束
else{
w_cur = w_cur-ob[ i ].w;	 // 修改当前值50
p_cur = p_cur-ob[ i ].p;
y[ i ] =false;
k = i + 1;	      // 搜索右分支子树
}
}
}

delete y;
return p_total;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  代码 数据结构 算法