以下贪心算法相关概念及题目转载自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