JAVA贪心算法实现背包问题

以下贪心算法相关概念及题目转载自http://blog.csdn.net/effective_coder/article/details/8736718,java实现代码为博主原创

贪心算法思想:

顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

贪心算法的基本思路:

从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。

该算法存在问题:

1. 不能保证求得的最后解是最佳的;

2. 不能用来求最大或最小解问题;

3. 只能求满足某些约束条件的可行解的范围。

实现该算法的过程:

从问题的某一初始解出发;

while 能朝给定总目标前进一步 do

   求出可行解的一个解元素;

由所有解元素组合成问题的一个可行解;

用背包问题来介绍贪心算法:

背包问题:有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

物品 A B C D E F G

重量 35 30 60 50 40 10 25

价值 10 40 30 50 35 40 30

分析如下

目标函数: ∑pi最大

约束条件是装入的物品总重量不超过背包容量:∑wi<=M( M=150)。

(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?

(2)每次挑选所占重量最小的物品装入是否能得到最优解?

(3)每次选取单位重量价值最大的物品,成为解本题的策略。

package cn.wit.algorithm;
import java.util.*;

class Obj{
	int p;//price
	int w;//weight
	double pw;//price/weight
	boolean mark=false;//标记位,表示是否被选中,本题中未使用,但很多类似的题中需要,加上供扩展算法
	
}

public class Greedy {
	public static double maxPrice(int cap,int num,int [][] objs){
		Obj[] objArr=new Obj[num];
		for(int i=0;i<num;i++){
			objArr[i]=new Obj();
		}
		
		for(int i=0;i<num;i++){	
			objArr[i].w=objs[i][0];
			objArr[i].p=objs[i][1];
			objArr[i].pw=objs[i][1]*1.0/objs[i][0];
			
		}
		Arrays.sort(objArr,new Comparator<Obj>(){//重载Java数组自带排序方法,使用归并排序,方便而且排序效率高
			public int compare(Obj o1,Obj o2){
				if(o1.pw<o2.pw){
					return 1;
				}
				else if(o1.pw==o2.pw){
					return 0;
				} 
				else 
					return -1;
			}
		});
		
		//总price与指示变量
		double pSum=0;
		int	i=0;		
		while(cap>0){
			cap-=objArr[i].w;
			pSum+=objArr[i].p;
			i++;
		}
		
		
		//若cap为负数,说明取多了,需要减去最后一个物品的一部分价值
		if(cap<=0){
			int gap=-cap;
			pSum-=gap*objArr[--i].pw;
			
		}
		
		
		return pSum;
	}
	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		int cap=150;
		int num=7;
		int[][] objs={{35,10},{30,40},{60,30},{50,50},{40,35},{10,40},{25,30}};
		double maxP=maxPrice(cap, num, objs);
		System.out.println(maxP);
		
		
	}

}
执行结果为:190.625




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值