回溯法解决0-1背包问题
2015-06-06 15:04
399 查看
代码和分析如下:
#include<iostream> using namespace std; //回溯法求解0-1背包问题; //本题为了方便计算结果,已输入固定数值 int value[8]={11,21,31,33,43,53,55,65};//物品的价值 int weight[8]={1,11,21,23,33,43,45,55};//物品的重量 int M=110;//包重 double wv[8]; int y[8]; //数值 void wv_max(int weight[],int value[],double wv[],int n); void banapl(int x[],int M,int n,int *fv,int *fw); double bound(int v,int w,int k,int M,int n); void swap(int *a,int *b); void dswap(double *a,double *b); int main(){ int n=8; int i,j; M=110; for(int i=0;i<n;i++){ wv[i]=value[i]*1.0/weight[i]; } wv_max(weight,value,wv,n); int fw=0,fv=0; banapl(y,M,n,&fv,&fw); cout <<"-----------------------------------"<<endl; cout <<"数据编号 "<<"价值 "<<"重量 "<<"价值/重量"<<endl; cout <<"-----------------------------------"<<endl; for(int i=0;i<n;i++){ cout <<"第"<<i+1<<"组数据:| "<<value[i]<<" | "<<weight[i]<<" | "<<wv[i]<<endl; } cout <<"-----------------------------------"<<endl; cout <<"各物品占用情况: "; for(int i=0;i<n;i++){ cout <<y[i]<<" "; } cout<<endl; cout <<"总重量: "<<fv<<" 总价值: "<<fw<<endl; return 0; } //使用冒泡排序 void wv_max(int weight[],int value[],double wv[],int n){ for(int i=0;i<n-1;i++){ for(int j=n-2;j>=0;j--){ if(wv[j]<wv[j+1]){ swap(weight[j],weight[j+1]); swap(value[j],value[j+1]); dswap(&wv[j],&wv[j+1]); } } } } void banapl(int y[],int M,int n,int *fv,int *fw){ int cw=0,cv=0;//cw代表当前重量,cv代表当前价值 int k=0; int x[8]={0}; //用来标记对应数组下标的物品是否放入背包 *fv=-1; //进行初始化 while(true){ while(k<n&&cw+weight[k]<=M){ //在包不超重的前提下对物品进行装载 cv=cv+value[k]; cw=cw+weight[k]; x[k]=1; k=k+1; } if(k>=n){ *fw=cw; *fv=cv; for(int i=0;i<n;i++){ y[i]=x[i]; } }else{ x[k]=0; } while(bound(cv,cw,k,M,n)<=*fv){ //使用约束函数,一般情况下分数背包容量大于等于0-1背包,如果当前的分数背包容量都无法满足的话,只能回溯了 while(k!=0&&x[k]!=1){ //向上返回,返回到第一个装入包的物品位置上 k--; } if(k==0){ return; } x[k]=0; //进行回溯,向上返回,将上一个装入背包的物品取出,想象一下深度优先遍历 cw=cw-weight[k]; cv=cv-value[k]; } k=k+1; } } double bound(int v,int w,int k,int M,int n){//约束函数,类似于分数背包 double b=(double)v; int we=w; int i; for(i=k+1;i<n;i++){ we=we+weight[i]; if(we<M){ b=b+value[i]; }else{ return b+(1-(we-M)*1.0/weight[i])*value[i]; //类似于分数背包 } } return b*1.0; } void swap(int *a,int *b){ int temp; temp=*a; *a=*b; *b=temp; } void dswap(double *a,double *b){ double temp; temp=*a; *a=*b; *b=temp; }
相关文章推荐
- HDU 2896 病毒侵袭
- 文件与目录的默认权限与隐藏权限
- C++设计模式之中介者模式
- 高效能人士的七个习惯(读书笔记)
- BZOJ 1617: [Usaco2008 Mar]River Crossing渡河问题( dp )
- iis配置write模块
- Spring_SpringMVC_MyBaties框架搭建是 jdbc.properties文件注意事项
- IPv6
- apache配置php+多站点+多目录
- 集合框架和数据结构
- 论文核心思想总结
- C/C++
- 大型网站构架
- Linux and Shell
- JavaScript基础学习
- log4j与日志系统
- IO和NIO
- 堆排序java实现
- Hadoop基础学习
- opencv提取图像边缘特征sobel算子的运用