贪心算法
1.基本思想
从问题的某一个初始解出发,在每一个阶段都根据贪心策略来做当前最优的决策,逐步逼近给定的目标,尽可能快的求得更好的解。当达到算法中的某一步不能再继续前进时,算法终止。
2.得出结论
每个阶段面临选择时,贪心法都作出对眼前来讲是最有利的选择,选择一旦作出不可更改,即不允许回溯,根据贪心策略来逐步构造问题的解。
3.解决步骤
1)分解:将原问题分解为若干个相互独立的阶段,并能逐步使用贪心策略解决每一个阶段。子问题具有相同的解决策略。
2)解决:对于每个阶段依据贪心策略进行贪心选择,求出局部的最优解。
3)合并:将各个阶段的解合并为原问题的一个可行解。
4.贪心算法产生优化解的条件
1)贪心选择性质:若一个问题的全局最优解可以通过局部最优解来得到,则说明该问题具有贪心选择性质。
2)最优子结构性质:若一个问题的最优解一定包含其子问题的最优解时。
5.贪心算法和动态规划的区别
1)贪心算法是自顶向下,以迭代的方式一步一步做出贪心选择,从而把问题简化成规模更小的问题
2)动态规划是自底向上求出各子问题的有化解,最后汇集有化解从而得出问题的全局最优解
但是所有能够使用贪心算法解决的问题都可以使用动态规划解决。
6.贪心算法存在的问题
1)不能保证求得的最后解是最佳的
2)不能用来求最大或最小解问题
3)只能求满足某些约束条件的可行解的范围
7.算法框架
void Greedy(A,N)
{
init(solution );//1.首先得出一个初始解
for(i=0;i<N;i++){
x=select(A(i));//2.用贪心选择策略将原问题划分为一个子问题,并将其解决
if(x满足最终解的条件 && solution中未包含x){
solution = union(x,soulution);//3.合并这个阶段所得到的子问题的最优解
}
update(select);//4.更新贪心策略所判断的条件
}
return solution;
}
8.算法正确性证明
1)问题存在从贪心选择开始的最优解<--------贪心选择性质(子问题最优===>全局最优):采用归纳法
2)一步一步的贪心选择能够得到问题的最优解<--------最优子结构性质(全局最优包含子问题最优):采用反证法
9.关键点思考
1)依据什么策略将原问题划分为相互独立的子问题?
a)一般依据最终解决的问题来将原问题划分成子问题。
b)子问题必须能够使用贪心策略去解决。
c)子问题的解决必须具有顺序性,且相互独立。
2)如何证明所选择的贪心策略对问题的求解是正确的?
证明贪心策略和问题具有2个性质。
10.典型案例
a)单源最短路径----给定图的一个源点计算出源点至其它点的最短路径(问题应用场景:交通路线)
问题解决:
1)分解:将图中的节点分成2个集合,一个是已求解出的源点到顶点最短距离的顶点集合V,另一个是未求解出源点到其最短距离的顶点的集合S。
2)求解:源点u只经过集合V中的一系列顶点{p1,p2,p3…}到达S集合中最近的那个顶点q加入V,并且更新V中各个顶点到达S中顶点的路径值。
3)合并:最终V集合包含所有顶点,S集合为空
//u:输入的源点ID c:图的邻接矩阵 n:图中节点的个数 path:表示结果
void Dijstra(int u,int c[][],int n,int path[])
{
int i,j;
}