当前位置:首页 » 编程语言 » 背包问题java

背包问题java

发布时间: 2022-06-27 08:27:44

❶ 关于这个java语言描述的0-1背包问题是否有错误

有点问题:
public static void knapsack(int[]v,int[]w,int c,int[][]m)
{
int n=v.length-1;
int jMax=Math.min(w[n]-1,c);
for(int j=0;j<=jMax;j++)
m[n][j]=0;
for(int j=w[n];j<=c;j++)
m[n][j]=v[n];
for(int i=n-1;i>1;i--)
{
jMax=Math.min(w[i]-1,c);
for(int j=0;j<=jMax;j++)
m[i][j]=m[i+1][j];
for(int j=w[i];j<=c;j++)
m[i][j]=Math.max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
}
m[1][c]=m[2][c];
if(c>=w[1])
m[1][c]=Math.max(m[1][c],m[2][c-w[1]]+v[1]);
}
public static void traceback(int[][]m,int[]w,int c,int[]x)
{
int n=w.length-1;
for(int i=1;i<n;i++) {
if(m[i][c]==m[i+1][c])x[i]=0;
else {
x[i]=1;
c-=w[i];
}
x[n]=(m[n][c]>0)?1:0;
}

//int n=w.length-1;
for(int i=1;i<n;i++)
if(m[i][c]==m[i+1][c])x[i]=0;
else {
x[i]=1;
c-=w[i];
}
x[n]=(m[n][c]>0)?1:0;
}

❷ java语言,背包问题,从Excel表中读取数据

基本概念
问题雏形
01背包题目的雏形是:
有N件物品和一个容量为V的背包。第i件物品的体积是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
从这个题目中可以看出,01背包的特点就是:每种物品仅有一件,可以选择放或不放。
其状态转移方程是:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
对于这方方程其实并不难理解,方程之中,现在需要放置的是第i件物品,这件物品的体积是c[i],价值是w[i],因此f[i-1][v]代表的就是不将这件物品放入背包,而f[i-1][v-c[i]]+w[i]则是代表将第i件放入背包之后的总价值,比较两者的价值,得出最大的价值存入现在的背包之中。
理解了这个方程后,将方程代入实际题目的应用之中,可得
for (i = 1; i <= n; i++)
for (j = v; j >= c[i]; j--)//在这里,背包放入物品后,容量不断的减少,直到再也放不进了
f[i][j] = max(f[i - 1][j], f[i - 1][j - c[i]] + w[i]);

问题描述
求出获得最大价值的方案。
注意:在本题中,所有的体积值均为整数。
算法分析
对于背包问题,通常的处理方法是搜索。
用递归来完成搜索,算法设计如下:
int make(int i, int j)//处理到第i件物品,剩余的空间为j 初始时i=m , j=背包总容量
{
if (i == 0) return 0;
if (j >= c[i])//(背包剩余空间可以放下物品 i )
{
int r1 = make(i - 1, j - w[i]);//第i件物品放入所能得到的价值
int r2 = make(i - 1, j);//第i件物品不放所能得到的价值
return min(r1, r2);
}
return make(i - 1, j);//放不下物品 i
}
这个算法的时间复杂度是O(n^2),我们可以做一些简单的优化。
由于本题中的所有物品的体积均为整数,经过几次的选择后背包的剩余空间可能会相等,在搜索中会重复计算这些结点,所以,如果我们把搜索过程中计算过的结点的值记录下来,以保证不重复计算的话,速度就会提高很多。这是简单的“以空间换时间”。
我们发现,由于这些计算过程中会出现重叠的结点,符合动态规划中子问题重叠的性质。
同时,可以看出如果通过第N次选择得到的是一个最优解的话,那么第N-1次选择的结果一定也是一个最优解。这符合动态规划中最优子问题的性质。
解决方案
考虑用动态规划的方法来解决,这里的:
阶段:在前N件物品中,选取若干件物品放入背包中
状态:在前N件物品中,选取若干件物品放入所剩空间为W的背包中的所能获得的最大价值
决策:第N件物品放或者不放
由此可以写出动态转移方程:
我们用f[i][j]表示在前 i 件物品中选择若干件放在已用空间为 j 的背包里所能获得的最大价值
f[i][j] = max(f[i - 1][j - W[i]] + P[i], f[i - 1][j]);//j >= W[ i ]
这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[v];如果放第i件物品,那么问题就转化为“前i-1件物品放入已用的容量为c的背包中”,此时能获得的最大价值就是f[c]再加上通过放入第i件物品获得的价值w。
这样,我们可以自底向上地得出在前M件物品中取出若干件放进背包能获得的最大价值,也就是f[m,w]
算法设计如下:
int main()
{
cin >> n >> v;
for (int i = 1; i <= n; i++)
cin >> c[i];//价值
for (int i = 1; i <= n; i++)
cin >> w[i];//体积
for (int i = 1; i <= n; i++)
f[i][0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= v; j++)
if (j >= w[i])//背包容量够大
f[i][j] = max(f[i - 1][j - w[i]] + c[i], f[i - 1][j]);
else//背包容量不足
f[i][j] = f[i - 1][j];
cout << f[n][v] << endl;
return 0;
}

