贪心算法基本原理
贪心算法的核心就是贪,就是总是做出当前看来最优的选择,因此可知,贪心算法不从整体去考虑,它做出的选择也是局部最优选择,从而达到全局优化选择。虽然贪心算法不一定能得到最优解,但是对很多问题,它是能够得到整体最优解的,因此贪心算法是否能到最优解,需要严格证明。
贪心算法产生有化解的条件
- 贪心选择性质:
若一个问题的全局最优解可以通过局部最优解来得到,则说明该问题具有贪心选择性质。 - 优化子结构:
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。
贪心算法和动态规划的区别
- 贪心算法是自顶向下的,而动态规划则是自底向上的。
- 动态规划是自底向上求出各子问题的有化解,最后汇集有化解从而得出问题的全局最优解(可以想象成各个小河流入大海)
贪心算法是自顶下向下,以迭代的方式一步一步做出贪心选择,从而把问题简化成规模更小的问题
贪心算法的基本思路
从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:
1. 不能保证求得的最后解是最佳的;
2. 不能用来求最大或最小解问题;
3. 只能求满足某些约束条件的可行解的范围。
实现该算法的过程:
从问题的某一初始解出发;
while 能朝给定总目标前进一步 do
求出可行解的一个解元素;
由所有解元素组合成问题的一个可行解;
背包问题:
private int MAX_WEIGHT = 20; private int[] weights = new int[]{35,30,60,50,40,10,25}; private int[] values = new int[]{10,40,30,50,35,40,30};
private void packageGreedy(int capacity,int weights[],int[] values) { int n = weights.length; double[] r = new double[n];//性价比数组 int [] index = new int[n];//按性价比排序物品的下标 for(int i = 0;i<n;i++){ r[i] = (double)values[i]/weights[i]; index[i] = i;//默认排序 } double temp = 0;//对性价比进行排序 for(int i = 0;i<n-1;i++){ for(int j = i+1;j<n;j++){ if(r[i]<r[j]){ temp = r[i]; r[i] = r[j]; r[j] = temp; int x = index[i]; index[i] = index[j]; index[j] = index[x]; } } } //排序好的重量和价值分别存到数组 int[] w1 = new int[n]; int[] v1 = new int[n]; for(int i = 0;i<n;i++){ w1[i] = weights[index[i]]; v1[i] = values[index[i]]; } int[] x = new int[n]; int maxValue = 0; for(int i = 0;i<n;i++){ if(w1[i]<capacity){ //还可以装得下 x[i] = 1;//表示该物品被装了 maxValue+=v1[i]; System.out.println("物品"+w1[i]+"被放进包包"); capacity = capacity - w1[i]; } } System.out.println("总共放下的物品数量:"+ Arrays.toString(x)); System.out.println("最大价值:"+maxValue); }