联考集团讲课笔记
为什么博主不先更 CTT 游记呢?因为不把讲课内容记下来,过几天就白学了!!!
12.12 zzy 讲课
克莱姆法则
可以逆用,来求解把矩阵一列换成一个固定向量的行列式这样的问题。
但是矩阵不可逆的时候感觉根本没用。不如正确的求解代数余子式的方法配合 Laplace 展开。
矩阵非常特殊的时候可能是有用的,但是感觉也没什么用。
图特矩阵和一般图匹配
首先是广为人知的 Schwartz-Zippel 引理:
对于一个非零 \(n\) 元 \(d\) 次多项式 \(P\),设均匀随机变量 \(X_1,X_2\ldots X_n\in\mathbb F\),那么 \(Pr(P(X_1,X_2,\ldots,X_n)=0)\le \dfrac{d}{|\mathbb F|}\)。
图特矩阵判断一般图是否有完美匹配,正需要判断一个(非常多元而且难求,但是容易求点值)多项式是否恒为 0,因此和这个引理非常搭。
而构造方案基于一个定理:
这说明,如果知道了图特矩阵的逆矩阵,我们可以快速看出哪条边可以在完美匹配中,于是我们随便选一条边加入方案中,并将这两个点删去即可。
对应在图特矩阵上,相当于删去了两行两列。现在的问题就变成了如何维护逆矩阵。根据逆矩阵和伴随矩阵的关系,我们发现删去 \(i\) 行 \(j\) 列后行列式非 0,也就是仍然可逆。而再删去 \(j\) 行 \(i\) 列后,剩下的图就是一个新的、有完美匹配的图特矩阵了,自然是可逆的。
于是现在的问题变成了,如何删去一行一列,同时维护逆矩阵。通过交换行列,我们可以只研究删掉首行首列的问题。又有一个定理:
好像和什么“舒尔补”之类的理论有关,我不懂。但是它明显能解决目前的问题。于是每次删一行一列复杂度 \(O(n^2)\),总复杂度 \(O(n^3)\)。
至于把最大匹配转化成完美匹配,只要保留图特矩阵的基中的向量对应的点即可。
单纯形
只介绍标准型,即
基本合法解的形式
我们希望矩阵限制能改写成如下若干等式的形式:
我们称处于等式左边的为基本变量,右边的为非基本变量,这些等式相当于说把基本变量全部表示成非基本变量的线性组合加上一个非负数。注意一个变量不一定一直是基本的,或是非基本的,它的状态在之后的过程中可能会像 LCT 中的虚实边一样切换。
如何将初始的标准型转化成这种形式?先考虑 \(b\ge 0\) 时。那么只要在标准型中加入松弛变量,就可以写成这种形式。至于 \(b\not\ge 0\) 的情况,我们最后讨论。
我们再定义 pivot 操作,它用于把一个基本变量和一个非基本变量的地位交换,假设它们分别叫 \(X,Y\),而同时包含它们的等式形如 \(X=q-\sum_j B_jx_j-BY\)。
那其实很简单,就变成 \(Y=\dfrac{1}{B}(q-\sum_j B_jx_j-X)\) 即可,但是我们要把其他等式中的 \(Y\) 替换掉,以保证每条等式的右边只有非基本变量。
同时我们也注意保持代价函数 \(z\) 也总由非基本变量线性组合加上一个常数 \(z_0\) 而成。
花大力气保持这样一个形式,是为了考虑一种简单的情况:非基本变量全部取 0,此时代价函数即为 \(z_0\),同时基本变量恰好取 \(q_i\),都是非负的,不违反限制。我们称这个解为基本合法解。
pivot 的作用及变量的选择
我们通过交换非基本变量和基本变量(即进行 pivot 操作),可以改变 \(z_0\),从而使代价函数发生改变,而同时满足限制。
但是我们如何选择 pivot 的两个变量呢?这是不能随便选的,不然要是 pivot 之后使得某个 \(q_i<0\) 就把基本合法解的形式破坏了。
我们考虑某对基本/非基本变量 \(X,Y\),它们共同在的方程对 \(Y\) 的取值提出了一定的限制。具体的,\(X=q-\sum_j B_jx_j - BY\) 的话,如果提到的数都是非负的,那么就会有限制 \(Y\le q/B\)。但是,如果 \(B_j\) 或者 \(B\) 的非负条件不满足,也有可能出现 \(Y\) 可以发散到无穷大的情况。
那么对于某个非基本变量 \(Y\),每条方程(或者说每个基本变量)相当于给它提出了一个限制。可以发现,pivot 如果选择了 \(Y\) 作为非基本变量,那么选择的基本变量必须是对 \(Y\) 产生了最紧的限制的基本变量,否则就会出现 \(q_i<0\) 的情况。于是,如果我们已经确定了 pivot 的非基本变量,则可以确定出选择哪个基本变量。
那么如何选择非基本变量呢?目前 \(z\) 由非基本变量线性组合加上常数 \(z_0\) 构成,我们选择系数最大的那个非基本变量。
为什么呢?可以发现,对 \(X,Y\) pivot 后,对于基本合法解的修改情况是:
- 原基本变量 \(X\) 取值现在是 0。
- 其他基本变量的值可能改变。
- 原非基本变量 \(Y\) 的取值现在会变成一个新的非负数,即最紧限制。
- 其他非基本变量的值仍然为 0。
由于目前的代价函数只与 \(Y\) 和其他非基本变量有关,所以上述 4 条中唯一会改变 \(z\) 的值的,就是 3。而 \(Y\) 的变大导致 \(z\) 的变大,这一增长的速度,和 \(z\) 的线性组合表示中 \(Y\) 的系数有关。这是一种贪心的想法。
值得注意的是,pivot 后代价函数的取值是新的 \(z_0\),这不仅由 \(Y\) 前系数决定,还由 \(Y\) 能增大多少来决定。因此,我们选择的 \(Y\) 并不一定是使得 \(\Delta z_0\) 最大的,因此我们的贪心与直接的贪心还是有些区别的。
什么时候停止呢?如果无法选择出一对可以 pivot 的变量,或是选择出的非基本变量前的系数为负,则已经求出最优解,可以停止。否则,如果选出的非基本变量可以无限制增长,而前面的系数为正,说明答案是发散至正无穷。
感性理解
将向量 \(x\) 看成 \(n\) 维空间中的点。标准型中的限制相当于是若干个半空间取交,这会形成一个凸集,容易说明一定存在一个最优解在凸集的顶点上。
而凸集的顶点,是若干半空间边界的唯一交点。在一个 \(n\) 维空间上,至少要有 \(n\) 个半空间边界,才会交出这样一个唯一交点——这相当于说有至少要有 \(n\) 个方程才能唯一解出 \(n\) 个未知数。
如果一开始的标准型有 \(n\) 个变量,\(m\) 个限制,那么加入松弛变量后有 \(n+m\) 个变量,\(m\) 个等式限制,和 \(n+m\) 个非负限制。而凸集顶点必须抵到至少 \(n+m\) 个限制,也就是说,就算这个顶点抵到了所有等式限制,它也需要至少抵到 \(n\) 个非负限制才行。于是,所有变量中,至少有 \(n\) 个是 0!
于是我们不难理解为什么单纯性算法过程中求出的解总会使 \(n\) 个非基本变量为 0,但是仍能求出最优解。因为总会有一个最优解使得至少 \(n\) 个变量为 0。非常神奇!
同时我们可以发现,所谓 pivot 操作,在几何意义上,就是让解代表的多面体顶点,移动到相邻的一个多面体顶点。于是,整个单纯形算法,可以看成在 \(n+m\) 维空间的某个多面体的顶点上按一定规则不断游走的过程。
遗留问题
遗留的一个问题是,如果初始标准型中 \(b\not\ge 0\),怎么转化成基本可行解的形式?
\(b\ge 0\) 时有平凡解 \(x=0\),不会无解。但此时线性规划可能是无解的。
我们需要解一个辅助线性规划:
即让所有的不等式都放松 \(x_0\) 那么多。构造的代价函数会使得放松的幅度最小。这样之后线性规划显然就有解了。
然后在这个线性规划下,我们仍然直接加入松弛变量转化成“基本可行解”的形式,但此时存在 \(q_i<0\)。此时我们可以选择最小的 \(q_i\)(负得最多的那个)对应的基本变量 \(X\),对 \(X,x_0\) 进行一次 pivot 操作后,新的 \(q_i\) 就都非负了。
然后我们接着用单纯形解完这个线性规划。如果解出来 \(x_0>0\),那说明必须放松,原线性规划才会有解,也就是原线性规划事实上无解。
否则说明 \(x_0=0\),也就是它可以作为一个非基本变量,即使它目前是一个基本变量,我们可以随便把它和某个非基本变量 pivot,就把它变成一个非基本变量了,且因为 \(x_0=0\),这个 pivot 不会不能进行。
于是此时 \(x_0\) 已经是一个非基本变量,我们直接将其从所有式子中删去,就得到了原线性规划的一个“基本可行解”形式,就可以接着跑单纯形了!
线性规划对偶
首先介绍拉格朗日对偶的思想。和拉格朗日乘子法类似:
注意这里的 \(x,f(x),g(x),\lambda\) 既可以是数,也可以是向量。
如果 \(g(x)<0\),那么内层 \(\max\) 中 \(-\lambda g(x)\) 可以趋于正无穷,就对取 \(\min\) 没贡献了。
而拉格朗日对偶说明:(中间的不等号可能是大于等于,没有仔细研究)
很有意思吧!而且如果 \(f(x)\) 和 \(g(x)\) 均为关于向量 \(x\) 的线性函数,则这个问题即为线性规划问题,由强对偶定理可以说明,等号可以取到。
于是可以用这个来推导一些非标准型的线性规划对偶而无需增加辅助变量,比如说:
即标准型去掉 \(x\ge 0\) 的限制。写成拉格朗日对偶的形式:
由于 \(x\) 任取,只有 \(c^T-\lambda^TA=0\) 时内层才不会发散至负无穷。于是相当于
比增加辅助变量的方法简洁很多,相信在各种题目里也会好用。
12.13 hhz 讲课
区域赛题。
12.14 wys 讲课
今日收获:splay、LCT、Top Tree、全局平衡二叉树、二叉点分治,复杂度分析都是使用了 \(\log n-\log s\) 的方法!
加深了对 zzy 论文的理解!
知道了这里描述的 Top Tree 就是用 Splay 维护 LCT 的虚儿子而已,easy!(狗头)
没有实现,也懒得实现,有空再说,至少等我能使用我的新键盘