由于是用了一个二重循环,这个算法的时间复杂度是O(n*w)。而用搜索的时候,当出现最坏的情况,也就是所有的结点都没有重叠,那么它的时间复杂度是O(2^n)。看上去前者要快很多。但是,可以发现在搜索中计算过的结点在动态规划中也全都要计算,而且这里算得更多(有一些在最后没有派上用场的结点我们也必须计算),在这一点上好像是矛盾的。

❸ 回溯法解决0-1背包问题 java写的 求大神指点~~~~(>_<)~~~~

因为你把n和c 定义为static ,而且初始化为0,。数组也为静态的,一个类中静态的变量在这个类加载的时候就会执行,所以当你这类加载的时候,你的数组static int[] v = new int[n];
static int[] w = new int[n];
就已经初始化完毕,而且数组大小为0。在main方法里动态改变n的值是改变不了已经初始化完毕的数组的大小的,因为组已经加载完毕。

我建议你可以在定义n,c是就为其赋初值。比如(static int n=2 static int c=3)

❹ Java版的背包问题

因为 要求找出所有满足上述条件的解
所以 全排列组合 来一遍。

❺ 0-1背包问题java代码

importjava.io.BufferedInputStream;
importjava.util.Scanner;

publicclasstest{
publicstaticint[]weight=newint[101];
publicstaticint[]value=newint[101];

publicstaticvoidmain(String[]args){
Scannercin=newScanner(newBufferedInputStream(System.in));
intn=cin.nextInt();
intW=cin.nextInt();
for(inti=0;i<n;++i){
weight[i]=cin.nextInt();
value[i]=cin.nextInt();
}
cin.close();
System.out.println(solve(0,W,n));//普通递归
System.out.println("=========");
System.out.println(solve2(weight,value,W));//动态规划表
}

publicstaticintsolve(inti,intW,intn){
intres;
if(i==n){
res=0;
}elseif(W<weight[i]){
res=solve(i+1,W,n);
}else{
res=Math.max(solve(i+1,W,n),solve(i+1,W-weight[i],n)+value[i]);
}
returnres;
}

publicstaticintsolve2(int[]weight,int[]value,intW){
int[][]dp=newint[weight.length+1][W+1];
for(inti=weight.length-1;i>=0;--i){
for(intj=W;j>=0;--j){
dp[i][j]=dp[i+1][j];//从右下往左上,i+1就是刚刚记忆过的背包装到i+1重量时的最大价值
if(j+weight[i]<=W){//dp[i][j]就是背包已经装了j的重量时,能够获得的最大价值
dp[i][j]=Math.max(dp[i][j],value[i]+dp[i+1][j+weight[i]]);
//当背包重量为j时,要么沿用刚刚装的,本次不装,最大价值dp[i][j],要么就把这个重物装了,那么此时背包装的重量为j+weight[i],
//用本次的价值value[i]加上背包已经装了j+weight[i]时还能获得的最大价值,因为是从底下往上,刚刚上一步算过,可以直接用dp[i+1][j+weight[i]]。
//然后选取本次不装weight[i]重物时获得的最大价值以及本次装weight[i]重物获得的最大价值两者之间的最大值
}
}
}
returndp[0][0];
}
}

❻ 背包问题,头搞大了!网上的代码

我给你注释了下,希望你能理解到。

