贪心算法
问题一:
一个活动ai的列表,1<=i<=n,si时间开始,fi结束,没有两个活动在同时发生。
任务:找到最大兼容size的子集。
尝试1:总是选择最短且与之前不冲突活动,删掉冲突的活动?
不可以。
尝试2:选择一个与其他冲突最小的activity。看起来对未来选择限制最小。
不可以。
**正确的策略:**在不与之前选择的冲突下,总是选择结束时间最早的。
证明这个贪心算法的最优
证明任何最优解与贪婪算法的活动数量相同:
- 找到违反贪婪原则的第一个的活动。
- 表明用贪婪算法的选择代替这个活动可以得到相同数量的活动。
- 循环以上步骤知道贪婪算法完全代替最优解。
时间复杂度:
我们将他们的对初始时间和结束时间排序,按结束时间的增序。
—>时间复杂度:O(nlogn)
我们按顺序查看列表,找到第一个开始时间是在前一个活动的结束时间之后的活动。
每个活动被执行一次,所以每次需要O(n).
所以,总的时间复杂度是O(nlogn).
问题二:
一个活动列表同问题一,但结束时间是fi=si+d. 所以所有的活动的运行时间都相同。没有两个活动占用同样的时间。
任务:找到一个有最大持续时间的活动子集。
因为所有的活动持续时间一样,等价于找到不冲突的活动的最大个数。
如果持续时间不一样呢?
贪心策略不能用了。—>动态规划
问题三:
Telstra想为住户提供网络服务,基站范围是5km。放置最少的基站覆盖所有房屋。
贪心算法:
一名Telstra工程师从最靠近左边的房屋开始,并在5公里处放置了一座塔。然后,他找到了不在基站范围内的最西侧的房屋,并在距基站以东5公里处放置了另一座塔楼,并以此方式循环。
他的另一名同事做了相同的事但是从右向左,并称用了更少的塔?
答案是否定的。因为最优算法左右都是一样的。
问题四:
初始时间T0,有一系列工作ai,1<=i<=n, 持续时间ti并且截止时间di。同事间只有一个工作在进行。所有工作必须完成。如果一个工作ai在fi>di的时间完成,则算推迟时间li=fi-di。
任务:计划所有的时间,使job最大的推迟时间最短。
解决方式:忽略工作持续时间并且按截止时间的升序安排工作。
最优解:考虑最优解不包含反转。如果ai被安排在 aj之前但dj <di,则作业ai和aj形成一个反转。
如图,dj<di, 但工作i在工作j之前被安排。
我们需证明存在一个解没有任何的相反。
冒泡排序消除反转!
因为反转后fi-di和f(i+1)-d(i+1)都小于反转前的f(i+1)-d(i+1),
交换相邻的相反的工作减少最大延迟时间。所以交换直到消除反转。
问题5:Tape storage
一个有着n个files,长度为li的列表需要存储到磁带上。每个文件可能性均等。要检索一个文件,必须从头开始扫描直到找到磁盘上对应文件。
任务:对磁盘上文件排序使平均检索时间最小。
解决方法:如果文件按l1…ln的顺序存储,所以预计时间是:
l1+(l1+l2)+(l1+l2+l3)+…+(l1+l2+l3+…+ln)=nl1+(n-1)l2+(n-3)l3+…+2l(n-1)&