/*给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。 问应如何选择装入背包的物品,使得装入背包中物品的总价值最大? */ #include <iostream> using namespace std; #define MAXSIZE 100 #define TRUE 1 #define FALSE 0 #define ERROR -1 typedef float value; typedef float weight; typedef int KeyType; // 定义关键字类型为整数类型 typedef struct //元素定义 { weight w;//重量 value v;//价值 value q;//单位重量价值 int index;//序号 bool job;//表示是否被用 }Bag; typedef struct //定义背包集 { Bag r[MAXSIZE+1];//r[0]闲置或用作 “ 哨兵单元” int length; //背包个数 }Bags; int n;//包个数 int i;//辅助整型变量 weight c;//背包的容量 weight cw;//当前重量 value bestp=0;//当前最优价值 value cp;//当前价值 Bags L;//定义背包集 int Partition(Bags &L,int low,int high) //快速排序 // 交换顺序表L中子表r[low…..high]的记录,枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大于它. { int shuzhou; //定义枢轴 L.r[0]=L.r[low]; //用第一个记录作为枢轴记录 shuzhou=L.r[low].q; while(low<high) { while(low<high && L.r[high].q>=shuzhou) –high; L.r[low]=L.r[high]; while(low<high && L.r[low].q<=shuzhou) ++low; L.r[high]=L.r[low]; } L.r[low]=L.r[0]; return low; }//Partition void QuickSort(Bags &L,int low,int high) //快速排序 //对顺序表L[low ….high]作快速排序 { int shuzhou; if(low<high) { shuzhou=Partition(L,low,high); // 获得枢轴 QuickSort(L,low,(shuzhou-1)); //对枢轴前半部分排序 QuickSort(L,(shuzhou+1),high); //对枢轴后半部分排序 } }//QuickSort value bound(int i) {//计算上界 weight left=c-cw;//剩余容量 value bound=cp; //以物品单位重量价值递减顺序装入物品 while(i<=n&&L.r[i].w<=left) { left-=L.r[i].w; bound+=L.r[i].v; i++; } //装满背包 if(i<=n) bound+=L.r[i].v*left/L.r[i].w; return bound; }//bound void backtrack(int i) { if(i>n) {//到达叶子结点 bestp=cp; return ; } //搜索子树 if(cw+L.r[i].w<=c) {//进入左子树 cw+=L.r[i].w; cp+=L.r[i].v; //L.r[i].job=true;//选中 backtrack(i+1); cw-=L.r[i].w; cp-=L.r[i].v; //L.r[i].job=false;//未选中 } if(bound(i+1)>bestp)//进入右子树 backtrack(i+1); }//backtrack void knapsack(weight c)//0-1背包问题主算法 { QuickSort(L,1,L.length); backtrack(1);//回溯搜索 }//knapsack int main() { //输入要选择的背包信息 cout<<“请输入背包的容量:”; cin>>c; cout<<“请输入物品个数(注意:不能超过 100个!):”; cin>>n; if(n>100) { cout<<“你输入的物品个数太多!!!”<<endl; return FALSE; } L.length=n; for(i=1;i<=n;i++) { cout<<“请输入第个”<<i<<“物品的重量:”; cin>>L.r[i].w; cout<<“请输入第个”<<i<<“物品的价值:”; cin>>L.r[i].v; L.r[i].q=L.r[i].v/L.r[i].w;//单位重量价值 L.r[i].index=i;//索引号 cout<<endl; } //执行0-1背包问题主算法 knapsack(c); //输出结果 for(i=1;i<=n;i++) if(L.r[i].job) cout<<“第个”<<L.r[i].index<<“物品被选中”<<endl; cout<<“被选中的物品的总价值为: “<<bestp<<endl;; return TRUE; } /* 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]/w[i] * cleft; return b; } */ |