1.贪心算法是每一步总是做出在当前看来最好的选择,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。通常是自顶向下的解决问题,一迭代的方式作出相继的选择。
2.(1).贪心策略。首先确定贪心策略,选择一个看上去最好的方案。
(2).局部最优解。把问题分成一个个小问题。
(3)贪心算法不一定是永远会得出最优解,例如多级调度里的长作业优先算法。
3.常见题型:
1)活动安排问题:
2)哈弗曼编码问题
3)单元最短路径
4)最小生成树问题
5)多级调度问题
(1)活动安排问题
贪心策略:每次从剩下的会议中选择具有最早结束时间且与已安排的会议相容的会议安排。
再按照结束时间从小到大排序。
(2)哈弗曼编码问题
贪心策略:做贪心选择时有效的确定当前要合并的两颗最小频率的树,合并后产生的新树的频率为两树的频率的和,并将新树插入优先队列Q,进过n-1次合并之后,剩下的最后一棵树就是所求树。
时间复杂度:初始化优先队列为O(n),插入运算为O(logn),n-1次合并为O(nlogn),总的为O(nlogn)。
(3)单元最短路径
首先把没有连接的端点对应的二维数组设为一个大值,再把数据填入, Dijkstra算法G[][]数组是端点之间的距离,dist[]数组是1端点得到其他端点的最短距离,prev[]数组是1端点到其它顶点的最短路径的上一个节点,在 Dijkstras算法更新最短路径时,只要dist[u]+G[u][i]<dist[i],就把prev[i]=u,dist[i]= dist[u]+G[u][i],直到最后。
时间复杂度:O(n2);
(4)最小生成树问题
最小生成树:最小连同子图,加一条边就会有回路,少一条就不会全部连通。
prim算法:先设S={1}选取满足条件的i属于S,j属于V-S ,且c[i][j]为最小的边,并把定点J添加到S中,一直到S=V结束。
时间复杂度:O(n2)
Kruskal算法:本思想是:首先将G的n个顶点看成n个孤立的连通分支,将所有的边按权从小到大排序 然后从第一条边开始,依边权递增的顺序查看每条边,并按下述方法连接两个不同的连通分支:当查看到第k条边(v,w)时,如果端点v和w分别是当前两个不同的连通分支T和中的顶点时,就用边(v,w)将T1和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和在当前的同一个连通分支中,就直接再查看第k+1条边。这个过程一直进行到只剩下一个连通分支时为止。
时间复杂度为:O(nlogn)
(5)多机调度问题
长作业优先算法:先将作业按执行的时间长短从大到小排序,在依次将作业分配给不同的空闲机器,那个先结束就在其后加入没完成的最长的,直到结束。
此算法不一定会一定得到最优解,时间复杂度:O(nlogn);