算法导论第16章 贪心算法之活动选择
2013-12-19 20:30
330 查看
问题描述:
假定有一个n个活动的集合S = {a1, a2, ...., an}, 这些活动使用同一个资源,而这个资源在某一刻只能供一个活动使用。每个活动ai有一个开始时间si和结束时间fi, 0 ≤ si < fi < +∞.如果被选中,任务ai发生在半开时间区间[si, fi)。 如果两个活动ai, aj满足[si, fi), [sj, fj)不重叠,则他们是兼容的。即若si ≥ fj 或 sj ≤ fi,则ai, aj是兼容的
在活动选择中,我们希望选出一个最大兼容活动集,假定活动已按结束时间的单调递增顺序排序:f1 ≤ f2 ≤ f3 ≤....≤ fn-1 ≤ fn
该问题有最优子结构,可以用动态规划算法求解,但是动态规划会求解所有子问题,但对于选择问题,可以只考虑一个选择,贪心选择。即每次都选择剩下的集合当中结束时间最早的活动。
定理16.1: 考虑任意非空子问题Sk, 令am是Sk中结束时间最早的活动,则am在Sk的某个最大兼容活动子集中。
贪心算法通常是自顶向下的设计:做出一个选择,然后求解剩下的那个子问题,而不是自底向上的求出很多子问题,然后再做出选择(这是动态规划常用的方法)
#include <iostream> using namespace std; /************************************************************************/ /* 递归法, 共有n个活动,为了方便算法初始化, 添加了一个虚拟活动a0,结束时间为f0=0 输入: start[]:每个活动的开始时间, final[]: 每个活动的结束时间 k: 要求解的子问题,nn:问题的规模 过程中打印符合条件的活动 与ak活动兼容的活动的条件是:start[m] > final[k] 活动的开始时间比ak的结束时间靠后 */ /************************************************************************/ void recursiveActivitySelector(int *start, int *final, int k, int n) { int m = k+1; //找出符合条件的活动 while (m <= n && start[m] < final[k]) m++; if (m <= n) { cout << "a" << m << " "; recursiveActivitySelector(start, final, m, n); } else cout << " " << endl; } /************************************************************************/ /* 递归版的迭代版本 输入:start[]:每个活动的开始时间, final[]: 每个活动的结束时间 过程中打印符合条件的活动 与ak活动兼容的活动的条件是:start[m] > final[k] 活动的开始时间比ak的结束时间靠后 */ /************************************************************************/ void greedyActivitySelector(int *start, int *final, int n) { cout << "a1 "; int k = 1; for (int m = 2; m <= n; m++) { //找出符合条件的活动 if (start[m] > final[k]) { cout << "a" << m << " "; k = m; } } cout << endl; } int main() { int start[] = {-1, 1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12}; int final[] = {0, 4, 5, 6, 7, 9, 9, 10, 11, 12, 14, 16}; cout << "递归法求活动:"; recursiveActivitySelector(start, final, 0, 11); cout << "迭代的贪心算法:"; greedyActivitySelector(start, final, 11); system("pause"); return 0; }贴上一张图:递归算法的求解过程,很详细
在输入活动已按结束时间排序的情况下,这两个算法的运行时间都为Θ(n)
运行结果为:
相关文章推荐
- 算法导论-第16章-贪心算法-16.1 活动选择问题
- 算法导论 第16章 活动选择问题的递归和迭代贪心算法
- 《算法导论》读书笔记之第16章 贪心算法—活动选择问题
- 算法导论第16章 贪心算法-活动选择问题
- 算法导论贪心算法活动选择
- 算法导论贪心算法之活动选择
- 算法导论程序40--贪心算法(活动选择问题)
- 算法导论,贪心算法 —— 活动选择问题(python示例)
- 算法导论--贪心算法与动态规划(活动选择问题)
- 《算法导论》笔记 第16章 16.1 活动选择问题
- 《算法导论》之 贪心算法—活动选择问题
- 算法导论 第16章 贪心算法-活动选择问题C++实现
- 活动选择问题(算法导论第16章(贪心算法)
- 贪心算法-活动选择
- 第十六章 贪心算法——活动选择问题
- 贪心算法之活动选择问题--求解现实问题的思路
- 算法导论——16.1-5动态规划解决活动选择带值问题
- 贪心算法—活动选择问题
- 贪心算法-活动选择
- 贪心算法——活动选择