Greedy Method Intro Note

436 阅读3分钟

1. 贪心算法介绍

1.1 目的

解决最优问题(最大或者最小)

最优问题举例 : 比如A点到B点有多条路径, 选择哪条路径时间最短?

1.2 大致思路

Greedy Method

def Greedy(a, n):
	for i in range(1, n):
    	  x = select(a) // 选择策略
          if feasible(x): // 如果可行
          	solution = solution + x // 加入结果集

1.3 举例

买最好的车

  • 方案一: 查看城里所有城里最好的车直到找到最好的
  • 方案二: 选择城里最知名的车, 觉得他是最好的车 在方案二中, (我) 有自己的select的方案, 我认为好的车是知名的, 根据这个结果, 挑选出知名的车, 找到其中最好的(但不代表是客观意义上的最好, 是我选择策略中的最好)

2. Knapsack Problem

一个m=15容量的包, n=7个object, 每个物体有profit利润,和重量weight, 条件: 放满15kg的包, 利润最大化

  • 选出p/w最大的物体, 如果没有超重加入背包中.
  • 选择下一个物体, 到达15KG则退出

3. Job Sequencing with Deadlines

问题描述: 你是一个店员, 你需要做三样工作不能同时进行, 从9点12点, 分别是j1j5 5个工作, 对应有他的总利润和deadline, 比如9点开门, job1的ddl是2小时, 就说明要在11点前完成.

贪心策略

  • 选择利润最大的工作J1, 利润为20,
  • 需要在9+2 = 11点前做完, 所以910, 1011 来进行这个工作
  • 继续这个策略然后选择利润最大工作j2
  • j3因为需要在9+1=10点前完成, 已经被j1, j2 占据 不可选
  • 选择j4
  • 最后结果(j1, j2, j4)

小结

  • 还是那个思想, 选择某个局部条件最优(如利润), 判断是否满足限制条件(如工作时间),如果可以则加入结果集, 不可以继续查看下一个

4. Optimal Merge Pattern

前置知识

如果想要合并两个有序数组长度为m和n, 至少需要m+n次操作.

问题

  • 现在我们想合并4个数组, 长度分别为6, 5, 2, 3
  • 方法一 40次操作 直接按6合并5, 然后合并2再合并3, 一共需要40次操作, 而6+5+2+3=16次操作
  • 方法二 32次操作
  • 方法三 31次操作

规律

  • 先把小的数组合并在一起, 再合并大的.

补充例子

5. 霍夫曼编码

前置知识

  • 用于对发送的消息编码, 我们知道比如要传输英文字符,用ASCII编码, 每个字符占8位, 如'A', 数字表示为65, 二进制表示为01000001, 但如果我们不需要发送ASCII码中的所有字符,因此需要压缩编码

定长编码

如下图, 其中ABCDE, 为使用到得字符, 要表示5种不同的字符, 至少需要3位, 2^3=8, 每个字符用3个二进制数表示, 整个消息一共20个字符, 20x3 = 60bits.

霍夫曼编码

  • 用到了贪婪算法,每次挑选出现频次最小的字符结合,那么最终结果就是, 用较短的二进制码表示出现频次高的字符, 用较长的二进制码表示出现频次较低的字符, 最终只需要45bits来表示整个message的信息.

参考

video link