- 贪心算法在每步取得局部最优解
1. Interval scheduling
1.1 问题描述
- 目标:在没有工作冲突的情况下兼容最多的工作数;
- 工作的起始时间为 ,结束时间为.
1.2 问题分析
- Greedy template: 1. 对任务按某种规则排序;2. 根据已排好序的任务列表选择排序位置最靠前且不冲突的任务。
- 可以有如下4种排序方法:
-
起始时间增序
有如上反例,若按start time,最多工作数为1,但实际情况为4,故不可行;
- 结束时间增序;
- interval length工作时长 增序;
有如上反例,最多工作数为1,但实际为2,故不可行; - 最少冲突工作数增序
有如上反例,深灰色工作冲突数为2,第一排浅灰色冲突数为3,最多工作数为3,但实际为4,故不可行。
将工作按结束时间排序,依次选取与前面不冲突的工作。
时间复杂度:排序是O(logn),for循环O(n), O(nlogn)
1.3 证明最优
反证法:
假设贪心不是最优解:
- 令 是按贪心算法选择的工作序列;
- 令是最优解序列且前项工作与贪心序列相同;
因为贪心序列是按结束时间排序的,现假设最优解O与贪心解A不同,故有; - 将替换为,构造最优解O',即将第个工作提前了,与前后工作都没有重叠,它也是最优解,因为最大工作数没变;
- 至此,我们证明了一个与A更接近的最优解O‘,它在前个工作上都与A一样,与前提最多只有前项相同矛盾,故A是最优解。
2. Scheduling to Minimize Lateness
2.1 问题描述
- 目标:每项任务有需要的时间和ddl,记所有任务中迟交最长的时间为,最小化。
e.g. 上图中return结果为6
2.2 问题分析
先考虑如何排序
- 所需时间增序
有如上反例,job1无迟交,job2迟交1,return 1;实际上若交换两个工作位置,return 0; - ddl时间增序
- 最迟开始时间增序
将工作按ddl时间增序
2.3 证明最优
Exchange argument:通过交换元素将最优解转换为贪心解,但还保持最优性
- 一个inversion定义为一对工作 和,但却排在之前;
Observation1:因为贪心解按ddl时间点排序,所以贪心解不存在inversion;
Observation3:如果存在inversion,必然存在相邻的两个工作存在inversion.
有结论:交换相邻的一对inverted jobs,并不会增大最大迟交时间。
证明: - 交换后,若最大迟交时间增大,只可能是因为 ,因为提前了,延后了。
- 令为交换前的最大迟交之间,为交换后的
- 如果迟交了,有
,即最大迟交时间不变
下面证明贪心法最优:
反证法:
假设S*是最优解,且有最少的inversions (即构造了和贪心解最像的最优解) - 若S* 没有inversions,S* = A;
- 若S*有inversions, 令{i, j} 是这对相邻的inversion:交换i,j 最大迟交没有增加,且更像贪心解A;
- 与假设的定义矛盾,故A是最优解。
时间复杂度: Θ(N log N) (due to sorting)
3. Optimal Caching
3.1 问题描述
当cache中不存在所需元素时,需要访问cache交换元素。
目标:cache misses的次数最少
3.2 问题分析
最优算法:cache miss时替换当前future queries中最远访问的元素。
e.g. future queries中第一个元素g出现cache miss, 需要exchange,判断current cache中需要替换哪个元素。
在future queries中
- a:第2个出现;
- b:第3个出现;
- c:第4个出现;
- d:第6个出现;
- e:第5个出现;
- f:第15个出现;
Exchange f and g
3.3 证明最优
思路:构造最优规划,它有最小的cache misses次数;Farthest-In-Future规划,两者在前个请求的序列是相同的,如果能证明在第步时,可以转化为并且没有增加cache misses的次数,则可以说明是最优解。
最开始,假设和中元素如下:
abcd | |
abcd |
Case 1: 元素已经在Cache中
假设下一个请求的元素是d显然两者都不会发生cache miss,故两者总的cache misses次数还是相同;
abcd | |
abcd |
Case 2: 元素不在Cache中,和与外界交换相同的元素
假设下一个请求的元素是e,两者都用a与其交换,有
ebcd | |
ebcd |
和都增加了一次cache misses,故总cache misses次数还是相同;
Case 3: 元素不在Cache中,和与外界交换不同的元素
假设下一个请求的元素是e,交换a,交换b,有
aecd | |
ebcd |
之后,下一个请求的元素有四种情况:
Case 3a: 元素在中, 不在中; S交换a
也就是请求b,这时S用a交换b,有
ebcd | |
ebcd |
有两次cache misses,而只有一次,之后和序列又保持一致;
Case 3b: 元素在中, 不在中; S不交换a
也就是请求b,S用c交换b,有
abde | |
ebcd |
用a交换c,有
abde | |
abde |
两者cache misses次数相同,之后和序列又保持一致
Case 3c: 元素在中, 不在中
即请求a,这种情况不可能发生,因为S_{FF}移出的是最远需要的元素,即request中a会排在b之后;
Case 3d: 元素不在和中
假设请求f,用a交换f, 用b交换f,有
cdef | |
cdef |
两者cache misses次数相同,之后和序列又保持一致
的cache misses次数不会多于最优解, 即是最优解。
4. Clustering of Maximum Spacing
4.1 问题描述
Cluster间的距离(Spacing):两个clsuter中距离最近的两个点之间的距离;
目标:给定cluster数量k,找到有最大spacing的k个聚类。
4.2 问题分析
Single-link k-clustering 算法:
- 现有含n个cluster的一张图;
- 找到在不同集合中距离最近的一对点,在它们之间连线,
- 重复n-k次,就会得到k个clusters
- 这个过程相当于删掉最小生成树中k-1条最长的边;
4.3 证明最优
- 假设是从最小生成树中删去k-1条最长边后形成的k个clusters集合(),有最大的max spacing
- 假设是其它的clustering集合:
- 的spacing定义为第k-1条最长边的长度;
- 是两点,它们在中在同一个集合,但是在的不同集合和中;
- 假设()路径中的两点定义了和之间的spacing,这个spacing ,所以最优。