1.贪婪算法的基本思想
求解一个最优化问题包含一系列的步骤,每一步都有一组选择,做出在当前看来最好的选择,希望通过做出局部优化选择来达到全局优化选择,这就是贪婪算法的基本思想。
贪婪算法能否产生优化解具有两个条件:Greedy选择性和优化子结构。
Greedy选择性:若一个优化问题的全局优化解可以通过局部优化地选择得到,则该问题具有Greedy选择性。
优化子结构:若一个优化问题的优化解包含他的子问题的优化解,则称其具有优化子结构。
2.求解最大相容集合
2.1 问题定义
输入:S = { 1, 2, ... , n }, F = { [si, fi] }, n ≥ i ≥ 1;
输出:S的最大相容集合;
题目大意就是已知n个活动的开始和结束时间,求出在时间不冲突的情况下,最多可举行活动的数量。
2.2 算法分析
为了选择最多相容的活动,每次选择fi最小的活动,这样我们就能选择更多的活动。该问题是否可以使用贪婪算法需要我们讨论此问题是否满足Greedy选择性和优化子结构,分析如下图所示。
理论依据有了,就可以大胆编写代码来实现了。
3.代码实现
import numpy as np
# 需要安排的活动集合
activity_set = np.array([[2,3],[4,5],[6,8],[2,5],[3,6],[5,6]])
# 活动数目
num = len(activity_set)
# 定义一个集合存放最终结果
result_set = set()
# 将活动按照结束时间递增排序
activity_set = activity_set[activity_set[:,1].argsort()]
# 把第一个活动放入结果集合
result_set.add((activity_set[0][0],activity_set[0][1]))
# 从第二个活动开始遍历,若活动的开始时间在前一个活动结束时间之后,那此活动相容,
#并且该活动也变成衡量其他活动是否相容的对象
j = 0
i = 1
while i < num:
if activity_set[i][0] >= activity_set[j][1]:
result_set.add((activity_set[i][0],activity_set[i][1]))
j = i
i += 1
print '相容最大集合为:',result_set
4.时间复杂性分析
-如果结束时间已排序:O(n)
-如果结束时间未排序:O(nlogn)