背包问题(java实现)

用贪心算法解决一般背包问题。
背包问题
给定N种物品和一个容量为MAX_WEIGHT的背包,物品i的重量是weight[i],其价值为price[i],背包问题是如何选择装入背包的物品,使得装入背包中物品的总价值最大?
从物品可不可以分割,背包问题可以划分为0-1背包问题普通背包问题
0-1背包问题适合用动态规划求解,用贪心算法获不的最优解。
普通背包问题可用贪心算法求得最优解。

对于普通背包问题的求解,至少有三种看似合理的贪心策略:
(1)选择价值最大的物品,因为这可以尽可能快地增加背包的总价值。但是,虽然每一步选择获得了背包价值的极大增长,但背包容量却可能消耗得太快,使得装入背包的物品个数减少,从而不能保证目标函数达到最大。
(2)选择重量最轻的物品,因为这可以装入尽可能多的物品,从而增加背包的总价值。但是,虽然每一步选择使背包的容量消耗的慢了,但背包的价值却没能保证迅速增长,从而不能保证目标函数达到最大。
(3)选择单位重量价值最大的物品,在背包价值增长和背包容量消耗两者之间寻找平衡。
而第三种策略则可以获得最优解,所以解决普通背包问题可以用第三种贪心策略。
下面我们用
//物品的数量
int NUMBER=6;
//背包的最大载重量
int MAX_WEIGHT=21;
//每个物品的重量
int weight[]= {5,3,2,10,4,2};
//每个物品的价值
int price[]= {11,8,15,18,13,6};
这样的数据进行测试,代码如下。

public class BagTest {

	public static void main(String[] args) {
		//物品的数量
		int NUMBER=6;
		//背包的最大载重量
		int MAX_WEIGHT=21;
		//每个物品的重量
		int weight[]= {5,3,2,10,4,2};
		//每个物品的价值
		int price[]= {11,8,15,18,13,6};
		//贪心算法求解普通背包问题(物品可拆解)
		GreedyBag.greedybag(weight, price, MAX_WEIGHT, NUMBER);
	}
}
package 贪心法解决背包问题;

public class GreedyBag {

	public static void greedybag(int weight[],int price[],int MAX_WEIGHT,int NUMBER) {
		
		int i;
		double total_value=0;//可获得的最大价值
		double X[]=new double[NUMBER];//存储物品存放的结果(解向量),值为0-1
		
		//初始化解向量,java可以默认为0
		for(i=0;i<X.length;i++) {
			X[i]=0;
		}
		
		//surplus_capacity(剩余容量)
		double surplus_capacity=MAX_WEIGHT;//背包的剩余容量
				
		//specific(比值)定义一个数组存储单位价值
		double specific[]=new double [weight.length];
		
		for( i=0;i<specific.length;i++) {
			specific[i]=(double)price[i]/weight[i];//可获得小数
		}
		
		//将重量与价值按照单位价值 降序 重新排序(冒泡排序)
		for( i=0;i<specific.length-1;i++) {
			for(int j=i+1;j<specific.length;j++) {
				double temp=0;
				if(specific[i]<specific[j]) {
					//单位价值降序排序
					temp=specific[i];
					specific[i]=specific[j];
					specific[j]=temp;
					//重量重新排列
					temp=weight[i];
					weight[i]=weight[j];
					weight[j]=(int)temp;
					//价值重新排序
					temp=price[i];
					price[i]=price[j];
					price[j]=(int)temp;
			}
		}
	}
		//将物品按单位价值降序放入背包
		for(i=0;i<NUMBER;i++) {
			//如果第I个物品的重量大于背包的剩余容量,则表明此物品的分割,退出循环
			if(surplus_capacity<weight[i]) {
				break;
			}else {
				//物品可以整个放入,解为1
				X[i]=1;
				surplus_capacity-=weight[i];//更新背包的剩余容量
			}			
		}
		//如果背包还没有被放满,则可以将此物品拆解放入(整个物品已经放不进去)
		if(i<=NUMBER) {
			X[i]=surplus_capacity/weight[i];//自动转成double型
		}
		//输出结果
		for(i=0;i<NUMBER;i++) {
			System.out.println("重量为:"+weight[i]+"  "+"价值为:"+X[i]*price[i]+"  "+"放入为:"+X[i]);
		}
		//计算最大的价值量
		for(i=0;i<NUMBER;i++) {
			total_value+=X[i]*price[i];			
		}
		
		System.out.println("最大的价值量为:"+total_value);
	}
	
	


}

结果如图。结果如图
如果有问题,欢迎讨论指导。

猜你喜欢

转载自blog.csdn.net/qq_43785075/article/details/105252116
今日推荐