第七周作业
2014-04-25 16:46
176 查看
(1)背包问题。对上文中提到的背包问题提供的表1,第一行为背包总重量15,物品数量5;第2-6行,分别为第1-5件物品的重量与价值),W=15,编程计算最终背包所装物品的编号、总重量与总价值。要求能够把构造的二维表格输出到文件KnapsackResult.txt中
import java.io.File; import java.io.PrintWriter; import java.util.Scanner; public class Knapsack { private int[] v;//存储物品的价值 private int[] w;//存储物品的重量 private int allWeight;//背包容纳重量 private int allNum;//物品数量 private int fValue[][];//fValue[i][j]存储前i个物品的重量为j的最大价值 public Knapsack(int allWeight,int allNum){ this.setAllNum(allNum); this.setAllWeight(allWeight); this.v=new int[allNum]; this.w=new int[allNum]; this.fValue=new int[allNum+1][allWeight+1]; } public int[] getV() { return v; } public void setV(int[] v) { this.v = v; } public int[] getW() { return w; } public void setW(int[] w) { this.w = w; } public int[][] getfValue() { return fValue; } public void setfValue(int[][] fValue) { this.fValue = fValue; } public static void main(String[] args) { String path="src/Knapsack.txt"; String resultPath="src/KnapsackResult.txt"; Scanner scanner=null; PrintWriter writer=null; try { scanner=new Scanner(new File(path)); writer=new PrintWriter(new File(resultPath)); int allWeight=scanner.nextInt();//背包所能容纳的总重量 int allNum=scanner.nextInt();//物品数量 Knapsack kna= new Knapsack(allWeight,allNum);//初始化背包 int[] v=kna.getV(); int[] w=kna.getW(); int[][] fvalue=kna.getfValue(); int i=1; for(i=1;i<=allNum;i++){//初始化物品价值数组和重量数组 w[i-1]=scanner.nextInt(); v[i-1]=scanner.nextInt(); } for(i=1;i<=allNum;i++){ fvalue[i][0]=0; } for(i=1;i<=allWeight;i++){ fvalue[0][i]=0; } for(i=1;i<=allNum;i++){ for(int j=1;j<=allWeight;j++){ if(j<w[i-1]){ fvalue[i][j]=fvalue[i-1][j]; }else{ fvalue[i][j]=Math.max(fvalue[i-1][j], fvalue[i-1][j-w[i-1]]+v[i-1]); } } } System.out.println("背包中物品的最大价值是:"+fvalue[allNum][allWeight]); kna.traceBack(v, w, fvalue, allWeight, allNum);//求出物品编号和背包总重量 System.out.println("构造的二维表格输出结果:"); for(i=1;i<=allNum;i++){ //输出二维数组到文本文件KnapsackResult.txt中 for(int j=1;j<=allWeight;j++){ System.out.print(fvalue[i][j]+" "); writer.print(fvalue[i][j]+" "); } System.out.println(); writer.println(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(scanner!=null) scanner.close(); if(writer!=null) writer.close(); } } /** * 回溯法逆序找到背包的物品编号 * @param v 存储物品的价值 * @param w 存储物品的重量 * @param fvalue fValue[i][j]存储前i个物品的重量为j的最大价值 * @param allWeight 背包容纳重量 * @param allNum 物品数量 */ public void traceBack(int[] v,int[] w,int[][] fvalue,int allWeight,int allNum){ int wupinNo[]=new int[allNum+1]; int j=allWeight; for(int i=allNum;i>0;i--){ if(fvalue[i][j]>fvalue[i-1][j]){ wupinNo[i]=1; j-=w[i-1]; if(j<0){ break; } } } int sumWeight=0;//记录背包的总重量 System.out.println("背包中物品的编号是:"); for(int i=1;i<=allNum;i++){ if(wupinNo[i]==1){ System.out.print(i+" "); sumWeight+=w[i-1]; } } System.out.println(); System.out.println("背包的总重量是:"+sumWeight); } public void setAllWeight(int allWeight) { this.allWeight = allWeight; } public int getAllWeight() { return allWeight; } public void setAllNum(int allNum) { this.allNum = allNum; } public int getAllNum() { return allNum; } }