线性规划对偶

发布时间 2024-01-02 16:37:31作者: Cry_For_theMoon

我草,终于开始学线性规划对偶了。

抄袭一下 dxm 论文。

定义

首先线性规划是这样一个东西:

\[\max : c^{T}x \\ s.t. \\ Ax\le b \\ x\ge 0 \]

\(x\)\(1\times n\) 向量,\(A\)\(m\times n\) 矩阵。则上述形式对应了一个,\(n\) 个变量 \(m\) 条约束的线性规划问题。

\(x_i\) 可以是实数,但一定非负。

第一行被称作目标函数,也就是我们要最优化的内容。下面的都是我们的约束。

对偶

我们可以转而去做这样一个问题:

\[\min: b^Ty \\ s.t. \\ A^Ty\ge c \\ y\ge 0 \]

下面这个式子的答案和上面的是一致的。

这个结果其实有很多东西值得我们理清一下:

  • 首先我们注意到原问题是可能无解的:而线性规划对偶只在有解的条件下成立。换言之对偶,对判断有无解是没有帮助的,我们往往需要先确认原问题有无解。
  • 注意到 \(y\)\(1\times m\) 矩阵。实质上:对偶就是对原问题的每个约束,新建了一个关于它变量(不妨乘坐该限制的对偶变量)。
  • 我们很容易写出对偶后的目标函数,但是约束不容易比较快速的写出。按照我的理解:对偶后的问题,每个约束都和原问题中的一个变量 \(x_i\) 相关。不等式右侧很好写,左侧实际上是就是,你考虑原问题的每个约束 \(j\),如果在这个约束的左侧,\(x_i\) 的系数是 \(p_j\)。那么在对偶后的问题里,\(y_j\)(也就是这个约束的对偶变量)的系数就也是 \(p_j\)。这样就能比较快速地写出对偶后的约束。

等于的情况

常有 \(Ax=b\) 这样的约束,我们当然可以拆成 \(Ax\ge b\)\(Ax\le b\) 来研究,但是还有更简洁的方法。

不妨说,有两个变量 \(x_1,x_2\),然后我们要求最大化 \(x_1+x_2\),限制是 \(x_1+x_2= c\)。拆成 \(x_1+x_2\le c\)\(-x_1-x_2\le -c\)

对偶以后:也就是最小化 \(y_1-y_2\),然后两条限制长得一摸一样:怎么都是 \(y_1-y_2\ge 1\)

\(Y:=y_1-y_2\) 然后你发现就是最小化 \(Y\),约束 \(Y\ge 1\)。而且你发现本来 \(y_1,y_2\) 都要求 \(\ge 0\),但 \(y_1-y_2\) 就无所谓了。

因此碰到等于的约束,我们依旧可以只得出一个对偶变量,并且它自身并不带非负的要求,可以任意取值(当然可能会被其他限制约束到)。

费用流对偶

考虑下列网络流问题:

无源汇最小费用流,可能有负权边。对每个点 \(u\),要求:它流出的流量减去流入的流量恰好为 \(b_u\)

首先这个问题怎么费用流解决?我们先把负权边流满建反边,然后跑上下界的做法。如果能说明没有负环,则不用流满负权边,直接跑上下界也可以。我们先假设这个问题是一定有解的。

然后写出线性规划形式:

\[\min: \sum_{u,v}w_{u,v}f_{u,v} \\ s.t.\\ -f_{u,v}\ge -c_{u,v} \\ \sum_{v}f_{u,v}-\sum_{v}f_{v,u}=b_u\\ f \ge 0 \]

\(z_{u,v}\)\(-f_{u,v}\ge -c_{u,v}\) 的对偶变量,\(p_u\)\(\sum_{v}f_{u,v}-\sum_{v}f_{v,u}=b_u\) 的对偶变量。对偶后得:

\[\max:\sum_{u,v}-c_{u,v}z_{u,v}+\sum_{u}b_up_u\\ s.t.\\ -z_{u,v}+p_{u}-p_v\le w_{u,v} \\ z,p\ge 0 \]

这里有一个很重要的技巧:消去多余变量。就是说,假如我们确定了所有的 \(p\),则因为 \(c\) 是非负的,那么 \(z\) 一定越小越好。而注意到:\(z_{u,v}\ge p_u-p_v-w_{u,v}\)。因此我们可以直接取等号(和 \(0\) 取最大值),然后:

\[\max:\sum_{u}b_up_u-\sum_{u,v}c_{u,v}\max\{0,p_u-p_v-w_{u,v}\} \\ s.t.\\ p\ge 0 \]

至此,我们其实已经得到了一种机械求解这种最优化问题的方法。当然你需要确保得到的费用流问题一定有解。

例:ZJOI2013 战线规划

\(s_i\)\(1\sim i\) 里放置了多少个。约束可以写成 \(s_{r}-s_{l-1}\ge d\) 的形式。

