簡單揹包問題

package 算法;

import java.util.Scanner;

/**
 * 揹包問題:
 *     給定一個容量爲capacity的揹包,給定一個數據項數組Item [] items,
 *     數組裏面的每個數據項只能放入揹包中一次,數組裏面的數據項包含數據的
 *     大小和價值,求容量爲capacity的揹包所能存放數據項的價值最大的解。
 */
//數據項類
class Item {
	public int size;
	public int value;
	public Item(int size,int value){
		this.size = size;
		this.value = value;
	}
}

public class Knapsack {
	private int  capacity;         //揹包的容量
	private Item[] items ;          //數據項數組
	private int numItem;         //數據想的個數
	private int[][] maxValue;        //最大值數組
	
	public Knapsack(int capacity,Item[] items){
		this.capacity = capacity;
		this.items = items;
		this.numItem = items.length;
		maxValue = new  int [this.numItem+1][this.capacity+1];
		
		
	}
	
	//構造最大數組
	public void makeMaxValue(){
		
	
		int testMax;
		for(int i =1; i <= numItem;i++){
			for(int j = 1; j <= capacity ;j++){
				if(j >= items[i-1].size){
					testMax =items[i-1].value+ maxValue[i-1][j-items[i-1].size];
					if(testMax >= maxValue[i-1][j]){
						maxValue[i][j] = testMax;
					}
					else{
						maxValue[i][j] = maxValue[i-1][j];
					}
				}
				else{
					maxValue[i][j] = maxValue[i-1][j];
				}
				
			}//end for(j)
		}//end for (i)
	}
	//推斷揹包中的數據項,所包含的數據項
	public void displayMaxValue(){
		
		
		makeMaxValue();
		showMaxValue();
		int lessCapacity = capacity;
		int lessValue = maxValue[numItem][capacity] ;
		//Item it;
		int itemSize;
		int itemValue;
		System.out.println("揹包的容量:" +capacity+"揹包裏面東西的價值:"+maxValue[numItem][capacity]);
		System.out.println("所包含的元素如下:");
		for(int i = numItem ; i > 0 ; i--){
			System.err.println(i);
			itemSize = items[i-1].size;
			itemValue = items[i-1].value;
			
			if(lessValue >= maxValue[i][itemSize] && maxValue[i][itemSize] >= maxValue[i-1][itemSize]){
				System.out.println("大小  "+itemSize+"價值  "+itemValue);
				lessValue = lessValue - itemValue;
				lessCapacity = lessCapacity -  itemSize;
			}
		}
		//判斷有沒有剩餘的空間
		if(lessCapacity > 0){
			System.out.println("剩餘的空間大小爲:"+lessCapacity);
		}
		else{
			System.out.println("剛好佔滿空間。");
		}
	}
	
	//輸出最大元素的數組
	private void  showMaxValue(){
		for(int i =1 ; i <= numItem; i++){
			for(int j = 1 ; j <= capacity ; j++){
				System.out.print(maxValue[i][j]+"   ");
			}
			System.out.println();
		}
	}

	//main用於測試算法
	public static void main(String[] args) {
		
		//數據想數組
		Item [] items = {new Item(2,1),new Item(3,4),new Item(4,3),
			                   	new Item(5,6),new Item(6,8)};
		
		int capacity = 0;
		Scanner sc = new Scanner(System.in);
		
		try{
			System.out.println("請輸入揹包的大小:");
			capacity = sc.nextInt();
		}catch (Exception e){
			e.printStackTrace();
		}
		
		Knapsack kna = new Knapsack(capacity, items);

		kna.displayMaxValue();
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章