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; }
相关文章推荐
- android 代码实现控件之间的间距
- [Android]在代码里运行另一个程序的方法
- 肯特·贝克:改变人生的代码整理魔法
- 网页恶意代码的预防
- 动易2006序列号破解算法公布
- 高手写的Tracer-Flash代码调试类代码下载
- CSS代码缩写技巧
- 非主流Q-zOne代码代码搜集第1/2页
- Ruby实现的矩阵连乘算法
- CreateWeb.vbs 代码
- C#插入法排序算法实例分析
- Lua中编译执行代码相关的函数详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#数据结构揭秘一
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题