还有 \(s_i\ge s_{i-1}\),发现也可以写成上面的约束。

代价定义为 \(\sum_{i=1}^{n}b_i(s_{i}-s_{i-1})\),重写一下也就是 \(\sum_{i=0}^{n}(b_i-b_{i+1})s_i\),因此可以重定义一下 \(b_i\),然后变成 \(\sum_{i=0}^{n}b_is_i\)

注意到我们并不需要令 \(s_0=0\),反正你的代价是以相邻的 \(s\) 的差的形式定义的。事实上我们想让 \(s_0=0\) 也比较困难。

怎么套用到上面的形式呢?我们只用给约束加一个 \(\infty\) 的权:也就是:

\[\min: \sum_{i=0}^{n}b_is_i+\sum_{u,v}\infty\max\{0,s_{l-1}-s_{r}+d\} \]

你发现这个式子取反就是上面的形式,直接对着建图跑费用流就行了。

不过这个题比较不牛,费用流板子比较菜会被卡,打不过单纯形。。

例:Aizu2230 How to Create a Good Game

\(x_{u,v}\) 是边 \(u\rightarrow v\) 增加的量,而 \(w_{u,v}\) 是原始边权。

再令 \(f_i\) 是新图 \(1\rightarrow i\) 的最长路。原图里 \(1\rightarrow n\) 的最短路为 \(C\)

则我们写出线性规划形式:

\[\max : \sum_{u,v}x_{u,v} \\ s.t. \\ f_{n}-f_{1}\le C \\ f_{v}-f_{u}\ge w_{u,v}+x_{u,v} \\ f,x\ge 0 \]

依旧是考虑消去无用变量:假如我们确定了 \(f\),则 \(x_{u,v}\le f_{v}-f_{u}-w_{u,v}\) 会直接去等号,而且这里不能和 \(0\)\(\max\),否则意味着此时 \(f_{v}-f_{u}\lt w_{u,v}+(x_{u,v}=0)\)。所以应该把约束改写成 \(f_{v}-f_{u}\ge w_{u,v}\)

整理一下:

\[\max : (\sum_{u,v}f_v-f_u-w_{u,v})-(\sum_{u,v}\infty\max\{0,f_u-f_v+w_{u,v}\})-\infty\max\{0,f_n-f_1-C\} \]

直接建图跑费用流即可,这次随便过了。

另外的一些例题

不能总机械套这个模型吧?

ZJOI2020 序列

虽然有三种操作,但其实从每个位置的视角来看,只有两种操作:一种是 \([l,r]\) 内的全部加,一种是 \([l,r]\) 内指定奇偶性的人加。

首先如果我们只有一操作,那么是 NOIP2018 T1 啊啊:答案直接就是 \(\sum_{i=1}^{n}\max\{0,a_{i}-a_{i-1}\}\)

然后我们令 \(f_i\) 是位置 \(i\) 有多少次一操作,\(g_i\) 是位置 \(i\) 有多少次二操作,则有:

\[\min : \sum_{i=1}^{n}\max\{0,f_i-f_{i-1}\}+\max\{0,g_{i}-g_{i-2}\}\\ s.t.\\ f_i+g_i=a_i\\ f,g\ge 0 \]

(以下我们都认为下标在 \([1,n]\) 范围外,就代表 \(0\)。)

注意到 \(g_i=a_i-f_i\),因此可以消去。得:

\[\min : \sum_{i=1}^{n}\max\{f_i-f_{i-1}\}+\max\{0,a_i-f_{i}-a_{i-2}+f_{i-2}\}\\ s.t.\\ -f_i\ge -a_i\\ f\ge 0 \]

到这里我们还无法直接对偶:因为目标函数里有和 \(0\)\(\max\)

接下来的手法很有启发性:当我们的目标函数里出现了 \(\max\{0,x\}\) 这种东西的时候,我们不妨新建一个变量 \(y \ge x\),然后因为线性规划自带的 \(y\ge 0\) 的限制,\(\min: y\) 就等价于 \(\min:\max\{0,x\}\)。我们对目标函数里的两个 \(\max\),新建变量 \(y_i,z_i\),则:

\[\min:\sum_{i=1}^{n}(y_i+z_i)\\ s.t.\\ y_i\ge f_i-f_{i-1} \Leftrightarrow y_i-f_{i}+f_{i-1}\ge0 \\ z_i\ge a_{i}-f_{i}-a_{i-2}+f_{i-2} \Leftrightarrow z_i+f_{i}-f_{i-2}\ge a_{i}-a_{i-2}\\ -f_i\ge -a_i \\ f,y,z\ge 0 \]

此时可以直接对偶了,对三条限制分别新建对偶变量 \(X,Y,Z\)

\[\max:\sum_{i=1}^{n}(a_i-a_{i-2})Y_i-Z_i \\ s.t. \\ X_i\le 1 \\ Y_i\le 1\\ -X_i+X_{i+1}+Y_i-Y_{i-2}-Z_{i} \le 0 \\ X,Y,Z\ge 0 \]

