您的位置:首页 > 编程语言

0-1背包问题测试代码

2013-03-08 11:16 155 查看
package ww;

public class test {

void initial(int[] weight,int[] value,int n, int capacity)
{
int[][] maxvalue = new int
[capacity+1];
int[] trace = new int
;
maxvalue[0][0] = 0;
for(int j=1;j<=capacity;j++)
{
if(weight[0]<=j)
maxvalue[0][j] = value[0];
else
maxvalue[0][j] = 0;
}
ZeroOnePack(trace,maxvalue,weight,value,n-1,capacity);
print(weight,value,maxvalue,trace,n-1,capacity);

System.out.println("最大重量为:"+maxvalue[n-1][capacity]);
System.out.println("对应所选物品为:0表示没有选该物品,1表示选择了该物品");
for(int k=0;k<=n-1;k++)
System.out.println(trace[k]);
}
int ZeroOnePack(int[] trace,int[][] maxvalue,int[] weight,int[] value,int i,int j)
{
int x1=0,x2=0;
if(i>=1 && j>=0)
{
x1=ZeroOnePack(trace,maxvalue,weight,value,i-1,j);
x2=((j-weight[i])<0 ? 0:(ZeroOnePack(trace,maxvalue,weight,value,i-1,j-weight[i])+value[i]));
if( x1 > x2 )
return (maxvalue[i][j] = x1);
else
return (maxvalue[i][j] = x2);
}
else if(i==0 && j>=0)
return maxvalue[0][j];
return 0;
}

void print(int[] weight,int[] value,int[][] maxvalue,int[] trace,int i,int j)
{//顺序输出,结果为0表示这个物品没有选择。
if( i==0 && j>=0 && j-weight[i]>=0)
trace[0]=1;
else if( i>=1 && j>=0)
{
if(maxvalue[i-1][j] < maxvalue[i-1][j-weight[i]]+value[i])
trace[i] =1;
print(weight,value,maxvalue,trace,i-1,j-weight[i]);
}
}
public static void main(String args[])
{
int[] value= {6,10,12};
int[] weight={1,2,3};
int n = value.length;
test a = new test();
a.initial(weight,value,n,5);
System.out.println();
}
}

物品编号从0开始。

这里的物品编号是从0开始的。单单实现求得最大值相对容易,但是要输出最后最大值是选择了哪些物品才得到的稍微会有点困难。无论物品编号是从0开始还是从1开始对这个问题而言都是一样的。0-1背包问题的求最大值的递归式为:



这里的m[i][j]中的i表示的第i个物品,j表示的可以容纳的最大的重量,上公式的max内的第一样表示不把第i个物品放入容量为j的包中,后一项表示要放入。在最后输出最大值对应的选择的物品时,采用的方式和求解最大值时的方法一样,也是递归的进行。整个问题是从上到下的递归的求解。

0-1背包问题的动态规划解法和算法导论中的装配线调到问题有点类似,就一条装备线上而言,两者的相同点是对于一个点(装配点、物品)要么选择、要么不选择这样两种情况。也就是说最后的结果类似于000111101010011这样1断断续续出现的。这一点和矩阵乘法的动态规划的情况就不同,矩阵乘法的动态规划是连续的,也就是说不存在这样断开的情况,它的情况是知道所有的i等于j才停止。另外一个特点就是,他们都需要在递归式里,父问题总是对应着几种可能的子问题,然后从这几个子问题中找到一个最优的问题,而不是像矩阵乘法那样,通过对不同的切分点k来将问题分成两个子问题,然后找使得这个解最大的那个k作为父问题的最优解。从这两点来看,对于动态规划问题,我们可以先根据问题的解的情况大体给这个问题定一个位,这样可以会帮助我们分析找到递归式。

另外,最后在最优解对应的物品时,即输出路径结果,我觉得有两种方法,一种是在求解最大值的时候做记录,然后再利用递归式输出路径结果;一种是不做记录,而是在递归输出时利用求解最大值过程中的目标值如这里的m[i][j]来帮助求解结果。当然我觉得对于这个背包问题,后一种方式处理可能会好点,还没有想到如何在计算中做记录,然后再利用递归输出路径结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: