利用动态规划算法实现0-1背包问题(java实现)

利用动态规划算法实现0-1背包问题
要求:测试数据以文本文件的形式存储,即所有的数据由文本文件读入。

package Zero_one_Package;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;

public class Zero_one {
	public int packageweight;//背包的总容量
	public int productnum;//物品总数
	public ArrayList<Integer> weights;//每个物品的重量
	public ArrayList<Integer> values;//每个物品的价值
	
	public static void main(String[] args) throws Exception {
		Zero_one zero_one = new Zero_one();
		while(true){
			zero_one.readdata();// 读取测试文件中数据
			int[][] m = zero_one.initpkdata();//
			int[][] res = zero_one.result(m);
			System.out.print("背包总容量:");
			System.out.println(zero_one.packageweight);
			System.out.println("物品总数:"+zero_one.productnum);
			System.out.println("物品重量及价值对应关系:");
			for(int i = 0; i < zero_one.weights.size(); i++){
				System.out.print(zero_one.weights.get(i)+" ");
			}
			System.out.println();
			for(int i = 0; i < zero_one.values.size(); i++){
				System.out.print(zero_one.values.get(i)+" ");
			}
			System.out.println();
			System.out.println("           ");
			System.out.println("求解过程:");
			for (int i = 0; i < res.length; i++) {
				for (int j = 0; j < res[i].length; j++) {
					System.out.print(res[i][j]+"    ");
				}
				System.out.println();
			}
			System.out.println("           ");
			System.out.println("此时背包中最大价值总和为:"+res[zero_one.productnum][zero_one.packageweight]);
			System.out.print("装入背包中物品序号为:");
			zero_one.findproducts(res);
			System.out.println();
			System.out.println("           ");
		}
	}
	 
	public void readdata() throws Exception{//读取测试数据
		System.out.println("请输入数据编号(1~5):");
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		BufferedReader br = new BufferedReader(new FileReader("D:/Program Files (x86)/MyStudy/src/Zero_one_Package/input/input_assign02_0" + num + ".dat"));
		String string = br.readLine();
		this.packageweight = Integer.parseInt(string.split(" ")[0]);
		this.productnum = Integer.parseInt(string.split(" ")[1]);
		String weight = br.readLine();
		this.weights = new ArrayList <Integer>();
		for (int i = 0; i < this.productnum; i++) {
			this.weights.add(Integer.parseInt(weight.split(" ")[i]));
		}
		
		String value = br.readLine();
		this.values = new ArrayList <Integer>();
		for (int i = 0; i < this.productnum; i++) {
			this.values.add(Integer.parseInt(value.split(" ")[i]));
		}
	}
	
	/**
	 * 初始化背包
	 * m[i][0] = 0 :表示背包重量为0,不能装东西,因此价值全为0
	 * m[0][j] = 0 :表示没有可以装的物品,因此价值为0
	 */
	public int[][] initpkdata(){
		int[][] m = new int[this.productnum+1][this.packageweight+1];
		for(int i = 0; i <= this.productnum; i++){
			m[i][0] = 0;
		}
		for(int j = 0; j <= this.packageweight; j++){
			m[0][j] = 0;
		}
		return m;
	}
	
	public int[][] result(int[][] arr){
		for(int i = 1; i <= this.productnum; i++){
			for(int j = 1; j <= this.packageweight; j++){
				// 当第i件物品重量大于当前包的容量 则放不进去
				// 所以当前背包所含价值等于前i-1件商品的价值
				if(this.weights.get(i-1) > j){
					arr[i][j] = arr[i-1][j];
				}
				/*当第i件物品能放进去时
				1 放入物品,价值为:arr[i-1][j-(int)this.weights.get(i-1)] + (int)this.values.get(i-1)
				2不放入物品,价值为前i-1件物品价值和:arr[i][j] = arr[i-1][j];
				此时最大价值为上述两种方案中最大的一个
				*/
				else{
					if(arr[i-1][j] < arr[i-1][j-this.weights.get(i-1)] + this.values.get(i-1)){
						arr[i][j] = arr[i-1][j-this.weights.get(i-1)] + this.values.get(i-1);
					}
					else{
						arr[i][j] = arr[i-1][j];
					}
				}
			}
		}
		return arr;
	}
	
	public void findproducts(int[][] arr){
		int j = this.packageweight;  
		for(int i = this.productnum; i > 0; i--){
		    if(arr[i][j] > arr[i-1][j]){
		        System.out.print(i+"  ");//输出选中的物品的编号
		        j = j - this.weights.get(i-1);
		        if(j < 0){
		        	break;
		        }
		    }
		}
	}
}

输入数据格式:
背包总容量 物品个数
物品重量
物品价值
(以空格分隔)
在这里插入图片描述
在这里插入图片描述

发布了32 篇原创文章 · 获赞 23 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_35443700/article/details/102816747