注意到确定 \(X,Y\) 以后,有 \(Z_i\ge -X_{i}+X_{i+1}+Y_{i}-Y_{i-2}\)。因此 \(Z_i=\max\{0,-X_i+X_{i+1}+Y_i-Y_{i-2}\}\)

因为这个问题能建出费用流模型,所以可以保证解的整数性,因此 \(X,Y\) 的取值都是 \(0/1\)

这样:最大化 \(\sum_{i=1}^{n}(a_i-a_{i-2})Y_i-\max\{0,-X_{i}+X_{i+1}+Y_{i}-Y_{i-2}\}\) 就可以直接 dp 了。

时间复杂度 \(O(n)\)

World Tour Finals 2022 Day1 D. Welcome to Tokyo!

线性规划对偶的好题。但是整数型相关的内容有点无法感受明白啊?

我们直接令 \(a_i\)\(i\) 是否选择 \(0/1\)。然后:

\[\max : \sum_{i=1}^{m}\min\{1,\sum_{j=l_i}^{r_j}a_j\}\\ s.t.\\ a_i\le 1\\ \sum_{i=1}^{n}a_i\le k \]

整数规划难以处理,但是我们可以猜测其一定有最优整数解,所以可以直接看作一般的线性规划。

在对偶之间,注意到目标函数有 \(\min\{1,x\}\) 这种形式,运用上面所述的技巧:

\[\max:\sum_{i=1}^{m}b_i\\ s.t.\\ a_i\le 1\\ b_i\le 1\\ b_i-\sum_{j=l_i}^{r_i}a_j\le 0\\ \sum_{i=1}^{n}a_i\le k \]

对偶:令四条限制的对偶变量分别为 \(X_i,Y_i,Z_i,C\),得:

\[\min:\sum_{i=1}^{n}X_i+\sum_{i=1}^{m}Y_i+kC\\ s.t.\\ X_i-\sum_{i\in [l_j,r_j]}Z_j+C\ge 0\\ Y_i+Z_i\ge 1 \]

四个变量实在是太难以处理:考虑对于每个 \(C\),提前算出目标函数减去 \(kC\) 的最优解 \(b_C\)。这样对于每个 \(k\),我们就相当于是查询 \(\min kC+bC\),容易求出。然后我们考虑 \(C\) 固定的情况。

根据解的整数性以及我们的最优化方向:\(Y_i+Z_i\ge 1\) 可以拆成:\(Y_i\oplus Z_i=1\)

因此 \(Z_i=1-Y_i\)。所以第一条限制变为:\(X_i-m+\sum_{i\in [l_j,r_j]}Y_j+C\ge 0\)

这里需要观察到一个贪心性质:最优解一定满足 \(X=0\):否则我们选出其中的 \(X\)\(Y=0\) 的位置,将他们变成 \(1\),目标函数显然不会更大。

那么我们的目标函数变成了 \(\min:\sum_{i=1}^{m}Y_i+kC\),而第一条约束变为了 \(\forall i,m-\sum_{i\in[l_j,r_j]}Y_j\le C\)

如果一个区间的 \(Y_i=0\),则我们称这个区间被选中。则我们就是在做这样一个问题:

  • 选出尽可能多的区间,使得每个点被覆盖的次数不超过 \(C\)

那么我们瞬间有很多想法,比如凸性什么的。我们来考虑对于一个固定的 \(C\),建出网络流模型:

那就是有一条拆点的单向链,限制了每个点被经过了不超过 \(C\) 次,然后我们对于一个区间,连 \(s\rightarrow in(L)\)\(out(R)\rightarrow t\)。跑最大流就是答案。

首先 \(C=1\) 是经典弱智贪心:按照右端点排序考虑每个区间是否能加入即可。

考虑 \(C\rightarrow C+1\) 的时候发生的变换。实际上也就是对每个点的 \(in\rightarrow out\) 之间多新连一条边出来。

那你观察这个新增的连边,就很显然不会出现新的增广路是经过反悔边的。因此我们可以从这个角度来发现答案具有增量性。

也就是我们求出 \(C\) 的时候选中了哪些区间。然后 \(C\rightarrow C+1\) 的时候对剩下的区间继续套那个 \(C=1\) 的贪心就行了。

但其实还有点问题的,就是我们新增了 \(x\) 个区间的话,其实这 \(x\) 个区间也许是能有交的:比如我们有两个区间有交,但是这个交点之前都没被覆盖过,在 \(C\ge 2\) 的时候这就是合法的。

所以考虑修改一下贪心:假设我们当前选的区间是 \([l,r]\),则先找到最大的 \(p\le r\) 使得 \(p\) 被覆盖了 \(C\) 次,然后找到一个未被使用的,\(r\) 最小的,且 \(l\gt p\) 的区间,选中即可。

时间复杂度 \(O((n+m)\log)\)

代码

未完待续