回溯法分支限界法解01背包问题计算机算法设计与分析实验报告.docx
《回溯法分支限界法解01背包问题计算机算法设计与分析实验报告.docx》由会员分享,可在线阅读,更多相关《回溯法分支限界法解01背包问题计算机算法设计与分析实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
![回溯法分支限界法解01背包问题计算机算法设计与分析实验报告.docx](https://file1.bdocx.com/fileroot1/2022-11/17/a3236367-c58b-4f4b-b666-2f262865fe3a/a3236367-c58b-4f4b-b666-2f262865fe3a1.gif)
回溯法分支限界法解01背包问题计算机算法设计与分析实验报告
回溯法、分支限界法解0-1背包问题(计算机算法设计与分析实验报告)
实验报告
课程名称:
算法设计与分析实验名称:
回溯法、分支限界法解0-1背包问题
任课教师:
张锦雄专业:
计算机科学与技术
班级:
2007级1班学号:
姓名:
蓝冠恒完成日期:
2011年1月12日
一、实验目的:
掌握回溯法、分支限界法的原理,并能够按其原理编程实现解决0-1背包问题,以加深对回溯法、分支限界法的理解。
二、主要实验内容及要求:
1.要求分别用回溯法和分支限界法求解0-1背包问题;
2.要求交互输入背包容量,物品重量数组,物品价值数组;
3.要求显示结果。
三、实验环境和工具:
操作系统:
win7操作系统
开发工具:
eclipse3.4、jdk1.6
开发语言:
java
四、实验结果与结论:
(经调试正确的源程序和程序的运行结果)
1.1、回溯法求解0-1背包问题源代码:
packagecn.lgh;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.util.Arrays;
importjava.util.Comparator;
/**
*回溯法解0-1背包问题。
*@author蓝冠恒
*/
publicclassBTKnapsack{
doublec;//背包重量
intn;//物品总数
double[]w;//物品重量数组
double[]p;//物品价值数组
doublecw;//当前重量
doublecp;//当前价值
doublebestp;//当前最优价值
/**
*回溯法解0-1背包问题。
*@parampp
*物品价值数组
*@paramww
*物品重量数组
*@paramcc
*背包重量
*@return最优价值
*/
publicdoubleknapsack(doublepp[],doubleww[],doublecc){
c=cc;
n=pp.length;
cw=0.0;
cp=0.0;
bestp=0.0;
Element[]q=newElement[n];
for(inti=0;iq[i]=newElement(i+1,pp[i]/ww[i]);
}
Arrays.sort(q,newElemComparator());
p=newdouble[n+1];
w=newdouble[n+1];
for(inti=1;i<=n;i++){
p[i]=pp[q[i-1].id-1];
w[i]=ww[q[i-1].id-1];
}
backtrack
(1);
returnbestp;
}
//回溯过程
privatevoidbacktrack(inti){
if(i>n){//达到叶节点
bestp=cp;
return;
}
if(cw+w[i]<=c){
cw+=w[i];
cp+=p[i];
backtrack(1+i);
cw-=w[i];
cp-=p[i];
}
if(bound(i+1)>bestp){
backtrack(1+i);
}
}
//计算上界值
privatedoublebound(inti){
doublecleft=c-cw;
doublebound=cp;
//以物品单位重量价值递减顺序装入物品
while(i<=n&&w[i]<=cleft){
cleft-=w[i];
bound+=p[i];
i++;
}
//装满背包
if(i<=n){
bound+=p[i]*cleft/w[i];
}
returnbound;
}
/**
*物体编号和单位重量价值载体。
*@author蓝冠恒
*/
publicclassElement{
intid;//编号
doubled;//单位重量价值
publicElement(intid,doubled){
this.id=id;
this.d=d;
}
}
/**
*比较器
*@author蓝冠恒
*/
publicclassElemComparatorimplementsComparator
publicintcompare(Objectobject1,Objectobject2){
Elementelement1=(Element)object1;
Elementelement2=(Element)object2;
if(element1.dreturn1;
}else{
return0;
}
}
}
publicstaticvoidmain(String[]args){
Stringinput;
Stringflag;
doublecapacity=0;
double[]pp;
double[]ww;
doublebestP=0.0;
BTKnapsackbtKnapsack=newBTKnapsack();
BufferedReaderin=newBufferedReader(newInputStreamReader(System.in));
do{
try{
do{
System.out.println("请选择数字功能键:
1--输入数据,2--退出系统");
flag=in.readLine().trim();
}while(!
(flag.equals("1")||flag.equals("2")));
if(flag.equals("2")){
break;
}
do{
System.out.println("请输入各物品重量,数据之间必须以顿号间隔分开!
");
input=in.readLine().trim();
input=in.readLine().replaceAll("","");
}while(input.equals(""));
if(input.equals("2")){
break;
}
Stringdatas[]=input.split("[、]");
intn1=datas.length;
pp=newdouble[n1];
ww=newdouble[n1];
for(inti=0;iww[i]=Double.parseDouble(datas[i]);
}
do{
System.out.println("请输入各物品价值,数据之间必须以顿号间隔分开!
");
input=in.readLine().trim();
input=in.readLine().replaceAll("","");
}while(input.equals(""));
if(input.equals("2")){
break;
}
datas=input.split("[、]");
intn2=datas.length;
if(n1!
=n2){
System.out.println("输入数据个数不一致,重新输入");
continue;
}
for(inti=0;ipp[i]=Double.parseDouble(datas[i]);
}
do{
System.out.println("请输入背包的容量:
");
input=in.readLine().trim();
input=in.readLine().replaceAll("","");
}while(input.equals(""));
if(input.equals("2")){
break;
}
capacity=Double.parseDouble(input);
bestP=btKnapsack.knapsack(pp,ww,capacity);
System.out.println("回溯法解得最优价值:
"+bestP);
}catch(Exceptione){
e.printStackTrace();
}
}while(true);
}
}
1.2、运行结果:
2.1、分支限界法求解0-1背包问题源代码:
packagecn.lgh;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.util.Arrays;
/**
*分支界限法解0-1背包问题。
*@author蓝冠恒
*/
publicclassBBKnapsack{
doublec;//背包重量
intn;//物品总数
double[]w;//物品重量数组
double[]p;//物品价值数组
doublecw;//当前重量
doublecp;//当前价值
int[]bestx;//最优解
MaxHeapmaxHeap=newMaxHeap();//活节点优先队列
//计算节点所对应的节点的上界
privatedoublebound(inti){
doublecleft=c-cw;
doubleb=cp;
//以物品单位重量价值递减装填剩余容量
while(i<=n&&w[i]<=cleft){
cleft-=w[i];
b+=p[i];