【算法系列-10】贪心算法

来源:互联网 发布:java分布式如何开发 编辑:程序博客网 时间:2024/05/24 00:47

声明:内容源自网络

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解


贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。


基本思路

贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止。

过程
①建立数学模型来描述问题;
②把求解的问题分成若干个子问题;
③对每一子问题求解,得到子问题的局部最优解;
④把子问题的解局部最优解合成原来解问题的一个解。


0-1背包问题

有一个背包,背包容量是M=150kg。有7个物品,物品不可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
物品 A B C D E F G
重量 35kg 30kg 6kg 50kg 40kg 10kg 25kg
价值 10$ 40$ 30$ 50$ 35$ 40$ 30$

分析:
目标函数:∑pi最大
约束条件是装入的物品总重量不超过背包容量:∑wi<=M(M=150)
⑴根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?
⑵每次挑选所占重量最小的物品装入是否能得到最优解?
⑶每次选取单位重量价值最大的物品,成为解本题的策略。

代码

物品类:

public class Goods implements Comparable<Goods> {private int weight;private int value;/*单位重量价值*/private int unitValue;public Goods(int weight, int value){this.weight = weight;this.value = value;this.unitValue = (weight == 0) ? 0 : (value/weight);}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}public int getUnitValue() {return unitValue;}public void setUnitValue(int unitValue) {this.unitValue = unitValue;}@Overridepublic int compareTo(Goods o) {// TODO Auto-generated method stubint value = o.unitValue;if(unitValue > value)return 1;if(unitValue < value)return -1;return 0;}}

背包类:

public class Knapsack {private List<Goods> list;/*背包总承重*/private int bWeight;/*背包价值*/private int totalValue;public Knapsack(int bWeight){this.bWeight = bWeight;this.list = new ArrayList<Goods>();}public List<Goods> getList() {return list;}public void setList(List<Goods> list) {this.list = list;}public int getbWeight() {return bWeight;}public void setbWeight(int bWeight) {this.bWeight = bWeight;}public int getTotalValue() {totalValue = 0;for(Goods goods : list){totalValue += goods.getValue();}return totalValue;}}

算法类

/** * Program Name:* Description:贪心算法* Methods:* @version ver:1.0*/public class GreedyAlg {private Knapsack knapsack;private Goods[] goodsArray;public GreedyAlg(Knapsack knapsack, Goods[] goodsArray){this.knapsack = knapsack;this.goodsArray = goodsArray;/*对货物按照单位重量价值从大到小排序*/Arrays.sort(goodsArray, Collections.reverseOrder());}public void solve(){int currentWeight = 0;List<Goods> list = knapsack.getList();for(int i=0; i<goodsArray.length; i++){/*判断当前货物是否可以放到包中,如不能则继续循环*/if(currentWeight + goodsArray[i].getWeight() > knapsack.getbWeight())continue;currentWeight += goodsArray[i].getWeight();list.add(goodsArray[i]);}}public static void main(String[] args){Knapsack knapsack = new Knapsack(150);Goods goodsA = new Goods(35, 10);Goods goodsB = new Goods(30, 40);Goods goodsC = new Goods(6, 30);Goods goodsD = new Goods(50, 50);Goods goodsE = new Goods(40, 35);Goods goodsF = new Goods(10, 40);Goods goodsG = new Goods(25, 30);Goods[] array = {goodsA, goodsB, goodsC, goodsD, goodsE, goodsF, goodsG};GreedyAlg greedyAlg = new GreedyAlg(knapsack, array);greedyAlg.solve();int totalValue = knapsack.getTotalValue();System.out.println("Input Knapspack total value is----->" + totalValue);}}

总结

贪心算法不回溯,只是局部最优解,请注意!

贪心算法不保证能得到最优解,动态规划可以得到最优解。

动态规划每次都要回朔处理,这样的话效率不高。如果只为求最优解,动态规划自然更好!但是如果对效率有要求,对最优解的值没有严格要求,贪心法就适用了。根据实际问题的取舍很重要。

0 0
原创粉丝点击