Coursera - Algorithm (Stanford) - 课程笔记 - Week 12

Knapsack Problem

  • 问题定义
    • 输入: n n n件物品,每个物品包含两个数据——价值 v i v_i vi,和大小 w i w_i wi,以及目标背包的大小 W W W
    • 输出:一个自己 S ⊆ { 1 , 2 , … , n } S \sube \{1, 2, \dots, n\} S{1,2,,n},最大化 ∑ i ∈ S v i \sum_{i \in S} v_i iSvi,要求 ∑ i ∈ S w i ≤ W \sum_{i \in S} w_i \le W iSwiW
  • 最优子结构
    • 如果 n ∉ S n \notin S n/S S S S必然为前 n − 1 n - 1 n1个物品的最优解
    • 如果 n ∈ S n \in S nS,那么 S − n S - n Sn W − w n W - w_n Wwn的背包的最优解
    • v i , x = max ⁡ { v i − 1 , x , v i − 1 , x − w i + v i } v_{i, x} = \max \{v_{i-1, x}, v_{i-1, x- w_i} + v_i\} vi,x=max{vi1,x,vi1,xwi+vi}
  • 实现
    • 二维数组,从左到右不断更新(两重循环): A [ i , x ] = max ⁡ { A [ i − 1 , x ] , A [ i − 1 , x − w i ] + v i } A[i, x] = \max \{A[i - 1, x], A[i - 1, x - w_i] + v_i\} A[i,x]=max{A[i1,x],A[i1,xwi]+vi}
    • 时间复杂度 θ ( n W ) \theta(nW) θ(nW)
  • 结果重建
    • 最佳价值: A [ n , W ] A[n, W] A[n,W]
    • 结果重建
      • 如果 A [ i , x ] = A [ i − 1 , x ] A[i, x] = A[i - 1, x] A[i,x]=A[i1,x],那么此时不包含第 i i i个物体,从 A [ i − 1 , x ] A[i - 1, x] A[i1,x]继续考察
      • 如果 A [ i , x ] = A [ i − 1 , x − w i ] + v i A[i, x] = A[i - 1, x - w_i] + v_i A[i,x]=A[i1,xwi]+vi,那么此时包含第 i i i个物体,从 A [ i − 1 , x − w i ] A[i - 1, x -w_i] A[i1,xwi]继续考察

