当前位置:文档之家› 回溯法、分支限界法解0-1背包问题(计算机算法设计与分析实验报告)

回溯法、分支限界法解0-1背包问题(计算机算法设计与分析实验报告)

this.d= d;
}
}
/**
*比较器
*@author蓝冠恒
*/
publicclassElemComparatorimplementsComparator<Object> {
publicintcompare(Object object1, Object object2) {
Element element1 = (Element) object1;
if(input.equals("2")){
break;
}
String datas[] = input.split("[、]");
intn1 = datas.length;
pp=newdouble[n1];
ww=newdouble[n1];
for(inti = 0; i < n1; i++) {
ww[i]= Double.parseDouble(datas[i]);
//计算节点所对应的节点的上界
privatedoublebound(inti) {
doublecleft =c-cw;
doubleb =cp;
//以物品单位重量价值递减装填剩余容量
while(i <=n&&w[i] <= cleft) {
cleft -=w[i];
b +=p[i];
i++;
}
//装填剩余容量装满背包
cp= 0.0;
bestp= 0.0;
Element[] q =newElement[n];
for(inti = 0; i <n; i++) {
q[i] =newElement(i + 1, pp[i] / ww[i]);
}
Arrays.sort(q,newElemComparator());
p=newdouble[n+ 1];
c= cc;
n= pp.length;
Element[] q =newElement[n];
doublews = 0.0;
doubleps = 0.0;
for(inti = 0; i <n; i++) {
q[i] =newElement(i + 1, pp[i] / ww[i]);
ps += pp[i];
privatedoublebound(inti) {
doublecleft =c-cw;
doublebound =cp;
//以物品单位重量价值递减顺序装入物品
while(i <=n&&w[i] <= cleft) {
cleft -=w[i];
bound +=p[i];
i++;
}
//装满背包
if(i <=n) {
break;
}
datas= input.split("[、]");
intn2 = datas.length;
if(n1!=n2){
System.out.println("输入数据个数不一致,重新输入");
continue;
}
for(inti = 0; i < n1; i++) {
pp[i]= Double.parseDouble(datas[i]);
BBnode enode =null;
inti = 1;
doublebestp = 0.0;
doubleup = bound(1);
while(i !=n+ 1) {
doublewt =cw+w[i];
//检查当前扩展节点的左儿子节点
if(wt <=c) {
if(cp+p[i] > bestp) {
Element element2 = (Element) object2;
if(element1.d< element2.d) {
return1;
}else{
return0;
}
}
}
publicstaticvoidmain(String[] args) {
String input;
{
b +=p[i] /w[i] * cleft;
}
returnb;
}
//添加新的活节点到子集树和优先队列中
privatevoidaddLiveNode(doubleupperProfit,doublepp,doubleww,
intlevel, BBnode parent,booleanleftChild) {
BBnode b =newBBnode(parent, leftChild);
HeapNode node =newHeapNode(b, upperProfit, pp, ww, level);
maxHeap.put(node);
}
//优先队列式分支界限法
privatedoublebbKnapsack() {
}
}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();//活节点优先队列
break;
}
capacity=Double.parseDouble(input);
bestP=btKnapsack.knapsack(pp, ww, capacity);
System.out.println("回溯法解得最优价值:"+bestP);
}catch(Exception e) {
e.printStackTrace();
实验报告
课程名称:算法设计与分析实验名称:回溯法、分支限界法解0-1背包问题
任课教师:张锦雄专业:计算机科学与技术
班级:2007级1班学号:
姓名:蓝冠恒完成日期:2011年1月12日
一、实验目的:
掌握回溯法、分支限界法的原理,并能够按其原理编程实现解决0-1背包问题,以加深对回溯法、分支限界法的理解。
}
do{
System.out.println("请输入背包的容量:");
input = in.readLine().trim();
input = in.readLine().replaceAll(" ","");
}while(input.equals(""));
if(input.equals("2")){
*回溯法解0-1背包问题。
*@parampp
*物品价值数组
*@paramww
*物品重量数组
*@paramcc
*背包重量
*@return最优价值
*/
publicdoubleknapsack(doublepp[],doubleww[],doublecc) {
c= cc;
n= pp.length;
cw= 0.0;
bestx[j] = (enode.leftChild) ? 1 : 0;
enode = enode.parent;
}
returncp;
}
/**
*将个物体依其单位重量价值从大到小排列,然后调用bbKnapsack完成对子集树优先队列式分支界
*限搜索。
*
*@return最优解
*/
publicdoubleknapsack(double[] pp,double[] ww,doublecc,int[] xx) {
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) {
二、主要实验内容及要求:
1.要求分别用回溯法和分支限界法求解0-1背包问题;
2.要求交互输入背包容量,物品重量数组,物品价值数组;
3.要求显示结果。
三、实验环境和工具:
操作系统:win7操作系统
开发工具:eclipse3.4、jdk1.6
开发语言:java
四、实验结果与结论:(经调试正确的源程序和程序的运行结果)
break;
}
do{
System.out.println("请输入各物品重量,数据之间必须以顿号间隔分开!");
input = in.readLine().trim();
input = in.readLine().replaceAll(" ","");
相关主题