0-1背包问题
来源:互联网 发布:手机模拟期货软件 编辑:程序博客网 时间:2024/06/07 13:15
回溯法:
#include <iostream>#include <iomanip>using namespace std;int k = 0;//index 的序号int h = 0;//向上回溯了h个节点template <class Typew, class Typep>class Knap{friend Typep Knapsack(Typep*, Typew*, Typew, int);//private:public:Typep Bound(int i);void Backtrack(int i);Typew c; //背包容量int n; //物品数Typew *w;//物品重量数组Typep *p;//物品价值数组Typew cw;//当前重量Typep cp;//当前价值Typep bestp;//当前最优价值int *index;//满足条件的组合中物品号};//回溯函数template <class Typew, class Typep>void Knap<Typew, Typep>::Backtrack(int i) //i是当前节点{if (i > n) //到达叶子节点{bestp = cp;return;}if (cw + w[i] <= c) //进入左子树{cw += w[i];cp += p[i];k++; index[k] = i;Backtrack(i + 1);cw -= w[i];cp -= p[i];h++;//向上回溯了h个节点}if (Bound(i + 1)> bestp) //进入右子树{if(h>0) k -= h;Backtrack(i + 1);}}//节点上界template <class Typew, class Typep>Typep Knap<Typew, Typep>::Bound(int i){//上界函数 Typew cleft = c - cw;//剩余容量Typep b = cp; //当前价值//依次装入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>class Object{friend Typep Knapsack(Typep *, Typew *, Typew, int);public:int operator <=(Object a)const{return (d >= a.d);}Object& operator =(Object a){d = a.d;ID = a.ID;return *this;}//private:int ID;float d; //单位价值};//排序函数template <class Typew, class Typep>void Sort(Object<Typew, Typep> Q[], int n){Object<Typew, Typep> tempt;int flag;for (int i = 0; i < n; i++){flag = i;for (int j = i + 1; j < n; j++){if (Q[j].d > Q[flag].d) flag = j;}if (flag != i){tempt = Q[i];Q[i] = Q[flag];Q[flag] = tempt;}//cout << Q[i].ID << ":" << Q[i].d << endl;}}template <class Typew, class Typep>Typep Knapsack(Typep p[], Typew w[], Typew c, int n){//Backtrack的初始化Typew W = 0;Typep P = 0;Object<Typew, Typep> *Q = new Object<Typew, Typep>[n];for (int 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; //装入所有物品Sort(Q, n);Knap<Typew, Typep> K;K.p = new Typep[n + 1];K.w = new Typew[n + 1];K.index = new int[n + 1];for (int i = 1; i <= n; i++){K.p[i] = p[Q[i - 1].ID]; //cout<<i<<":"<<K.p[i]<<" ";K.w[i] = w[Q[i - 1].ID]; //cout<<i<<":"<<K.w[i]<<endl;K.index[i] = 0;}K.cp = 0;K.cw = 0;K.c = c;K.n = n;K.bestp = 0;//回溯搜索K.Backtrack(1);cout <<"可放入的物品列表:\n\n"<< "单位价值排名 " << "重量 " << "价值" << endl;for (int i = 1; i <= n; i++){if (K.index[i] != 0)cout <<setw(8)<< K.index[i] << " " << K.w[K.index[i]] << " " << K.p[K.index[i]] << endl;}delete[] Q;delete[] K.w;delete[] K.p;//delete[] K.index; //不知道为什么,有这个delete程序就没办法返回return K.bestp;}int main(){int c = 92;int n = 7;int p[8] = { 0, 55, 45, 65, 30, 40, 35, 30 };int w[8] = { 0, 15, 16, 15, 13, 20, 18, 14 };Knap<int, int> K;cout << "\n最多可装价值为: "<<Knapsack<int, int>(p, w, c, n)<<endl;return 0;}
阅读全文
0 0
- 背包问题(0-1背包、完全背包、多重背包)详解
- 背包问题和0-1背包问题
- 背包问题和0-1背包问题
- 背包问题系列--"0-1背包问题"
- 背包笔记-含0/1背包问题、完全背包问题、多重背包问题、二维背包问题、分组背包问题
- 【背包问题】背包问题之0-1背包、完全背包、多重背包
- 0-1背包问题
- 0/1背包问题
- 0,1背包问题
- 0-1背包问题
- 0/1背包问题
- 0-1背包问题
- // 0-1背包问题
- 0/1背包问题
- 0-1背包问题
- 0-1背包问题
- 0-1背包问题
- 0/1背包问题
- SSM环境搭建(三)
- 【软考】七层网络构架总结
- 【软考】校验码
- 12. 图的广度优先遍历
- Java集合框架上机练习题-2
- 0-1背包问题
- easyui之layout布局之后无法显示
- 【软考】单链表,双链表,循环链表
- win工程
- (转)你确定你的交易系统最快?
- Kotlin学习中触碰到的知识点
- HDU 2855
- 看看编程大牛们是怎么摆放桌面文件的
- Nginx的安装