高级算法题目,动态规划解

标签(空格分隔): 高级算法,动态规划

consider the following optimization problem.

Instance: n positive integers x1<x2<<xn .

Find two disjoint nonempty subsets A,B{1,2,,n} with iAxiiBxi ,such that the ratio iAxiiBxi is minimized.

Give a pseudo-polynomial time algorithm for the problem, and then give an FPTAS for the problem based on the pseudo-polynomial time algorithm.

解:
将原问题扩展为在A已经有 kA ,B已经有 kB 值的情况下,选择two disjoint nonempty subsets,使得
iAxi+kAiBxi+kB ,such that the ratio iAxi+kAiBxi+kB is minimized.
可以看的出来变化后的问题比原问题复杂.而原问题就是 kA,kB=0 的情况
在该问题上很容易写出递推式.
有n个整数 x1<x2<<xn ,所以在n上递推.记 OPT(i,kA,kB) 为有前 i 个整数,且A已经有 kA ,B已经有 kB 值的情况下的选择的最优解
对问题解 OPT(n,kA,kB) 做递推关系推导,分情况讨论。
1. xn 不在最优解 OPT(n,kA,kB)
此时 OPT(n,kA,kB) = OPT(n1,kA,kB)
2. xn 在最优解 OPT(n,kA,kB) 中,此时又有两种情况
2.1 xn A
此时可以认为 A 中有 xn 的情况下,求前 n1 个数的原问题的最优解,此时
OPT(n,kA,kB) = OPT(n1,kA+xn,kB)
2.2 xn B
此时可以认为 A 中有 xn 的情况下,求前 n1 个数的原问题的最优解,此时
OPT(n,kA,kB) = OPT(n1,kA,kB+xn)
综上可以认为:
OPT(n,kA,kB) = min{OPT(n1,kA,kB),OPT(n1,kA+xn,kB),OPT(n1,kA,kB+xn)}
这就是该问题的递推式.
原问题的答案的形式为 OPT(n,0,0) ,根据动态规划求得该式子即为解

算法复杂度为 O(nnixinixi)

下面给出FPTAS
xi=xik ,其中 k=ϵxmaxn ,此时算法复杂度为 nnxmaxknxmaxk=n5ϵ2

总结

  1. 本质上动态规划就是把某个递推公式从前向后展开。所以用动态规划做,第一件事就是要写出递推公式。
  2. 而递推的含义本质上就是先计算出规模更小的问题,然后用规模更小的问题解决规模更大的问题。
  3. 分情况讨论的方法很容易产生递推式.
  4. 递推产生的问题可能比原问题复杂,原问题是新问题的子集

附 对揹包问题动态规划的理解

OPT(n,c) 为有n个物体,揹包容量为c时的最佳解决方案。
很容易产生递推式,分情况讨论:
1.最后一个物体在 OPT(n,c) 中。即在我们找到的揹包问题最佳方案中,最后一个物体被选中,装进了揹包里
那么此时,我们只需要解决 前n-1个物体在揹包已经装了第n个物体时,应当怎么选择使得价值最大 这个问题。此时揹包容量只有 cc(n) ,而这个问题就是 OPT(n1,cc(n)) c(n) 指最后一个物体的容量
2.最后一个物体不在 OPT(n,c) 中。也就是最佳解决方案并没有选择最后一个物体.
此时, OPT(n,c)=OPT(n1,c)

综上, OPT(n,c)=min{OPT(n1,cc(n)),OPT(n1,c)}
所以一个很简单的分类讨论,就可以写出递推式。
然后用动态规划写出递归函数的展开形式,就是揹包问题的动态规划方法.

而我在试图通过分类讨论写出上面问题的递推式时,发现必须要解决带 kA,kB 的更复杂的问题。而原问题是新问题的一个子集。所以很容易通过分类讨论将原问题扩展到更复杂的新问题。

这不经让我想到数理逻辑中证明完全性定理时的情形。有时候要解决问题A,必须首先将问题A扩充为问题B,问题A是问题B的一个子集。然后解决问题B.几何里的辅助线,羣里的羣作用思想不也是同样的思想吗。

点赞