01背包问题_回溯法_java实现

原创 2012年03月22日 18:55:57
问题描述:


需对容量为的背包进行装载。从个物品中选取装入背包的物品,每件物品的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。

输入:

多个测例,每个测例的输入占三行。第一行两个整数:nn<=10)和c,第二行n个整数分别是w1wn,第三行n个整数分别是p1pn
和 都等于零标志输入结束。

输出:

每个测例的输出占一行,输出一个整数,即最佳装载的总价值

输入样例:

1 2
1
1
2 3
2 2
3 4
0 0

输出样例:

1

4

//回溯法实现01背包问题

import java.util.Scanner;
public class Main
{
static int c;
static int n;
static int []w;
static int []p;
static int cw;
static int cp;
static int bestp;
public static void main(String args[])
{

Scanner s=new Scanner(System.in);
//n=Integer.parseInt(s.next());
//c=Integer.parseInt(s.next());
while(s.hasNext())
{
String line=s.nextLine();//读入c和n
String[] sArray=line.split(" ");
n=Integer.parseInt(sArray[0]);
c=Integer.parseInt(sArray[1]);
if(n==0&&c==0)
return;
if(n==0)
{
System.out.println(0);
continue;
}

line=s.nextLine();//读入w的行
sArray=line.split(" ");
w=new int[sArray.length];
for(int j=0;j<sArray.length;j++)
{
w[j]=Integer.parseInt(sArray[j]);
}

line=s.nextLine();//读入p的行
sArray=line.split(" ");
p=new int[sArray.length];
for(int j=0;j<sArray.length;j++)
{
p[j]=Integer.parseInt(sArray[j]);
}
System.out.println((Knapsack(p,w,c)));
}

}//Main

///////////////////////////////////////////////////////////////////////////////////////////////     
private static class Element implements Comparable
{
int id;//物品编号
double d;
private Element(int idd,double dd)
{
id=idd;
d=dd;
}
public int CompareTo(Object x)
{
double xd=((Element)x).d;
if(d<xd)return -1;
if(d==xd)return 0;
return 1;
}
public boolean equals(Object x)
{
return d==((Element)x).d;
}
public int compareTo(Object arg0) {
// TODO Auto-generated method stub
return 0;
}
}//Element

////////////////////////////////////////////////////////////////////////////////////////////////////     

///////////////////////////////////////////////////////////////////////////////////////////////
public static int Knapsack(int []pp,int []ww,int cc)
{
c=cc;
n=pp.length-1;
//n=pp.length;
cw=0;
cp=0;
bestp=0;
Element []q=new Element[n+1];

//for(int i=1;i<=n;i++)
//q[i-1]=new Element(i,pp[i]/ww[i]);
for(int i=0;i<=n;i++)
q[i]=new Element(i,pp[i]/ww[i]);
//对q[]从大到小排序
for(int m=0;m<q.length;m++)
{
for(int j=m+1;j<q.length;j++)
{
if(q[m].d<q[j].d)
{
//                             int temp=m;
//                             m=j;
//                             j=temp;
int temp1=q[m].id;
q[m].id=q[j].id;
q[j].id=temp1;

double temp2=q[m].d;
q[m].d=q[j].d;
q[j].d=temp2;
}
}
}

p=new int[n+1];
w=new int[n+1];

for(int j=0;j<=n;j++)
{
p[j]=pp[q[j].id];
w[j]=ww[q[j].id];
}

backtrack(0);
return bestp;
}//knapsnack
static void backtrack(int i)
{
if(i>n)
{
bestp=cp;
return;
}
if(cw+w[i]<=c)
{
cw+=w[i];
cp+=p[i];
backtrack(i+1);
cw-=w[i];
cp-=p[i];
}
if(bound(i+1)>bestp)
backtrack(i+1);
}//backtrack
private static double bound(int i)
{
double cleft=c-cw;
double bound=cp;

while(i<=n&&w[i]<=cleft)
{
cleft-=w[i];
bound+=p[i];
i++;
}
if(i<=n)
bound+=p[i]*cleft/w[i];
return bound;
}//bound
}


回溯算法_01背包问题_Java实现

回溯算法也叫试探法,通俗的将就是一个方向的路一直往前走,能走则走,不能走则退回来换一个方向再试。一般的实现步骤是:针对一个问题定义解的空间,至少包含问题的一个最优解;用易于搜索的解空间结构,使得能用回...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

01背包问题(回溯法实现,java)

上两天学习的回溯算法,老师让我们回溯法来解决01背包问题, 经过了几天的改改增增,终于实现成功了。 自我感觉回溯算法思想,从左到右,一步一步,能走则走,不能则过! 下面直接贴代码,代码上详细注释...
  • anLA_
  • anLA_
  • 2015年10月30日 19:57
  • 1981

Java语言描述:回溯法之01背包问题(最易理解的回溯法讲解)

问题描述: 已知:有一个容量为V的背包和N件物品,第i件物品的重量是weight[i],收益是cost[i]。 限制:每种物品只有一件,可以选择放或者不放 问题:在不超过背包容量的情况下,最多能获得多...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Java实现回溯法解决0-1背包问题

description 给定n种物品和一个背包。物品i的重量是wi,价值为vi,背包的容量为C。问:应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

[HDU 1059] Dividing (多重背包+二进制优化)

链接HDU 1059题意给出6种硬币,价值分别为[1, 6],每种硬币有xi个,问是否能将这些硬币分为两组,每组硬币的价值为总价值的一半。题解是一种简化版的多重背包问题。先考虑这样一个问题,给出n个物...

01背包问题的动态规划算法、蛮力法和空间优化算法

算法思想: (1)、动态规划算法:解决背包物品价值最大化问题的最优解,是建立在每一个子问题的最优解的前提下完成的。设Value[i,j]表示的是i个物品放进背包容量为j的背包的价值,令i从0增至n(...

回溯法-01背包问题 java

  • 2010年05月28日 09:12
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:01背包问题_回溯法_java实现
举报原因:
原因补充:

(最多只允许输入30个字)