我草,终于开始学线性规划对偶了。
抄袭一下 dxm 论文。
定义
首先线性规划是这样一个东西:
max:cTxs.t.Ax≤bx≥0
令 x 是 1×n 向量,A 是 m×n 矩阵。则上述形式对应了一个,n 个变量 m 条约束的线性规划问题。
xi 可以是实数,但一定非负。
第一行被称作目标函数,也就是我们要最优化的内容。下面的都是我们的约束。
对偶
我们可以转而去做这样一个问题:
min:bTys.t.ATy≥cy≥0
下面这个式子的答案和上面的是一致的。
这个结果其实有很多东西值得我们理清一下:
- 首先我们注意到原问题是可能无解的:而线性规划对偶只在有解的条件下成立。换言之对偶,对判断有无解是没有帮助的,我们往往需要先确认原问题有无解。
- 注意到 y 是 1×m 矩阵。实质上:对偶就是对原问题的每个约束,新建了一个关于它变量(不妨乘坐该限制的对偶变量)。
- 我们很容易写出对偶后的目标函数,但是约束不容易比较快速的写出。按照我的理解:对偶后的问题,每个约束都和原问题中的一个变量 xi 相关。不等式右侧很好写,左侧实际上是就是,你考虑原问题的每个约束 j,如果在这个约束的左侧,xi 的系数是 pj。那么在对偶后的问题里,yj(也就是这个约束的对偶变量)的系数就也是 pj。这样就能比较快速地写出对偶后的约束。
等于的情况
常有 Ax=b 这样的约束,我们当然可以拆成 Ax≥b 和 Ax≤b 来研究,但是还有更简洁的方法。
不妨说,有两个变量 x1,x2,然后我们要求最大化 x1+x2,限制是 x1+x2=c。拆成 x1+x2≤c 和 −x1−x2≤−c。
对偶以后:也就是最小化 y1−y2,然后两条限制长得一摸一样:怎么都是 y1−y2≥1?
令 Y:=y1−y2 然后你发现就是最小化 Y,约束 Y≥1。而且你发现本来 y1,y2 都要求 ≥0,但 y1−y2 就无所谓了。
因此碰到等于的约束,我们依旧可以只得出一个对偶变量,并且它自身并不带非负的要求,可以任意取值(当然可能会被其他限制约束到)。
费用流对偶
考虑下列网络流问题:
无源汇最小费用流,可能有负权边。对每个点 u,要求:它流出的流量减去流入的流量恰好为 bu。
首先这个问题怎么费用流解决?我们先把负权边流满建反边,然后跑上下界的做法。如果能说明没有负环,则不用流满负权边,直接跑上下界也可以。我们先假设这个问题是一定有解的。
然后写出线性规划形式:
min:∑u,vwu,vfu,vs.t.−fu,v≥−cu,v∑vfu,v−∑vfv,u=buf≥0
令 zu,v 是 −fu,v≥−cu,v 的对偶变量,pu 是 ∑vfu,v−∑vfv,u=bu 的对偶变量。对偶后得:
max:∑u,v−cu,vzu,v+∑ubupus.t.−zu,v+pu−pv≤wu,vz,p≥0
这里有一个很重要的技巧:消去多余变量。就是说,假如我们确定了所有的 p,则因为 c 是非负的,那么 z 一定越小越好。而注意到:zu,v≥pu−pv−wu,v。因此我们可以直接取等号(和 0 取最大值),然后:
max:∑ubupu−∑u,vcu,vmax{0,pu−pv−wu,v}s.t.p≥0
至此,我们其实已经得到了一种机械求解这种最优化问题的方法。当然你需要确保得到的费用流问题一定有解。
例:ZJOI2013 战线规划
令 si 是 1∼i 里放置了多少个。约束可以写成 sr−sl−1≥d 的形式。
还有 si≥si−1,发现也可以写成上面的约束。
代价定义为 ∑ni=1bi(si−si−1),重写一下也就是 ∑ni=0(bi−bi+1)si,因此可以重定义一下 bi,然后变成 ∑ni=0bisi。
注意到我们并不需要令 s0=0,反正你的代价是以相邻的 s 的差的形式定义的。事实上我们想让 s0=0 也比较困难。
怎么套用到上面的形式呢?我们只用给约束加一个 ∞ 的权:也就是:
min:n∑i=0bisi+∑u,v∞max{0,sl−1−sr+d}
你发现这个式子取反就是上面的形式,直接对着建图跑费用流就行了。
不过这个题比较不牛,费用流板子比较菜会被卡,打不过单纯形。。
例:Aizu2230 How to Create a Good Game
令 xu,v 是边 u→v 增加的量,而 wu,v 是原始边权。
再令 fi 是新图 1→i 的最长路。原图里 1→n 的最短路为 C。
则我们写出线性规划形式:
max:∑u,vxu,vs.t.fn−f1≤Cfv−fu≥wu,v+xu,vf,x≥0
依旧是考虑消去无用变量:假如我们确定了 f,则 xu,v≤fv−fu−wu,v 会直接去等号,而且这里不能和 0 取 max,否则意味着此时 fv−fu<wu,v+(xu,v=0)。所以应该把约束改写成 fv−fu≥wu,v。
整理一下:
max:(∑u,vfv−fu−wu,v)−(∑u,v∞max{0,fu−fv+wu,v})−∞max{0,fn−f1−C}
直接建图跑费用流即可,这次随便过了。
另外的一些例题
不能总机械套这个模型吧?
ZJOI2020 序列
虽然有三种操作,但其实从每个位置的视角来看,只有两种操作:一种是 [l,r] 内的全部加,一种是 [l,r] 内指定奇偶性的人加。
首先如果我们只有一操作,那么是 NOIP2018 T1 啊啊:答案直接就是 ∑ni=1max{0,ai−ai−1}。
然后我们令 fi 是位置 i 有多少次一操作,gi 是位置 i 有多少次二操作,则有:
min:n∑i=1max{0,fi−fi−1}+max{0,gi−gi−2}s.t.fi+gi=aif,g≥0
(以下我们都认为下标在 [1,n] 范围外,就代表 0。)
注意到 gi=ai−fi,因此可以消去。得:
min:n∑i=1max{fi−fi−1}+max{0,ai−fi−ai−2+fi−2}s.t.−fi≥−aif≥0
到这里我们还无法直接对偶:因为目标函数里有和 0 取 max。
接下来的手法很有启发性:当我们的目标函数里出现了 max{0,x} 这种东西的时候,我们不妨新建一个变量 y≥x,然后因为线性规划自带的 y≥0 的限制,min:y 就等价于 min:max{0,x}。我们对目标函数里的两个 max,新建变量 yi,zi,则:
min:n∑i=1(yi+zi)s.t.yi≥fi−fi−1⇔yi−fi+fi−1≥0zi≥ai−fi−ai−2+fi−2⇔zi+fi−fi−2≥ai−ai−2−fi≥−aif,y,z≥0
此时可以直接对偶了,对三条限制分别新建对偶变量 X,Y,Z:
max:n∑i=1(ai−ai−2)Yi−Zis.t.Xi≤1Yi≤1−Xi+Xi+1+Yi−Yi−2−Zi≤0X,Y,Z≥0
注意到确定 X,Y 以后,有 Zi≥−Xi+Xi+1+Yi−Yi−2。因此 Zi=max{0,−Xi+Xi+1+Yi−Yi−2}。
因为这个问题能建出费用流模型,所以可以保证解的整数性,因此 X,Y 的取值都是 0/1。
这样:最大化 ∑ni=1(ai−ai−2)Yi−max{0,−Xi+Xi+1+Yi−Yi−2} 就可以直接 dp 了。
时间复杂度 O(n)。
World Tour Finals 2022 Day1 D. Welcome to Tokyo!
线性规划对偶的好题。但是整数型相关的内容有点无法感受明白啊?
我们直接令 ai 是 i 是否选择 0/1。然后:
max:m∑i=1min{1,rj∑j=liaj}s.t.ai≤1n∑i=1ai≤k
整数规划难以处理,但是我们可以猜测其一定有最优整数解,所以可以直接看作一般的线性规划。
在对偶之间,注意到目标函数有 min{1,x} 这种形式,运用上面所述的技巧:
max:m∑i=1bis.t.ai≤1bi≤1bi−ri∑j=liaj≤0n∑i=1ai≤k
对偶:令四条限制的对偶变量分别为 Xi,Yi,Zi,C,得:
min:n∑i=1Xi+m∑i=1Yi+kCs.t.Xi−∑i∈[lj,rj]Zj+C≥0Yi+Zi≥1
四个变量实在是太难以处理:考虑对于每个 C,提前算出目标函数减去 kC 的最优解 bC。这样对于每个 k,我们就相当于是查询 minkC+bC,容易求出。然后我们考虑 C 固定的情况。
根据解的整数性以及我们的最优化方向:Yi+Zi≥1 可以拆成:Yi⊕Zi=1。
因此 Zi=1−Yi。所以第一条限制变为:Xi−m+∑i∈[lj,rj]Yj+C≥0。
这里需要观察到一个贪心性质:最优解一定满足 X=0:否则我们选出其中的 X 个 Y=0 的位置,将他们变成 1,目标函数显然不会更大。
那么我们的目标函数变成了 min:∑mi=1Yi+kC,而第一条约束变为了 ∀i,m−∑i∈[lj,rj]Yj≤C。
如果一个区间的 Yi=0,则我们称这个区间被选中。则我们就是在做这样一个问题:
- 选出尽可能多的区间,使得每个点被覆盖的次数不超过 C。
那么我们瞬间有很多想法,比如凸性什么的。我们来考虑对于一个固定的 C,建出网络流模型:
那就是有一条拆点的单向链,限制了每个点被经过了不超过 C 次,然后我们对于一个区间,连 s→in(L) 和 out(R)→t。跑最大流就是答案。
首先 C=1 是经典弱智贪心:按照右端点排序考虑每个区间是否能加入即可。
考虑 C→C+1 的时候发生的变换。实际上也就是对每个点的 in→out 之间多新连一条边出来。
那你观察这个新增的连边,就很显然不会出现新的增广路是经过反悔边的。因此我们可以从这个角度来发现答案具有增量性。
也就是我们求出 C 的时候选中了哪些区间。然后 C→C+1 的时候对剩下的区间继续套那个 C=1 的贪心就行了。
但其实还有点问题的,就是我们新增了 x 个区间的话,其实这 x 个区间也许是能有交的:比如我们有两个区间有交,但是这个交点之前都没被覆盖过,在 C≥2 的时候这就是合法的。
所以考虑修改一下贪心:假设我们当前选的区间是 [l,r],则先找到最大的 p≤r 使得 p 被覆盖了 C 次,然后找到一个未被使用的,r 最小的,且 l>p 的区间,选中即可。
时间复杂度 O((n+m)log)。
代码
未完待续
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?