本文主要是介绍南开大学软件学院2021年秋季学期研究生算法课程(复习)贪心分治之分治(包含快速傅里叶变换),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
状态空间中的算法
状态空间:状态(点)+状态转移(边)+价值函数(点权)
- 求解过程的抽象模型
- 暴力搜索和动态规划都是一类算法框架(或算法思想),本质都是在状态空间中寻找解
- 二者都需要准确地用最少的状态变量建模
- 而对于动态规划,还需要定义正确的价值函数和转移更新
分治:子问题互不重叠,但最优子结构需考虑全部子问题
贪心:子问题互不重叠,但最优子结构仅考虑极少子问题
若认为动态规划算法的状态空间是有向无环图的话,对于分治和贪心,其状态空间通常可以建模成树,分治需要评估整个树,贪心则是树上的几条链
分治与贪心
经典算法回顾
归并排序:用两个子状态的解构造按序拼接当前状态的解,分治算法,时间复杂度O(n logn)
逆序对个数:用两个子状态的解构造统计个数当前状态的解,分治算法,时间复杂度O(n logn)
快速排序:需用两个子状态的解构造按序拼接当前状态的解,分治算法,期望时间复杂度O(n logn)
第k大数:仅需某一个子状态的解即可,贪心算法,期望时间复杂度O(n)
矩阵快速幂:两个子状态的解相同,贪心算法,时间复杂度O(logn)
分治
Strassen矩阵乘法
给出矩阵,求。
- 直接乘法的时间复杂度O(n^3)
- Strassen乘法的核心思想:分块矩阵。
- Strassen算法会复用分块矩阵乘法结果,先10次加法计算:
- 再用7次乘法计算:
- 最终使用8次加法得出结果:
- 时间复杂度?
分治算法的时间复杂度:T(n)=aT(n/b)+O(n^d)
主定理
一维数值积分
给出一维函数,计算(无闭式解)
- 梯形近似法:将区间等分n份,求n个梯形的面积和
- 对于区间,其梯形面积等价于过点和线性函数的积分
- 求过2个点的线性函数即线性插值(一次插值)
一维数值积分
给出一维函数,计算(无闭式解)
- 插值interpolation 拉格朗日插值多项式
- n+1个不同的点,可确定n阶多项式函数的全部系数
- 梯形法即为一次插值(但是近似程度不够)
- 优化一:利用二次插值(利用a,m=(a+b)/2,b三个点)
- 数值积分转化为下式(即辛普森积分法)
一维数值积分
给出一维函数,计算(无闭式解)
- 梯形近似法:将区间等分n份,求n个梯形的面积和
- 思考:分到多细为止?等分是否有问题?
- 显然,每个区间不必分解到相同粒度,但分解后结果要使得积分值在误差范围内
- 优化二:自适应辛普森算法----自适应算法也是一类算法框架
- AdaSimp(a,b,S(a,b,f)),其中S()为辛普森积分函数
- 计算S(a,m,f)和S(m,b,f)
- 若,则返回S(a,b,f)
- 否则,返回
- 时间复杂度?取决于的性质和的大小
- 思考:高维积分这种方法还可行吗?不可行的话该怎么办?
多项式算法
n阶多项式A(x)的定义为
给出两个n阶多项式A(x),B(x),计算C(x)=A(x)✖B(x)
- 多项式乘法:时间复杂度:O(n)
- 多项式乘法:时间复杂度:O(n^2)
多项式的表示法
以下对n-1阶多项式讨论
- 系数表示法Coefficient representation
- 即系数向量即可表示一个多项式
- 加法时间复杂度O(n),乘法时间复杂度O(n^2)
- 点值表示法Point-value representation
- 即使用n个点即可表示n-1阶多项式,其中要求
- 若对于A(x)的点值表示和B(x)的点值表示
- 加法结果为复杂度O(n)
- 乘法结果注意为2n-2阶多项式,需要2n-1个点确定,即为复杂度O(n)
多项式表示法的转换
以下对n-1阶多项式讨论
- 求值Evaluation:系数表示➡点值表示
- 秦九韶算法/Horner's rule:
- 对n个点进行计算,总共需要O(n^2)的时间
- 插值Interpolation:点值表示➡插值表示
- 多项式插值唯一性:范德蒙德矩阵非奇异
- 拉格朗日插值,时间复杂度O(n^2)
-
于是,计算乘积可以通过
- A(x),B(x)系数表示➡系数乘法 O(n^2)➡C(x)系数表示
- A(x),B(x)系数表示➡求值 O(n^2)➡A(x),B(x)点值表示➡点值乘法 O(n)➡C(x)点值表示➡插值 O(n^2)➡C(x)系数表示
快速傅里叶变换Fast Fourier Transform,FFT
选n个特殊点,用分治优化求值和插值为O(n logn)
- A(x),B(x)系数表示➡FFT求值 O(n log n)➡A(x),B(x)点值表示➡点值乘法 O(n)➡C(x)点值表示➡FFT插值 O(n log n)➡C(x)系数表示
特殊的点为第k个n次单位根
背景知识:复变函数
- 复数的四则运算:加减乘除
- 复数的几何表示:复平面,模长和辐角
- 运算的几何意义:加:四边形法则;乘:模长乘,辐角加
- 欧拉公式:
- 单位根:复数域上满足所有解:共有n个根,记作
- n个单位根构成了循环群,生成元(本源根)
- 模n加/乘法群,,
- 折半引理:
- 消去引理:
- 求和引理:
离散傅里叶变换Discrete Fourier Transform,DFT
即对n-1阶多项式A(x)在n次单位根上的求值过程
- 给出的系数表示,即向量,计算其在n次单位根上的值,即
- 在这种情况下,向量即为系数向量的离散傅里叶变换,记作
- 或者
- 由单位根的特殊性质,DFT可用分治快速完成➡FFT
快速傅里叶变化(求值部分)
- 首先,假定A(x)的阶数n为2的整数次幂(通过引入0系数高阶项可以永远做到)
- 分别通过A(x)的奇数次项和偶数次项系数定义新多项式
- 由此可得分治算法的关键:
- 因此,计算A(x)在上的值,可以转化为:
- 先计算和在上的值(注意根据折半引理和消去引理可以使计算点的个数减半)
- 再根据合并结果
- 具体来说,计算,可以转化为:
- 对于(前n/2个点)
- 对于(后n/2个点,但)
- 总结来说,A(x)上的n次单位根的值,只需分别计算一遍,的n/2次单位根值即可构造出来
- 时间复杂度?
快速傅里叶变换(插值部分)
- 注意,离散傅里叶变换 其实可以写成矩阵形式,其中是范德蒙德矩阵,第k行第j列元素为
- 于是,也就是,由范德蒙德矩阵的求逆公式,第k行第j列元素为
- 因此,插值部分即将视作系数向量,构成新多项式,计算其在点上的值,所得向量结果除上n即得到答案,此过程同理亦可分治
分治算法小结
- 难点:综合所有子问题的解构造问题的解的过程
- 特点:时间复杂度通常使用主定理计算
- 思维特点:
- 子问题规模要成倍缩小;(分解)
- 假设子问题完成,如何得出原问题的答案;(合并)
- 更多:平面最近点对、CDQ分治、并行分布式的Map-Reduce
这篇关于南开大学软件学院2021年秋季学期研究生算法课程(复习)贪心分治之分治(包含快速傅里叶变换)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!