import java.util.Scanner;
public class Backpack{
static float[] weight=new float[100];
static boolean[] flag = new boolean[100];
static boolean fl=false;
static int nn;
public static int Knap(float sum,int n) {

int i;
if (sum==0) { 我输入总体积为0时,不管物品和物品体积输什么,什么都
for(i=0;i<nn;i++){ 不提示程序就结束了,没搞懂这段代码的含义
//你这里直接结束的原因在于你的sum为0,但是你的flag数组里面全部是false, 凡是定义boolean类型的,java默认为false,
//所以这里的for循环当sum在你第一次sum=0的时候是永远不会执行的,所以总体积为0的时候就直接跳入System.out.println();返回1,程序返回1正常结束。但是当你开始处理了背包的时候随着flag数组里面的值变化(不超过n个物体的下标),这里循环开始慢慢执行的。
if(flag[i]) {
System.out.print("选择");
System.out.println(weight[i]);
}
}
System.out.println();
fl=true;
return 1;
}
else if (sum<0||(sum>0&&n<0))
return 0;

//即就是拿了最后输入的那个背包的重量,凡是已经拿取得背包,将对应的flag数组元素标记为true
flag[n]=true; 为什么这里flag[]变为true?
//减去最后输入的背包重量,用剩下的n-1个来完成递归调用,一直到sum ==0,或者sum < 0 || sum >0 &&n <0为止
i=Knap(sum-weight[n],n-1); 这个是什么含义?
//如果不能满足上面的条件,也就是说用第n个背包作为第一个结果算组合失败,所以抛弃最后一个背包(第n个)
flag[n]=false; 为什么又变成false了?
//将重量重置为起始重量,从倒数第二个背包开始重新递归计算
i=Knap(sum,n-1); 这个又是什么意思?

if(fl)
return 1;
return 0;

}
public static void main(String[] args){

float sum;
System.out.println("背包总体积:");
Scanner s = new Scanner(System.in);
sum = s.nextFloat();
System.out.println("物品件数:");
nn = s.nextInt();
System.out.println("输入物品的体积:");
for (int i=0; i<nn; i++)
weight[i] = s.nextFloat();

if (Knap(sum,nn-1)==0)
System.out.println("无解");
}
}

Jseven_jy 的问题出在他的程序譬如你输入物品件数3的时候你只能输入3个重量。
譬如
10
3
1
4
5
你那个有6个,他的程序没有处理到。所以出错。算是bug一个。

Jseven_jy : 看不到信息,公司封了只能开到知道和贴吧。其他的全部看不到。

❼ JAVA背包问题,对于我十万火急!!!!!!求救!!!!求救!!!!

public class Beibao {

/**
* @param args
*/
static int lenth = 5;
static int T = 10;
static int w[]= {2,4,6,8,10};
static int already = 0;
static int a[]= {0,0,0,0,0};
public static void go(int i)
{
if(already == T)
{
for(int j = 0;j< lenth;j++)
{
System.out.print(a[j]+" ");
}
System.out.println();
}
else
{
for(int m = i;m < lenth;m++)
{
if(a[m] == 0 && already + w[m] <= T)
{
a[m] = 1;
already += w[m];
go(m+1);
a[m] = 0;
already -= w[m];
}
}
}
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
go(0);
}

}

❽ 01背包问题变种:从给定的N个正数中选取若干个数之和最接近M的JAVA写法

BIAS0:= (C-MA(C,2))/MA(C,2)*100;
BIAS1 := (C-MA(C,12))/MA(C,12)*100;
BIAS2 := (C-MA(C,26))/MA(C,26)*100;
BIAS3 := (C-MA(C,48))/MA(C,48)*100;
HXL:=V/CAPITAL*100;
D1:=INDEXC;
D2:=MA(D1,56);
DR2:=D1/D2<0.94;
E1:=(C-HHV(C,12))/HHV(C,12)*10;
E2:=(C-REF(C,26))/REF(C,26)*10;

热点内容
荣耀v6平板扩展存储 发布:2024-05-08 03:41:12 浏览:421
安卓手机为什么半年一更新 发布:2024-05-08 03:36:52 浏览:660
存储设备报价 发布:2024-05-08 02:22:01 浏览:554
定步长的算法 发布:2024-05-08 02:16:18 浏览:110
怎么使用pe口袋服务器 发布:2024-05-08 02:02:18 浏览:471
xml数据库c 发布:2024-05-08 02:01:46 浏览:456
仿知乎android 发布:2024-05-08 01:56:00 浏览:904
mysql编译参数 发布:2024-05-08 01:53:46 浏览:194
怎么看台式电脑配置生产日期 发布:2024-05-08 01:32:26 浏览:460
java基础培训学校 发布:2024-05-08 01:30:44 浏览:468