《算法导论》学习笔记
这次读《算法导论》的重点主要在算法的理论分析上,这一点是原先信息学竞赛部分缺失的。
习题答案:https://walkccc.me/CLRS/
函数的增长
\(\Theta\)记号
\(f(n)=\Theta(g(n))\)当且仅当存在\(c_1>0\),\(c_2>0\)和\(n_0\)满足对任意\(n\ge n_0\)都有\(c_1g(n)\le f(n)\le c_2g(n)\)。称为\(f(n)\)的渐进确界。
实际上就是\(f(n)/g(n)\)的上极限小于等于\(c_2\)不为无穷,下极限大于等于\(c_1\),大于0。那么对于常见的函数,我认为可以直接通过计算\(f(n)/g(n)\)的极限,再根据收敛函数上下极限都为极限得证,比构造证明要更简单。
显然有:如果\(f(n)=\Theta(g(n))\),则\(g(n)=\Theta(f(n))\)。
另外,我们可以类似地定义二元函数的\(\Theta\)记号,改为存在\(n_0\)和\(m_0\)即可。
\(O\)记号和\(\Omega\)记号
\(f(n)=O(g(n))\)当且仅当存在\(c和\)n_0\(满足对任意\)n\ge n_0$都有\(0\le f(n)\le cg(n)\)。称为\(f(n)\)的渐进上界。
\(f(n)=\Omega(g(n))\)当且仅当存在\(c\)和\(n_0\)满足对任意\(n\ge n_0\)都有\(cg(n)\le f(n)\)。称为\(f(n)\)的渐进下界。
渐进上界只要求\(f(n)/g(n)\)的上极限不为无穷,渐进下界只要求\(f(n)/g(n)\)的下界不为0。
\(o\)记号和\(\omega\)记号
\(f(n)=o(g(n))\)当且仅当对任意的\(c>0\)都存在\(n_0\)满足对任意\(n\ge n_0\)都有\(0\le f(n)\le cg(n)\)。可以直接写成\(\lim_{n\to \infty}f(n)/g(n)=0\)。
\(f(n)=\omega(g(n))\)当且仅当对任意的\(c>0\)都存在\(n_0\)满足对任意\(n\ge n_0\)都有\(cg(n)\le f(n)\)。可以直接写成\(\lim_{n\to \infty}f(n)/g(n)=\infty\)。
可以大致理解为\(\Theta\)表示相等,\(O\)表示小于等于,\(\Omega\)表示大于等于,\(o\)表示小于,\(\omega\)表示大于。
五种符号都满足传递性,正如实数的大小关系也满足传递性。
需要注意的是可能存在两个函数不满足任何记号,例如\(n\)和\(n^{1+\sin(n)}\),相除得到\(n^{\sin(n)}\),上极限为无穷,下极限为0。
有著名的式子:当\(a>1\)时有\(\lim_{n\to \infty}\frac{n^b}{a^n}=0\)。即\(n^b=o(a^n)\),\(\log^b(n)=o(n^a)\),似乎常用\(\epsilon\)记这种情况的\(a\)。
斯特林近似公式:\(n!=\sqrt{2\pi n}(n/e)^n(1+\Theta(1/n))\)。那么可以得到\(log(n!)=\Theta(n\log n)\)。
\(f(n)=\widetilde{O}(g(n))\)当且仅当存在\(c>0\),\(k\)和\(n_0\)满足对任意\(n\ge n_0\)都有\(f(n)\le cg(n)\log^k(n)\),表示忽略对数因子的\(O\)记号。
分治策略
矩阵乘法的strassen算法
思路类似分治的多项式乘法\(T(n)=3T(n/2)+\Theta(n)\),\(T(n)=\Theta(n^{1.585})\)。将矩阵分成四个部分,原本需要进行八次\(n/2\)规模的矩阵乘法,可以通过线性运算减少到七次,\(T(n)=7T(n/2)+\Theta(n^2)\),\(T(n)=\Theta(n^{2.807})\)。
通过加法和乘常数的运算来减少乘法运算,本质就是通过构造尽量少的向量对\(\vec{x_j}\)和\(\vec{y_j}\),使得对任意的矩阵\(M_i\)都在\(\vec{x_j}\vec{y_j}^{T}\)张成的空间内,其中矩阵\(M_i\)表示需要的第\(i\)个表达式中有每对数相乘的系数矩阵。我尝试直接搜索构造\(\vec{x_j}\)和\(\vec{y_j}\)属于\(\{-1,0,1\}\)的情况,效率比较低,strassen算法中有八个变量无法承受。
主方法求解递推式
\(T(n)=aT(n/b)+f(n)\) (1)存在某个常数\(\varepsilon>0\)满足\(f(n)=O(n^{log_b{a}-\varepsilon})\),\(T(n)=\Theta(n^{log_b{a}})\) (2)如果\(f(n)=\Theta(n^{log_b{a}})\),\(T(n)=\Theta(n^{log_b{a}log n})\) (3)存在某个常数\(\varepsilon>0\)满足\(f(n)=\Omega(n^{log_b{a}+\varepsilon})\),\(T(n)=\Theta(f(n))\)。
画出来递归树,如果每一层的复杂度相同,那么就是\(f(n)log n\);如果下层“更慢”,复杂度就是最下层节点数;如果上层“更慢”,复杂度就是第一层的时间。
矩阵运算
由于线性代数的知识比较缺乏,暂时略去证明。
先附上一些基本定义和结论:
·向量\(x\)的范式\(\|x\|=(x^Tx)^{1/2}\)
·奇异矩阵:不可逆的矩阵 非奇异矩阵的逆矩阵唯一
·\((AB)^T=B^TA^T\) (BA){-1}=AB^{-1}$ \((A^{-1})^T=(A^T)^{-1}\)
·任意矩阵的行秩等于列秩
·空向量\(x\)定义为满足\(Ax=0\)的非零向量,列满秩当且仅当不存在空向量,矩阵是奇异的当且仅当存在空向量
·正定矩阵:对任意非零向量都有\(x^TAx>0\)
·对称矩阵:\(A=A^T\)的矩阵
·对任意列满秩的矩阵,\(A^TA\)是对称正定矩阵
解线性方程组
解\(Ax=b\),通过LUP分解,找到\(n\times n\)的矩阵\(P\) \(L\) \(U\),其中\(L\)是单位下三角矩阵,\(U\)是上三角矩阵,\(P\)是置换矩阵,满足\(PA=LU\)。则\(LUx=Pb\),先解\(Ux\),再解\(x\)。
平常的高斯消元就是利用矩阵的线性变换(交换行,一行减另一行的若干倍)只得到\(U\),\(P\)和\(L\)本质就是“记录”线性变换的过程。
第一个等号说明了高斯消元中任一行减另一行若干倍的线性变换:\(A=LA'\);
第二个和第三个等号说明了递归子问题可以得到\(A=L_1L_2...LnU=LU\),其中\(L\)的第\(i\)列就是\(L_i\)的第\(i\)列(\(L_i\)的其他列和单位矩阵相同)。
那么对于\(P\)矩阵的构造思路类似,置换矩阵的乘法就是置换的复合,在递归子问题的同时可以写成\(P_nP_{n-1}...P_1A=LU\),其中每个\(P_i\)都是选择一行与第\(i\)行交换,具体可以用\(\pi\)来实现,\(P\)乘积的结果就是矩阵\(P_{i,\pi_i}=1\),每次交换第\(i\)行和第\(j\)行就是交换\(\pi_i\)和\(\pi_j\),最终得到\(PA=LU\)。
对称正定矩阵在LUP分解中的性质
·对称正定矩阵是非奇异矩阵:奇异矩阵存在空向量,\(Ax=0\)则\(x^TAx=0\),而正定矩阵保证不存在这样的\(x\)
·对称正定矩阵每一个主子矩阵都是对称正定的:取任何一个\(n\)维向量\(x\)只有前\(k\)维非零则\(0<x^TAx=x^TA_kx\)。
定义\(A=\begin{bmatrix}A_k& B^T\\ B& C\end{bmatrix}\)\(关于\)A_k\(的**舒尔补**为\)S=C-BA_k{-1}BT\(,原本LUP分解就是不断的使用\)k=1$的舒尔补。
舒尔补引理 对于对称正定矩阵\(A\),\(A\)关于\(A_k\)的舒尔补是对称正定的。
证明:利用对称的定义和\(A_k\)是对称的即可证明\(S\)是对称的;利用\(A\)的划分,把\(x\)划分为\(\begin{bmatrix}y\\ z\end{bmatrix}\),由于\(x^TAx>0\),有\(x^TAx=y^TA_ky+z^TBy+y^TB^Tz+z^TCz=(y+A_k^{-1}B^Tz)^TA_k(y+A_k^{-1}B^Tz)+z^T(C-BA_k^{-1}B^T)z\),则要证明舒尔补是正定的,只需要令\(y=0\)则此时\(z^TSz=x^TAx>0\)。
那么根据该引理,LUP分解的过程中每次得到的舒尔补的左上角元素\(a_11=e_1^TAe_1>0\),因此不需要置换矩阵,进行LU分解即可。
逆矩阵
\(AX=I_n\)可以看作是\(n\)个方程\(AX_i=e_i\)的向量解构成的矩阵,最简单的方法是先\(\Theta(n^3)\)时间内求出LUP分解,再对每个\(i\)以\(\Theta(n^2)\)时间内求\(X_i\)。
接下来说明矩阵求逆运算等价于矩阵乘法运算,即可以互相规约。
矩阵乘法不比矩阵求逆困难 如果能在\(I(n)=\Omega(n^2)\)时间内求出\(n\times n\)的矩阵的逆,且\(I(n)\)满足正则性条件\(I(3n)=O(I(n))\),则可在\(O(I(n))\)的时间内求出两个矩阵的乘积。
令
则
矩阵求逆不比矩阵乘法困难 如果能在\(M(n)=\Omega(n^2)\),且\(M\)满足两个正则性条件:对任意的\(0\le k\le n\)都有\(M(n+k)=O(M(n))\)和存在常数\(c<1/2\)使得\(M(n/2)\le cM(n)\),则可在\(O(M(n))\)时间内计算出任何一个非奇异矩阵的逆。
证明:先考虑正定对称矩阵。思路是利用舒尔补和分治,\(A=\begin{bmatrix}B& C^T\\ C& D\end{bmatrix}\),手动高斯消元求逆可以得到\(A^{-1}=\begin{bmatrix}B^{-1}+B^{-1}C^TS^{-1}CB^{-1}& -B^{-1}C^TS^{-1}\\ -S^{-1}CB^{-1} S^{-1}\end{bmatrix}\),那么将\(A\)的大小补成2的幂后每次将\(A\)切成等大的四块,分治求解\(B^{-1}\)和\(S^{-1}\),进行四次矩阵乘法,利用主定理有\(I(n)\le 2I(n/2)+4M(n/2)+O(n^2)=O(M(n))。对于非正定对称矩阵,利用\)A{-1}=(ATA){-1}AT,\(A^TA\)是正定对称矩阵。
通过这个证明,解线性方程组是也可写成\((A^TA)x=A^Tb\),再用LU分解\(A^TA\)。
最小二乘逼近
给定\(m\)个点\((x_i,y_i)\),令\(F(x)=\sum_{i=1}^{n}c_ix^{i-1}\),\(\eta_i=F(x_i)-y_i\),构造\(c\)使得\(\|\eta\|\)最小。注意如果\(n=m\)可以使得\(\eta=0\),这里只考虑\(n<m\)的情况。
令\(A_{i,j}=x_i^{j-1}\),则\(\eta=Ac-y\),\(\|\eta\|^2\)对\(c_k\)求偏导数得到\(\sum_{i}(Ac-y)_ia_{ik}=0\),即\((Ac-y)^TA=0\),\(A^T(Ac-y)=0\),\(A^TAc=A^Ty\),\(c=(A^TA)^{-1}A^Ty\),\(A^TA\)在列满秩是是正定矩阵。
线性规划
标准型
maximize \(c^{T}x\)
subject to \(Ax\le b\) \(x\ge 0\)
其中\(A\)的大小是\(m\times n\),即有\(m\)个限制,\(n\)个变量。
松弛型(slack form)
maximize \(v+c^{T}x\)
subject to \(b-Ax=y\) \(x\ge 0\) \(y\ge 0\)
为方便代码实现,令\(x_{n+i}=y_i\)。变量分为两类,一类是由等式计算得到的,也就是原来的\(y\),称为基本变量,对应\(c\)的值为0,\(b\)和\(A\)描述其等式关系\(x_i=b_i-\sum_{j}A_{i,j}x_j\);另一类是非基本变量,对应的\(b\)和\(A\)没有意义,在之后的转动中基本变量和非基本变量会不断转换。
需要始终保证的是,非基本变量取值为0时构成一组合法解,即基本变量值为\(b_i\ge 0\),目标值此时为\(v\)。
转动(pivot)
设\(B\)集合中的变量为基本变量,\(N\)集合中的变量为非基本变量。
取一个\(e\in N\)和\(l\in B\),将\(e\)变为基本变量,\(l\)变为非基本变量。\(\hat{N}=N\setminus \{e\} \cup \{l\}\),\(\hat{B}=B\setminus \{l\} \cup \{e\}\)。
需要进行的操作有:
1.将\(x_l\)的等式\(x_l=-\sum_{j\in N,j\ne e}A_{l,j}x_j-A_{l,e}x_e+b_l\)改写成\(x_e=-\sum_{j\in N,j\ne e}\frac{A_{l,j}}{A_{l,e}}x_j-\frac{1}{A_{l,e}}x_l+\frac{b_l}{A_{l,e}}\),对应到新的\(\hat{A}_{e,j}\),\(\hat{A}_{e,l}\),\(\hat{b}_e\)。
2.将其他基本变量\(x_i\)的等式改写为\(x_i=-\sum_{j\in \hat{N}}(A_{i,j}-A_{i,e}\hat{A}_{e,j})x_j+(b_i-A_{i,e}\hat{b}_e)\),对应到新的\(\hat{A}_{i,j}\)和\(\hat{b}_j\)。
3.重写目标值为\(v+\sum_{j\in N,j\ne e}c_jx_j+c_ex_e=v+c_e\hat{b}_e+\sum_{j\in \hat{N}}(c_j-c_e\hat{A}_{e,j})x_j\),对应到新的\(\hat{v}\)和\(\hat{c}_j\)。
单纯形算法(simplex)
1.先写成松弛型并找到一个初始基本解(即非基本变量取值为0构成合法解)。
2.每次选择\(e\)和\(l\)进行转动,需要保证所有\(\hat{b}_i\ge 0\),即\(b_i-a_{i,e}\hat{b}_e\ge 0\)。因此需要满足当\(a_{i,e}>0\)时\(\hat{b}_e\le \frac{b_i}{a_{i,e}}\),\(a_{i,e}\le 0\)时无限制。另外如果对\(e\)和\(l\)进行转动,\(\hat{b}_e=\frac{b_l}{a_{l,e}}\),因此只能选择\(\frac{b_i}{a_{i,e}}\)的最小值对应的\(i\)作为\(l\)进行转动。目标值\(v\)的增量为\(c_e\hat{b}_e\),应当选取任一个\(c_e>0\),再根据上述最小值找到\(l\)即可。如果所有的\(a_{i,e}\)均小于0,则\(x_e\)可取正无穷,线性规划问题无界(unbounded)。
3.当所有非基本变量\(i\in N\)有\(c_i\le 0\)时,达到最大值,令所有\(i\in B\),\(x_i=b_i\)作为原松弛型的最优解。
根据算法过程可知最终的解一定合法,还需要说明:1.单纯形算法一定能终止 2.单纯形算法得到的一定是最优解 3.如何找到初始基本解
终止性
可能会出现\(b_l=0\),即\(v\)不增加的情况,称为退化,有如下引理:
bland规则 如果每次选取符合条件的下标最小的\(x_e\)和\(x_l\),算法一定终止。
还有如下引理便于之后的证明:
如果\(a^{T}x=\gamma\)对任意实数向量\(x\)都成立,那么\(a\)是零向量,\(\gamma=0\)。
直接构造证明。
那么我们可以证明,对于每对\(B\)和\(N\),松弛形式唯一。否则设存在两组\((a,b,c,v)\),基本变量的等式相减得到\(0=(b_i-b_i')-\sum_{j\in N}(a_{i,j}-a_{i,j}')x_j\),利用引理可知两组\(a\)相同,两组\(b\)相同。再根据任何满足条件\(x\)都可得到目标值相同,构造证明两组\(v\)和两组\(c\)相同。
那么\(B\)和\(N\)只有至多\(C(n+m,n)\)种可能,如果一对\(B\)和\(N\)被第二次经过,由于松弛形式唯一,会导致循环(可以认为\((B,N)\)构成了一张有向图,每个节点出边确定),再根据bland规则得到矛盾。因此运行次数不超过\(C(n+m,m)\)次。
线性规划对偶
原始线性规划:\(\max c^{T}x\),满足\(Ax\le b\)和\(x\ge 0\)。
对偶线性规划:\(\min b^{T}y\),满足\(A^{T}y\ge c\)和\(y\ge 0\)。
线性规划的弱对偶性 对原始线性规划的任一组解\(x\)和对偶线性规划的任一组解\(y\),有\(c^{T}x\le b^{T}y\)。
证明:\(\sum_{j}c_jx_j\le \sum_{j}(\sum_{i}a_{i,j}y_i)x_j=\sum_{i}(\sum_{j}a_{i,j}x_j)y_i\le \sum_{i}b_iy_i\)。
根据弱对偶性,如果原始线性规划的一组解与对偶线性规划的一组解相同,那么这两组解都是对应问题的最优解。
接下来构造一组对偶问题的解,并证明用simplex算法得到的答案与其相同,既证明算法的最优性,又证明线性规划的强对偶原理:原始线性规划和对偶线性规划如果都有解,则解相等。
最优性
设算法结束时的松弛型为\((a',b',c',v')\),基本变量和非基本变量集合分别为\(B\)和\(N\)。令对偶问题的解为\(y_i=-c'_{n+i}\)(\(n+i\notin N\)时为0)。则对于任意的向量\(x\),有
再利用引理,得到\(v'-\sum_{i=1}^{m}b_iy_i=0\)和\(c_j'+\sum_{i=1}^{m}a_{i,j}y_i=c_j\)。
还需证明\(y\)符合条件:算法结束时所有\(c_j\le 0\),\(\sum_{i=1}^{m}a_{i,j}y_i\ge c_j'+\sum_{i=1}^{m}a_{i,j}y_i=c_j\)。
因此simplex得到的答案和该对偶问题的解相等。
习题(farkas引理):设\(A\)是\(m\times n\)的矩阵,\(c\)是\(n\)维向量,系统\(Ax\le 0\)且\(c^{T}x>0\)和系统\(A^{T}y=c\)且\(y\ge 0\)中恰有一个系统可解。
初始基本解
在原线性规划问题中加入新变量\(x_0\),构造线性规划问题:最大化\(-x_0\),\(\sum_{j=1}^{n}a_{i,j}x_j-x_0\le b_i\)且\(x_j\ge 0\)(包括\(x_0\))。那么如果原问题有解,\(x_0=0\)时成立,目标值为0;如果原问题无解,\(x_0>0\),目标值为负,返回infeasible。
先将所有的\(b_i\)调整成非负:令\(e=0\)转动,注意到\(A_{i,e}=1\),\(\hat{b}_j=b_i-\hat{b}_e\),\(\hat{b}_e=b_l\)。只要找到\(b_k\)的最小值并令\(l=k\)进行转动即可。
此时所有\(\hat{b}_j\ge 0\),但目标函数可能为负,因此进行simplex算法的后两步即可。
最后将\(x_0\)恢复为非基本变量:如果\(x_0\)是基本变量,注意到此时目标值就是\(-x_0=-b_0\),因此\(b_0=0\),令\(l=0\)的转动都是退化转动,任取\(a_{0,e}\ne 0\)即可。
把所有等式中的\(x_0\)删掉,并换成原来的目标函数,从该松弛型开始,此时非基本变量全0是初始基本解,再进行simplex算法的后两步即可。
数论算法
贝祖定理 \(\gcd(a,b)\)是\(a\)和\(b\)的线性组合集中的最小元素。
证明:若\(s\)是集合中最小元素,则\(a\mod s\)和\(b\mod s\)也是集合中元素,因此\(s\)是\(a\)和\(b\)的约数,\(s\le \gcd(a,b)\);再由于集合中的元素都是\(gcd(a,b)\)的倍数得到\(s\ge \gcd(a,b)\)。
唯一分解定理 合数\(a\)只能以唯一的方式写成如下乘积形式:\(a=\prod_{i=1}^{k}p_i^{e_i}\),其中\(p_1<p_2<...<p_k\),\(e_i\)为正整数。
我认为直接通过对\(\sum e_i\)归纳即可。
欧几里得算法
\(\gcd(a,b)=\gcd(b,a\mod b)\)
引理:设斐波那契的第\(k\)项为\(F_k\),则如果欧几里得算法递归调用的次数不低于\(k\),则\(a\ge F_{k+2}\)且\(b\ge F_{k+1}\)。
证明:直接归纳,要求\(b\ge F_{k+1}\)和\(a\mod b\ge F_k\)。
扩展欧几里得算法:\(d=bx+(a\mod b)y=bx+(a-\lfloor a/b \rfloor b)y=ay+b(x-\lfloor a/b \rfloor y)\)
有限群
定义:封闭性,单位元,结合律,逆元
简化剩余系和乘法运算构成群:利用扩展欧几里得算法证明逆元存在。简化剩余系的大小记做\(\phi(n)\),用容斥原理可以得到其计算公式。有公式\(\phi(n)\ge \frac{n}{6 \ln \ln n}\)。
子群:由于群的大小有限,对任一个元素\(a\),\(a\circ a\circ a...\)会出现循环,即\(a^n=a^m\),再利用结合律得到单位元\(e=a^{m-n}\)在子集内,并且存在逆元\(a^{m-n-1}\)。因此子集只需要满足封闭性就构成群。
拉格朗日定理:子群集合的大小是群集合大小的约数。
生成子群:生成元\(a\)生成的子群\(\{a^k:k\ge 1\}\)。令元素的阶\(ord(a)\)为最小的\(k\ge 1\)使得\(a^k=e\),容易证明生成子群的大小等于生成元的阶。
推论:\(a^i=a^j\)当且仅当\(i\equiv j \mod ord(a)\)
推论:设\(a\)是有限群\(S\)中的元素,\(a^{|S|}=e\)
元素的幂
根据有限群的推论可以直接得到费马小定理和欧拉定理。费马小定理的常见证法是先证明质数的完全剩余系每个元素乘常数仍然构成完全剩余系,得到\((p-1)!\times a^{p-1}\equiv (p-1)! \mod p\);欧拉定理则是利用简化剩余系,得到\((\prod_{i=1}^{\phi(n)} a_i)\times a^{\phi(n)}\equiv \prod_{i=1}^{\phi(n)} a_i \mod n\)。
费马小定理推广可以得到\(a^p\equiv a \mod p\),可以处理\(a=0\)的情况;扩展欧拉定理即\(b>\phi(n)\)时\(a^{b}\equiv a^{b \mod \phi(n)+\phi(n)} \mod n\),可以处理\(a\)与\(n\)不互质的情况,证明先将\(n\)写成\(p^e\),如果\(p|a\),利用\(\phi(n)\ge \phi(p^e)\ge e\)得到\(p^e|a^{\phi(n)}\)。
RSA公钥加密系统
A和B手上都有公钥\(P\)和密钥\(S\),\(P\)和\(S\)是函数,满足互为反函数。每个人的公钥可以公开,密钥只有自己知道。该系统可以处理两种情形:
·A传递消息\(M\)给B。利用B的公钥\(P_B\)加密得到\(P_B(M)\),只有B能利用自己的幂钥\(S_B(P_B(M))\)还原\(M\)。
·A传递自己的数字签名\(M\)给B。同时传递\(M\)和\(S_A(M)\),任何人都可以通过\(P_A(S_A(M))=M\)证明这个签名来自A,但没有人能够伪造改签名。
一般的函数利用\(P(M)=M^e \mod n\)和\(S(M)=M^c\mod n\),\(n\)也同样公开。选取\(n\),\(e\),\(c\)构造公钥幂钥的方式如下:随机大质数\(p\)和\(q\),可通过随机结合miller-rabin算法完成,令\(n=pq\),\(\phi(n)=(p-1)(q-1)\),再选取与\(\phi(n)\)互质的小奇数\(e\),令\(d\)为\(\mod \phi(n)\)下\(e\)的乘法逆元
注意,因为\(ed\equiv 1\mod \phi(n)\)这一特殊条件,可以得到比扩展欧拉定理更强的结论:\(p\nmid M\)下\(M^{ed}\mod p=M^{k(p-1)(q-1)+1}\mod p=M(M^{p-1})^{k(q-1)})\mod p=M\mod p\),\(p|M\)下同样,因此\(M^{ed}\equiv M \mod n\)。
该加密系统的可靠性依赖于合数分解质因数的困难性,否则可以轻松得到\(p\)和\(q\)。直接进行模意义下开\(e\)次方根的问题似乎不弱于分解\(n\)。
还有一些提高效率的方法:
·提高传递信息的效率:A传消息给B时,选取短密钥\(K\)既是加密密钥也是解密密钥,使得得到\(K\)后可快速计算\(K(M)\)和\(K^{-1}(M)\),那么对\(K\)加密得到\(P_B(K)\),传送\(K(M)\)和\(P_B(K)\),B先通过\(S_B(P_B(K))=K\)得到短密钥后,再通过\(K^{-1}(K(M))=M\)得到消息。只要\(K(M)\)和\(P_B(K)\)都容易计算,则可以提高加密效率。
·提高数字签名的效率:公开抗冲突三裂函数\(h\),使得\(h(M)\)可以使得\(M\)的长度变短,但是很难找到\(M'\)使得\(h(M')=h(M)\),那么同时传递\(M\)和\(S_A(h(M))\),可通过\(h(M)=P_A(S_A(h(M)))\)验证,同时提高了加密和验证的速度。
·利用证书分配公钥:如果无法肯定A的公钥,那么第三方C可以使用自己生成的\(P_C\)和\(S_C\)来伪造\(A\)的签名,所以在签名时B需要能够确认A的公钥。可以利用T的公钥的权威性来验证A的公钥的准确性。每个人都知道权威T的公钥\(P_T\),A先从权威T处获得证书,证书内容包括“A的公钥为\(P_A\)”和该信息通过\(S_T\)的结果,那么每次A需要发送自己的数字签名时,只需要付上该证书,那么B只需要用\(P_T\)验证后即可得到\(P_A\),进而验证A的签名。
machine learning
supervised learning:不断给出输入和标准答案,需要不断修正,要求提高总的正确率
unsupervised learning:只给出输入,要求找到尽可能接近的答案
reinforcement learning:有对解优劣的实时反馈,需要不断调整解,要求找到尽可能优的答案
clustering(聚类算法)
\(\Delta(x,y)=\|x-y\|^2\),要将向量\(x_1,x_2,...,x_n\)分成\(k\)个集合\(S_1,S_2,...,S_k\),并为每个集合分配一个任意的中心\(c_i\),使得\(\sum_{i=1}^{k}\sum_{x\in S_i}\Delta(x,c_i)\)最小。
对每个维度求偏导可以得到\(c_i\)的每一维就是集合内这一维的平均值。
先随机选一些点作为\(c_i\),然后每轮先为每个点找到新的最近中心(如果所有点都已经最近则推出),再重新计算每个集合的中心。由于每次找新的最近中心后答案变小,且重算中心答案不变大,总共有\(k^n\)种分配方案,因此该算法一定会停止。
这样只能得到局部最优解,如果希望得到尽可能优的解,需要多次随机初始的中心。
这种算法用于unsupervised learning中的分类,实际应用中需要regularization,即给向量的每个维度进行“放缩”,例如全部变成\([0,1]\)中的实数。
图片压缩问题:每个像素点有红绿蓝三种颜色的系数,例如系数是\([0,2^8)\)内的整数,可以通过降低系数的大小,实现图片大小的降低。思路就是将一些不同但相近的颜色合并成同一颜色,这个过程中并不要考虑每个像素的位置,直接对所有像素的颜色向量运行clustering算法,将每个集合的颜色全变为中心即可。
multiplicative-weight
要做判断题,有\(n\)个专家,并不知道他们的水平,正确率甚至可能低于50%,每次做完一道题会直接得到答案,要根据这些专家的做题情况最大化正确率。另外,不同于boosting算法是通过弱分类器得到强分类器,它的背景是已经给出了全部问题,且分类器可以自己构造,这个问题是supervised learning,最优只能做到和正确率最高的专家达到相同的正确率,设\(m\)为错误的题数,\(m^*\)为专家错误题数的最小值,用\(m-m^*\)来衡量算法优劣。
引理1:已知某个专家正确率为100%,存在一个算法最多错\(\log n\)道题就可找到该专家。
证明:设集合\(S\)中的专家目前全对,每次直接在\(S\)中进行投票,那么如果答错,\(S\)的大小减少一半。
引理2:已知某个专家总的错误题数为\(m^*\),存在一个算法最多错\(m^*\log n\)道题。
证明:沿用刚才的算法,当\(S\)变为空集时,每个专家至少都答错了一题,而我们至多答错\(\log n\)题。将\(S\)变成全集重复进行该过程,由于至多进行\(m^*\)轮,因此至多答错\(m^*\log n\)题。
给每位专家赋权值\(w_i\),初始全为1,每次按照加权投票,即根据答T的权值之和以及答F的权值之和的大小关系来决定答案,令答错的专家的\(w_i\)乘上\(1-\gamma\)。下面证明该算法在任意时刻\(m\le 2(\gamma +1)m^*+2\ln n/\gamma\)。
设总权值为\(W\),答题正确的专家权值和为\(W_1\),错误的专家权值和为\(W_2\),则\(W'=W_1+(1-\gamma)W_2=W-\gamma W_2\le W-\gamma/2 W=(1-\gamma/2) W\)。因此\(W\le n(1-\gamma/2)^m\),又因为\(W\ge w_i=(1-\gamma)^{m^*}\),取对数可得\(\ln (1-\gamma)+\ln m^* \le m\ln (1-\gamma/2)+\ln n\),再利用\(\ln(1+x)\le x\)和\(x\le 1/2\)时\(-x-x^2\le ln(1-x)\),得到\(m_i(-\gamma -\gamma^2)\le m \gamma/2 +\ln n\),得到结论。
令\(\gamma=\sqrt{\ln n/m^*}\),可以得到\(m\le 2m^*+4\sqrt{m^*\ln n}\)。
gradient descent
对于\(f:R^n\to R\),要找到局部最小值(类似clustering,如果要找全局最优解需要多次随机)。迭代\(T\)次,每次令\(x^{(t+1)}=x^{(t)}-\gamma (\nabla f)(x^{(t)})\),令最终解为\(x^{t}\)的平均值。以下是在\(f\)为凸函数时对算法的分析。
凸函数的定义:任意\(0\le \lambda\le 1\),有\(f(\lambda x+(1-\lambda) y)\le \lambda f(x)+(1-\lambda) f(y)\)。有如下性质:
·凸函数局部最小值就是全局最小值,否则不妨设\(f(y)\le f(x)\),利用定义可知\(f(\lambda x+(1-\lambda) y)\le f(x)\)。
·由于凸函数任意点的切面在原图形的下方,有\(f(x)\le f(y)+\langle (\nabla f)(x),x-y \rangle\)。
·反复利用第一条可以得到\(f(1/T\sum_{i=1}^{T}x^{(i)})\le 1/T\sum_{i=1}^{T}f(x^{(i)})\)
一元凸函数定义为二阶导为正,那么高维的凸函数就定义为二阶梯度算子得到的矩阵是半正定矩阵。
设最优解为\(x^*\),\(R=\|x^{(0)}-x^*\|\),\(L=\max\{ (\nabla f)(x^{(i)} \}\),最终结果为\(x^a\),\(\epsilon=f(x^a)-f(x^*)\),迭代次数为\(T\),要证明\(\epsilon\le RL/\sqrt{T}\)。
利用类似势能分析的思想,若\(f(x^{(t)})-f(x^*)\le B-\phi(t+1)+\phi(t)\),则\(f(x^a)-f(x^*)\le B+\phi(0)/T\),令\(phi(t)=\|x^{(t)}-x^*\|^2/2\gamma\),利用\(\|a+b\|^2-\|a\|^2=\|b\|^2+2\langle a,b \rangle\)和凸函数的性质,有\(\phi(t+1)-\phi(t)=1/2\gamma(\|x^{(t+1)}-x^{(t)}\|^2+2\langle x^{(t)}-x^*,x^{(t+1)}-x^{(t)}\rangle)=\gamma/2\|(\nabla f)(x^{(t)}\|^2+\langle x^{(t)}-x^*,-(\nabla f)(x^{(t)}\le \gamma/2\|(\nabla f)(x^{(t)}\|^2-(f(x^{(t)}-f(x^*)\),于是有\(B\ge \gamma/2(\nabla f)(x^{(t)}\),\(B\)最小值为\(L^2\gamma/2\)。进而\(\epsilon\le L^2\gamma/2+R^2/2\gamma T\),找合适的\(\gamma\)得到结论。
实际应用中需要找到比较准确的\(L\)和\(R\)的估计来取\(\gamma\),也可每次通过先倍增再二分找点(?)。
对于\(f\)的定义域限定在一个凸集合中的情况,只需要将每次迭代得到的结果修正为凸集合中与其最近的点,到最优解的距离不变大,上述证明仍然成立。
gradient descent可以用于求解线性代数问题的非精确解,例如解\(Ax=b\),可以转化为求\(f(x)=1/2x^TAx-b^Tx\)的最小值,\(f\)是凸函数。
近似算法
不妨设所求问题是最小化问题,设算法的近似解为\(C\),最优解为\(C^*\)。\(\frac{C}{C^*}\le \rho(n)\)则称该算法为\(\rho(n)\)近似算法,\(\rho(n)\)为近似比。
\(\rho(n)\)可能是常数,也可能是输入规模\(n\)的函数。
对于随机化近似算法,如果\(\frac{E(C)}{C^*}\le \rho(n)\),称该算法为随机化的\(\rho(n)\)近似算法,例如最优化3-SAT问题(每个表达式都是三个变量或变量的补的并,要赋值使得为真的表达式尽量多),直接随机每个变量的取值,则正确率为\(7/8\),期望下为\(8/7\)近似算法。
如果输入包含问题实例和\(\varepsilon\),且对任意\(\varepsilon>0\)都有该算法是\((1+\varepsilon)\)近似算法,则称该算法为近似模式。如果一个近似模式的运行时间对任意固定的\(\varepsilon>0\)都是关于实例规模\(n\)的多项式,则称为多项式时间近似模式,如\(O(N^{1/\varepsilon})\)。如果运行时间既为\(1/\varepsilon\)的多项式,又为\(n\)的多项式,则称为完全多项式时间近似模式,如\(O((1/\varepsilon)^2n)\)。
一般图最小点覆盖
每次选择一条没覆盖的边,将两个端点均选入覆盖集。
实际上就是选出了一个极大匹配,对于任意图上的匹配,设匹配数为\(A\),都有\(C^*=2A\)和\(C>A\),该算法是多项式时间的2近似算法。
旅行商问题
如果旅行商问题满足三角不等式\(c(u,v)\le c(u,w)+c(w,v)\),那么直接取图中的MST,从起点开始按照dfs序遍历,利用三角形不等式,总代价不高于边权之和的两倍。那么对于任意其他解,删去任何一条边后构成生成树,该生成树代价不低于最小生成树。\(C\le 2C^*\),是多项式时间的2近似算法。
如果旅行商问题不满足三角形不等式,可以证明如果\(P\ne NP\),不存在近似比为\(\rho\)的多项式时间近似算法:如果存在该算法,可以将任何一张无向图的边权设为1,不存在的边连上并设边权为\(\rho |V|+1\),则任何一条包含原图中不存在的边的回路代价至少为\((\rho |V|+1)+(|V|-1)=(\rho +1)|V|\),可用该算法在多项式时间内解决哈密顿回路问题。
集合覆盖问题
问题描述:给定集合\(X\)和\(X\)的子集族\(F\)选取最少的集合\(S\in F\),使得这些集合的并是全集。
每次选一个集合使得已选集合的并集大小最大,是关于输入的线性算法,可以证明该算法是\(H(\max\{|S|:S\in F\})\)近似算法,其中\(H(n)\)是\(n\)阶调和级数。
证明:思路是将代价摊到每个元素上,利用任一组解必须要覆盖所有元素放缩。设第\(i\)个选出的集合为\(S_i\),对所有\(x\in S_i\setminus \bigcup_{j<i}S_j\),令\(c_x=\frac{1}{|S_i\setminus \bigcup_{j<i}S_j|}\),则\(C=\sum_{x\in X} c_x\le \sum_{S^*} \sum_{i\in S^*} c_i\),其中\(S^*\)是最优解中的集合。只要能证明\(\sum_{i\in S^*} c_i\le H(|S^*|)\),则\(C\le C^*H(\max |S^*|)\)。
对与任何\(S\in F\),要证\(\sum_{x\in S}c_x\le H(|S|)\):令\(u_i\)表示前\(i\)个集合未覆盖的\(S\)中元素个数,即\(u_i=|S-\bigcup_{j<i}S_j|\),利用贪心的策略,有\(|S_i-\bigcup_{j<i}S_j|\ge |S-\bigcup_{j<i}S_j|=u_{i-1}\),\(\sum_{x\in S}c_x=\sum_{i}(u_{i-1}-u_i)\frac{1}{|S_i-\bigcup_{j<i}S_j|}\le \sum_{i}(u_{i-1}-u_i)\frac{1}{u_{i-1}}=\sum_{i}\sum_{j=u_i+1}^{u_{i-1}}\frac{1}{u_{i-1}}\le \sum_{i}\sum_{j=u_i+1}^{u_{i-1}}\frac{1}{j}=H(|S|)\)。
线性规划
对于带权最小点覆盖问题,写成线性规划的形式:\(z=minmize \sum w(v)x(v)\),要求对\((u,v)\in E\)满足\(x(u)+x(v)\ge 1\)。如果不考虑\(x(i)\in \{0,1\}\)的限制,直接求解,则由于\(x(u)+x(v)\ge 1\),\(x(u)\)与\(x(v)\)中至少有一个不低于\(1/2\),因此将\(x(u)\ge 1/2\)的点\(u\)选入覆盖集,则\(z\le C^*\)且\(C\le 2z\)。
子集和问题
“装箱问题”:给定\(n\)个数\(x_i\)和\(t\),要求选出一个集合,使得子集和不超过\(t\)且子集和尽量大。注意背包问题的输入量是关于\(\log t\)的多项式,\(O(nt)\)的背包算法是非多项式算法。
背包的新的表述:依次求\(S_i\),表示前\(i\)个元素能得到的子集和构成的集合,则\(S_i=S_{i-1}\cup (S_{i-1}+x_i)\)。为了使集合的大小是\(\log t\)的多项式,可以设\(1+\delta\),从最小元素开始,每次只保留已有最大元素的\(1+\delta\)倍以上的元素,则集合大小就是\(log_{1+\delta}t\)。则对于任何原本\(S_i\)中的元素\(z\),必有目前集合中的元素\(y\),满足\(y\le z/\delta^i\),归纳证明,加入新的\(x_i\)时原有的\(y\)保留或存在元素\(y/(1+\delta)\)(\(z\)变为\(z+x_i\)的情况同理)。那么令\(\delta=\varepsilon/2n\),有\(C\ge \frac{C^*}{(1+\varepsilon/2n)^n}\),先求导证明\(n\)增加时\(C/C^*\)减小,再令\(1/n'=\varepsilon/2n\)即可证明\(n\)趋于无穷时\(C/C^*\ge e^{\varepsilon/2}\ge 1+\varepsilon\)。算法复杂度\(T(n)=n\log_{1+\varepsilon/2n}t=n\frac{\ln(t)}{\ln(1+\varepsilon/2n)}\),利用\(\ln(x)\ge \frac{x-1}{x}\),有\(T(n)\le n\frac{(1+\varepsilon/2n)\ln t}{\varepsilon/2n}=\Theta(n^2\log t/\varepsilon)\),是完全多项式时间的近似模式。