《趣学算法》 第五章 回溯法代码实现(Java)

5.2 0-1背包问题

import java.util.Scanner;

public class Test5_2 {
	
	static final int M=105;
	static int i,j,n,W;                                        //n表示n个物品,W表示购物车的容量
	static int[] w=new int[M];                                 //w[i]表示第i个物品的重量
	static int[] v=new int[M];                                 //v[i]表示第i个物品的价值
	static int cw,cp,bestp;
	static int[] x=new int[M];                                 //表示第i个物品是否放入购物车
	static int[] bestx=new int[M];                             //当前最优解
		
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入物品的个数n:");
		n=scanner.nextInt();
		System.out.println("请输入购物车的容量W:");
		W=scanner.nextInt();
		System.out.println("请依次输入每个物品的重量w和价值v,用空格分开:");
		for(i=1;i<=n;i++) {
			w[i]=scanner.nextInt();
			v[i]=scanner.nextInt();
		}
		knapsack(W,n);                                           //背包问题求解
		scanner.close();
	}
	
	public static void knapsack(int W,int n) {
		cw=0;                                                    //初始化当前放入购物车的物品重量为0
		cp=0;                                                    //初始化当前放入购物车的物品价值为0
		bestp=0;                                                 //初始化当前最优值为0
		int sumw=0;                                              //用来统计所有物品的总重量
		int sumv=0;                                              //用来统计所有物品的总价值
		for(i=1;i<=n;i++) {
			sumw+=w[i];
			sumv+=v[i];
		}
		if(sumw<=W) {                                            //所有物品可放入购物车
			bestp=sumv;
			System.out.println("放入购物车的物品最大价值为:"+bestp);
			System.out.println("所有的物品均放入购物车。");
			return;
		}
		
		backTrack(1);                                            //从第一层开始搜索 
		System.out.println("放入购物车的物品最大价值为:"+bestp);
		System.out.print("放入购物车的物品序号为:");
		for(i=1;i<=n;i++) {
			if(bestx[i]==1)
				System.out.print(i+" ");
		}
		System.out.println();
	}
	
	/*用于搜索空间数,t表示当前扩展结点在第t层*/
	public static void backTrack(int t) {
		if(t>n) {                                                //已经到达叶子结点,记录最优值最优解
			for(j=1;j<=n;j++) {                                  //保存最优解
				bestx[j]=x[j];
			}
			bestp=cp;
			return;                                              //保存当前最优值
		}
		
		if(cw+w[t]<=W) {                                         //如果满足约束条件则搜索左子树即放入物品
			x[t]=1;                                              //放入购物车
			cw+=w[t];                                            //购物车当前的重量增加
			cp+=v[t];                                            //购物车当前的价值增加
			backTrack(t+1);                                      //递推深度优先搜索第t+1层
			
			cw-=w[t];                                            //上向回归时要把增加的值减去
			cp-=v[t];
		}
		
		if(bound(t+1)>bestp) {                                   //如果满足限界条件则搜索右子树
			x[t]=0;                                              //不放入物品,当前放入物品重量价值均不改变
			backTrack(t+1);                                      //深度优先搜索第t+1层
		}
	}
	
	/*计算上界,即剩余物品的总价值*/
	public static int bound(int i) {                            
		int rp=0;       
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值