step by step.
目录
贪心算法:总是作出在当前看来最好的选择。—— 局部最优选择
1. 活动安排问题
活动安排问题:设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si <fi 。如果选择了活动i,则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当si≥fj或sj≥fi时,活动i与活动j相容。
贪心算法:活动i在相容活动集合A中,当且仅当A[i]的值为true。用变量j记录最近一次加入A的活动序号。
由于fj总是当前集合A中所有活动的最大结束时间,故活动i与当前集合A中所有活动相容的充分必要条件是:si≥fj,若活动i与活动j相容,则将i成为最新加入集合A中的活动,并取代活动j的位置。
template<class Type>
void GreedySelector(int n, Type s[], Type f[], bool A[])
{
A[1]=true;
int j=1;
for (int i=2;i<=n;i++) {
if (s[i]>=f[j]) { A[i]=true; j=i; }
else A[i]=false;
}
}
排序时间:O(nlogn) 贪心算法时间:O(n)
理解:
2. 贪心算法的基本要素
(1) 贪心选择
贪心选择:每个选择都是当前状态下局部最好选择。自顶向下进行。
(动规:每一步选择依赖于相关子问题的解,自底向上进行。)
(2) 最优子结构性质
最优子结构性质:一个问题的最优解包含其子问题的最优解。
0-1背包问题:(动规)
满足最优子结构性质。但无法根据当前状态进行选择。
背包问题:(贪心)
满足最优子结构性质,且可根据当前状态选择。
void Knapsack(int n,float M,float v[],float w[],float x[]) { Sort(n,v,w); int i; for (i=1;i<=n;i++) x[i]=0; float c=M; for (i=1;i<=n;i++) { if (w[i]>c) break; x[i]=1; c-=w[i]; } if (i<=n) x[i]=c/w[i]; }
计算时间上界为O(nlogn)
PS:0-1背包问题怎么装也装不过背包问题。 :)
3. 贪心算法的证明
先说明问题具有最优子结构性质;然后证明存在最优解包含贪心选择的第一步(即可以采用贪心选择来开始)。
4. 装载问题
最轻者先装。
5. 多机调度问题
多机调度问题 要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
int Dispatch(Job *a, Header *M, int n, int m){
int min, max;
JobNode *p, *q; //中间变量
for(int i=0; i<n; i++){
M[i].s = 0; M[i].next = NULL; //将机器的总时间和作业指针初始化
}
Sort(a, n); //将a[]作业数组从小到大进行排序
if(n <= m)
return a[0].time; //作业数小于机器数的情况,直接取排好序的作业数组第一个元素
for(int j=0; j<n; j++){
q = (pJobNode)malloc(sizeof(JobNode)); //给中间变量分配空间
min = SelectMin(M, m); //得出作业时间总和最小的机器的下标
M[min].s += a[j].time;
q->ID = a[j].ID; //将a数组中的元素变成作业节点数据
q->time = a[j].time;
q->next = NULL; //尾指针置空
if(!M[min].next) //M未进行节点插入的情况,加入作业节点到头节点之后
M[min].next = q;
else{ //M已有作业节点的情况,加入作业节点到尾部
p = M[min].next;
while(p->next)
p = p->next;
p->next = q;
}
}
Print(M, m); //输出每台机器的运行作业的ID
max = SelectMax(M, m); //得出最大的s的机器的下标
return M[max].s; //返回至少需要的时间
}
① 当n<=m时,只要将机器i的[0, ti]时间区间分配给作业i即可,算法只需要O(1)时间。
② 当n>m时,首先将n个作业依其所需的处理时间从大到小排序。然后依此顺序将作业分配给空闲的处理机。算法所需的计算时间为O(nlogn)。
例题
eg。
设7个独立作业{1,2,3,4,5,6,7}由3台机器M1,M2和M3加工处理。各作业所需的处理时间分别为{2,14,4,16,6,5,3}。按算法greedy产生的作业调度如下图所示,所需的加工时间为17。
动规与贪心的比较
标准分治 | 动态规划 | 贪心选择 | |
适用类型 | 通用问题 | 优化问题 | 优化问题 |
子问题结构 | 每个子问题不同 | 很多子问题重复 | 只有一个子问题 |
最优子结构性质 | 满足 | 满足 | 满足 |
求解子问题数 | 全部子问题都要解决 | 全部子问题都要解决 | 只解决一个子问题 |
子问题在最优解里 | 全部 | 部分 | 部分 |
选择与求解次序 | 先选择后解决子问题 | 先解决子问题后选择 | 先选择后解决子问题 |
不写了我干没时间了拜拜!有空会补充的。
祝大家考试顺利: )