第7周作业1——背包问题

1)背包问题。对上文中提到的背包问题提供的表1(数据文件下载,第一行为背包总重量15,物品数量5;第2-6行,分别为第1-5件物品的重量与价值),W=15,编程计算最终背包所装物品的编号、总重量与总价值。要求能够把构造的二维表格输出到文件KnapsackResult.txt中。


书本P184~186

背包问题存在两个版本,一种是每种物品的数量是无限的多副本的背包问题和每种物品都只有一件的单副本的背包问题,两种问题的解决思路都不相同。

多副本的背包问题的具体算法描述为:

K0=0

for w=1 to W

      k(w)=max(k(w-wi)+vi:wi<w)

return k(W)

单副本的背包问题的算法描述为:

Initialize all k(0,j)=0 and all k(w,0)=0

for j=1 to n:

  for w=1 to W:

    if wj>w:k(w,j)=K(w,j-1)

    else :k(w,j)=max{k(w,j-1),k(w-wj,j-1)+vj}

return k(W,n)

  1. package pack;  
  2.   
  3. import java.io.File;    
  4. import java.io.FileNotFoundException;    
  5. import java.io.PrintWriter;    
  6. import java.util.Scanner;    
  7.     
  8. public class Knapsack {    
  9.     
  10.     private int[] v;//存储物品的价值    
  11.     private int[] w;//存储物品的重量     
  12.     private int allWeight;//背包容纳重量    
  13.     private int allNum;//物品数量    
  14.     private int fValue[][];//fValue[i][j]存储前i个物品的重量为j的最大价值    
  15.     public Knapsack(int allWeight,int allNum){    
  16.         this.allNum=allNum;    
  17.         this.allWeight=allWeight;    
  18.         this.v=new int[allNum];    
  19.         this.w=new int[allNum];    
  20.         this.fValue=new int[allNum+1][allWeight+1];    
  21.     }    
  22.         
  23.     public int[] getV() {    
  24.         return v;    
  25.     }    
  26.     
  27.     public void setV(int[] v) {    
  28.         this.v = v;    
  29.     }    
  30.     
  31.     public int[] getW() {    
  32.         return w;    
  33.     }    
  34.     
  35.     public void setW(int[] w) {    
  36.         this.w = w;    
  37.     }    
  38.     
  39.     public int[][] getfValue() {    
  40.         return fValue;    
  41.     }    
  42.     
  43.     public void setfValue(int[][] fValue) {    
  44.         this.fValue = fValue;    
  45.     }    
  46.     public static void main(String[] args) {    
  47.         String path="E:\\Knapsack.txt";    
  48.         String resultPath="E:\\KnapsackResult.txt";    
  49.         Scanner scanner=null;    
  50.         PrintWriter writer=null;    
  51.         try {    
  52.             scanner=new Scanner(new File(path));    
  53.             writer=new PrintWriter(new File(resultPath));    
  54.             int allWeight=scanner.nextInt();//背包总重量    
  55.             int allNum=scanner.nextInt();//物品数量    
  56.             Knapsack kna= new Knapsack(allWeight,allNum);//初始化背包    
  57.             int[] v=kna.getV();    
  58.             int[] w=kna.getW();    
  59.             int[][] fvalue=kna.getfValue();    
  60.             int i=1;    
  61.             for(i=1;i<=allNum;i++){//初始化物品价值数组和重量数组    
  62.                  w[i-1]=scanner.nextInt();    
  63.                  v[i-1]=scanner.nextInt();    
  64.             }    
  65.             for(i=1;i<=allNum;i++){    
  66.                 fvalue[i][0]=0;    
  67.             }    
  68.             for(i=1;i<=allWeight;i++){    
  69.                 fvalue[0][i]=0;    
  70.             }    
  71.             for(i=1;i<=allNum;i++){    
  72.                 for(int j=1;j<=allWeight;j++){    
  73.                     if(j<w[i-1]){    
  74.                         fvalue[i][j]=fvalue[i-1][j];    
  75.                     }else{    
  76.                         fvalue[i][j]=Math.max(fvalue[i-1][j], fvalue[i-1][j-w[i-1]]+v[i-1]);    
  77.                     }    
  78.                 }    
  79.             }    
  80.                 
  81.             System.out.println("背包中物品的最大价值是:"+fvalue[allNum][allWeight]);    
  82.             kna.traceBack(v, w, fvalue, allWeight, allNum);//求出物品编号和背包总重量    
  83.             System.out.println("构造的二维表格输出结果:");    
  84.             for(i=1;i<=allNum;i++){//输出二维数组到文本文件KnapsackResult.txt中    
  85.                 for(int j=1;j<=allWeight;j++){    
  86.                     System.out.print(fvalue[i][j]+" ");    
  87.                     writer.print(fvalue[i][j]+" ");    
  88.                 }    
  89.                 System.out.println();    
  90.                 writer.println();    
  91.             }    
  92.         } catch (Exception e) {    
  93.         
  94.             e.printStackTrace();    
  95.         }finally{    
  96.             if(scanner!=null) scanner.close();    
  97.             if(writer!=null)  writer.close();    
  98.         }    
  99.     }       
  100.       
  101.     public void traceBack(int[] v,int[] w,int[][] fvalue,int allWeight,int allNum){    
  102.         int wupinNo[]=new int[allNum+1];    
  103.         int j=allWeight;    
  104.         for(int i=allNum;i>0;i--){    
  105.             if(fvalue[i][j]>fvalue[i-1][j]){    
  106.                 wupinNo[i]=1;    
  107.                 j-=w[i-1];    
  108.                 if(j<0){    
  109.                     break;    
  110.                 }    
  111.             }    
  112.         }    
  113.         int sumWeight=0;//记录背包的总重量    
  114.         System.out.println("背包中物品的编号是:");    
  115.         for(int i=1;i<=allNum;i++){    
  116.             if(wupinNo[i]==1){    
  117.                 System.out.print(i+" ");    
  118.                 sumWeight+=w[i-1];    
  119.             }    
  120.         }    
  121.         System.out.println();    
  122.         System.out.println("背包的总重量是:"+sumWeight);    
  123.     }    
  124. }    



 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值