Sequence Alignment

  • 问题定义
    • 输入: X = x 1 , … , x m X = x_1, \dots, x_m X=x1,,xm Y = y 1 , … , y n Y = y_1, \dots, y_n Y=y1,,yn,插入空行罚分 α g a p \alpha_{gap} αgap,匹配罚分 α a b \alpha_{ab} αab
    • 输出:对齐结果,最少罚分
  • 最优子结构
    • 考虑当前对齐情形的两个序列的最后一个位置
      • x m , y n x_m, y_n xm,yn匹配
      • x m , _ x_m, \_ xm,_匹配
      • _ , y n \_, y_n _,yn匹配
    • X ′ = X − x m X^\prime = X - x_m X=Xxm Y ′ = Y − y n Y^\prime = Y - y_n Y=Yyn
      • 第一种情形, X ′ X^\prime X Y ′ Y^\prime Y的对齐结果将是最优的
      • 第二种情形, X ′ X^\prime X Y Y Y的对齐结果将是最优的
      • 第三种情形, X X X Y ′ Y^\prime Y的对齐结果将是最优的
  • 算法实现
    • X i X_i Xi表示 X X X的前 i i i个字符, Y j Y_j Yj同理
    • P i j P_{ij} Pij为和 X i X_i Xi Y j Y_j Yj的对齐罚分综合, P i j = { α x i y j + P i − 1 , j − i α g a p + P i − 1 , j α g a p + P i , j − 1 P_{ij} = \begin{cases}\alpha_{x_i y_j} &+& P_{i - 1, j - i} \\ \alpha_{gap} &+& P_{i - 1, j} \\ \alpha_{gap} &+& P_{i, j - 1} \end{cases} Pij=αxiyjαgapαgap+++Pi1,jiPi1,jPi,j1
    • 初始化: A [ i , 0 ] = A [ 0 , i ] = i ⋅ α g a p A[i, 0] = A[0, i] = i \cdot \alpha_{gap} A[i,0]=A[0,i]=iαgap
    • 两重循环,考察两个序列长度
      • A [ i , j ] = min ⁡ { A [ i − 1 , j − 1 ] + α x i , y j , A [ i − 1 , j ] + α g a p , A [ i , j − 1 ] + α g a p } A[i, j] = \min \{A[i - 1, j - 1] + \alpha_{x_i, y_j}, A[i - 1, j] + \alpha_{gap}, A[i, j - 1] + \alpha_{gap}\} A[i,j]=min{A[i1,j1]+αxi,yj,A[i1,j]+αgap,A[i,j1]+αgap}
    • 解重建
      • 向前回溯
      • 类似地,比较三种情形的罚分情形,取最佳,并继续考察对应位置
      • 任意一个序列到头,则直接加入对应数量的gap
    • 时间复杂度 O ( m + n ) O(m + n) O(m+n)

Optimal Binary Search Tree

  • 问题定义
    • 最佳的二叉搜索树:对于任意一个给定键值分布,搜索时间复杂度保持在最优
    • 在查询概率已知的情形下,平衡二叉树不一定最优,可以比 O ( log ⁡ n ) O(\log n) O(logn)更好
    • 给定对应键值的被查询概率分别为 p i p_i pi,键值按编号排大小
    • 最小查询时间 C ( T ) = ∑ i p i ⋅ d e p t h i C(T) = \sum_i p_i \cdot depth_i C(T)=ipidepthi
  • 最优子结构
    • 给定根节点 r r r,左子树要保证对 { 1 , … , r − 1 } \{1, \dots, r - 1\} {1,,r1}最优,右子树保证对 { r + 1 , … , n } \{r + 1, \dots, n\} {r+1,,n}最优
    • 子结构性质: C ( T ) = ∑ k p k + C ( T 1 ) + C ( T 2 ) C(T) = \sum_k p_k + C(T_1) + C(T_2) C(T)=kpk+C(T1)+C(T2)
    • 计算项目:最优连续区间 { i , i + 1 , … , j − 1 , j } \{i, i + 1, \dots, j - 1, j\} {i,i+1,,j1,j},类似于上述问题丢掉后缀,这里要分别丢掉前缀和后缀
  • 算法
    • C i j C_{ij} Cij为区间 { i , i + 1 , … , j − 1 , j } \{i, i + 1, \dots, j - 1, j\} {i,i+1,,j1,j}的加权代价
    • C i j = min ⁡ r { ∑ k p k + C i , r − 1 + C r + 1 , j } C_{ij} = \min_r \{\sum_k p_k + C_{i, r -1} + C_{r + 1, j}\} Cij=minr{kpk+Ci,r1+Cr+1,j}
    • 边界约定: C x y = 0 C_{xy} = 0 Cxy=0,如果 x > y x \gt y x>y
    • 两重循环(si): A [ i , i + s ] = min ⁡ r { ∑ k p k + A [ i , r − 1 ] + A [ r + 1. i + s ] } A[i, i + s] = \min_r \{\sum_k p_k + A[i, r - 1] + A[r + 1. i + s]\} A[i,i+s]=minr{kpk+A[i,r1]+A[r+1.i+s]}
    • 最优代价: A [ 1 , n ] A[1, n] A[1,n]
    • 实现过程中实际只计算了一个上三角矩阵
    • 运行时间复杂度: O ( n 3 ) O(n^3) O(n3) n 2 n^2 n2个子问题,每个问题的计算是线性时间)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值