贪心算法入门

今天看了一下贪心算法,贪心算法没有具体的算法框架。贪心算法主要找当前看来最好的解,没有考虑整体最优。得到的只是局部最优解。

贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。
二、贪心算法的基本思路:
    1.建立数学模型来描述问题。
    2.把求解的问题分成若干个子问题。
    3.对每一子问题求解,得到子问题的局部最优解。
    4.把子问题的解局部最优解合成原来解问题的一个解。
三、贪心算法适用的问题
      贪心策略适用的前提是:局部最优策略能导致产生全局最优解。
    实际上,贪心算法适用的情况很少。一般,对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可做出判断。
四、贪心算法的实现框架
    从问题的某一初始解出发;
    while (能朝给定总目标前进一步)
    { 
          利用可行的决策,求出可行解的一个解元素;
    }
    由所有解元素组合成问题的一个可行解;
下面摘自百度文库

排队问题 
【题目描述】 
 在一个医院B 超室,有n个人要做不同身体部位的B超,已知每个人需要处理的时间为ti,(0<i<=n),请求出一种排列次序,使每个人排队等候时间总和最小。 
输入数据:第1行一个正整数n(你<=10000》,第2行有n 个不超过 1000的正整数ti. 
输出要求:n个人排队时间最小总和。 输入输出样例 输入:4 5 10 8 7 输出: 67 
【算法分析】 
本题贪心算法:n个人时间从小到大排序,就是这n个人最佳排队方案。求部分和的和即为所求。 
反证法证明:假设有最优解序列:s1,s2„sn,如s1不是最小的Tmin,不妨设sk=Tmin,将s1与sk对调,显然,对sk之后的人无影响,对sk之前的人等待都减少了,(s1-sk)>0,从而新的序列比原最优序列好,这与假设矛盾,故s1为最小时间,同理可证s2„sn依次最小

下面是对百度文库中排队问题的实现

 1 //一个贪心算法小例子
 2 //贪心算法每次寻找局部最优解
 3 //贪心算法是否合适需要数学来论证其解是否为最优解
 4 //可以参考背包问题
 5 public class Greed {
 6 
 7     public static void main(String[] args) {
 8         int array[] = {5, 10, 8, 7};
 9         Greed greed = new Greed();
10         int time = greed.getTime(array);
11         System.out.println("time is: " + time);
12     }
13     //这里随便用的一个排序算法
14     //明天再系统的看看排序算法
15     //这里用的好像是选择排序
16     //每次选择最小的或者最大的数
17     //这里我采用升序的方式
18     public void sort(int array[]){
19         int min;
20         for(int i = 0; i < array.length; i++){
21             min = i;
22             for(int j = i + 1; j < array.length; j++){
23                 if(array[i] > array[j])
24                      min = j;
25             }//每一趟找出i后面最小值
26             if(i != min){
27                 int temp;
28                 temp = array[i];
29                 array[i] = array[min];
30                 array[min] = temp;
31             }//如果array[i]不是最小值,交换array[i]和array[min]的值
32         }
33     }
34     
35     /**
36      * 计算所有的时间和
37      * @param array
38      * @return
39      */
40     public int getTime(int array[]){
41         int sum = 0;
42         //先排序,在求部分和
43         sort(array);
44         show(array);
45         for(int i = 0; i < array.length; i++){
46             int time_one = 0;
47             for(int j = i; j >= 0; j--){
48                 time_one += array[j];
49             }
50             sum += time_one;
51         }
52         return sum;
53     }
54     
55     public void show(int array[]){
56         for(int i = 0; i < array.length; i++){
57             System.out.print(array[i] + " ");
58         }
59         System.out.println();
60     }
61 }
 
原文地址:https://www.cnblogs.com/luckygxf/p/4055018.html