Greedy algorithms
贪婪算法可能是实现和设计中最简单的算法,但它们通常是最难证明正确性的算法之一。
1. 部分背包问题Fractional Knapsack
已知:集合s有n个元素,每个元素中i满足:
Bi:一个正的利益
Wi:一个正的权益
目标:选择不同的元素使得在有限的w中有最大的权益
选择最大权益的元素
选择最小权益的元素
选择最大权益/权重比的元素
需要O (n log n)时间对项目进行排序,然后O (n)时间来处理他们的循环。
2. 间隔调度Interval Scheduling
- 输入:n个作业的集合。每一项工作在时间sj开始,在时间fj结束。
- 如果两份工作没有时间重叠,那么它们是兼容的。
- 目标:找到相互兼容的作业的最大子集。
按照工作开始时间排序
按照工作持续时间排序
对于每个作业,计算冲突的作业cj的数量。冲突按升序排列。
3.Interval Partitioning
- 课程i从si开始,到fi结束。
- 目标:找到最小的教室数量来安排所有的讲座,这样就不会有两堂课在同一时间在同一间教室上课。
This schedule uses 4 classrooms to schedule 10 lectures.
This schedule uses only 3.
时间复杂度:O(n log n)
4. 图论中最短路径
给定一个边权图和两个顶点u和v,我们希望找到一条在u和v之间总权值最小的路径,其中路径的权值是它的边的权值的总和。
应用: 互联网数据包路由,航班预订和驾驶方向。
例如: 普罗维登斯(PVD)和檀香山(HNL)之间的最短路径
-
最短路径的子路径本身就是最短路径
例如:从普罗维登斯(PVD)到檀香山(HNL)的最短路径还包含从普罗维登斯(PVD)到洛杉矶(LAX)的最短路径。 -
有一个最短路径树,从一个开始顶点到所有其他顶点(最短路径树)。
示例:来自Providence的最短路径树(PVD)
5. Dijkstra’s Algorithm
输入: 图G = (V, E); 边的权重w: E→R+; 顶点v开始
输出: 在v中从s到所有v的距离; 以s为根的最短路径树
假设: G是连通的,无向边的权值是非负的
复杂度:O(m log n)
6. 最小生成树(MST)
给定边权值为ce的连通图G = (V, E), MST是边T E的子集,因此T是一个边权和最小的生成树。
7. 贪心算法
简化的假设。所有边缘成本Ce是不同的。
cut性质。设S为节点的任意子集,设e为S中只有一个端点的最小代价边,MST包含e。
cycle性质。设C为任意循环,f为属于C的最大代价边,则MST不包含f。
周期Cycle。a-b, b-c, c-d,…,y-z, z-a的边缘集合。
割集Cutset。一个割是节点S的子集,对应的割集D是在S中只有一个端点的边的子集。
Cycle-Cut十字路口
一个循环和一个割集相交于偶数条边。