Cry_For_theMoon  

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

抄袭一下 dxm 论文。

定义

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

max:cTxs.t.Axbx0

x1×n 向量,Am×n 矩阵。则上述形式对应了一个,n 个变量 m 条约束的线性规划问题。

xi 可以是实数,但一定非负。

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

对偶

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

min:bTys.t.ATycy0

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

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

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

等于的情况

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

不妨说,有两个变量 x1,x2,然后我们要求最大化 x1+x2,限制是 x1+x2=c。拆成 x1+x2cx1x2c

对偶以后:也就是最小化 y1y2,然后两条限制长得一摸一样:怎么都是 y1y21

Y:=y1y2 然后你发现就是最小化 Y,约束 Y1。而且你发现本来 y1,y2 都要求 0,但 y1y2 就无所谓了。

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

费用流对偶

考虑下列网络流问题:

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

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

然后写出线性规划形式:

min:u,vwu,vfu,vs.t.fu,vcu,vvfu,vvfv,u=buf0

zu,vfu,vcu,v 的对偶变量,puvfu,vvfv,u=bu 的对偶变量。对偶后得:

max:u,vcu,vzu,v+ubupus.t.zu,v+pupvwu,vz,p0

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

max:ubupuu,vcu,vmax{0,pupvwu,v}s.t.p0

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

例:ZJOI2013 战线规划

si1i 里放置了多少个。约束可以写成 srsl1d 的形式。

还有 sisi1,发现也可以写成上面的约束。

代价定义为 i=1nbi(sisi1),重写一下也就是 i=0n(bibi+1)si,因此可以重定义一下 bi,然后变成 i=0nbisi

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

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

min:i=0nbisi+u,vmax{0,sl1sr+d}

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

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

例:Aizu2230 How to Create a Good Game

xu,v 是边 uv 增加的量,而 wu,v 是原始边权。

再令 fi 是新图 1i 的最长路。原图里 1n 的最短路为 C

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

max:u,vxu,vs.t.fnf1Cfvfuwu,v+xu,vf,x0

依旧是考虑消去无用变量:假如我们确定了 f,则 xu,vfvfuwu,v 会直接去等号,而且这里不能和 0max,否则意味着此时 fvfu<wu,v+(xu,v=0)。所以应该把约束改写成 fvfuwu,v

整理一下:

max:(u,vfvfuwu,v)(u,vmax{0,fufv+wu,v})max{0,fnf1C}

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

另外的一些例题

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

ZJOI2020 序列

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

首先如果我们只有一操作,那么是 NOIP2018 T1 啊啊:答案直接就是 i=1nmax{0,aiai1}

然后我们令 fi 是位置 i 有多少次一操作,gi 是位置 i 有多少次二操作,则有:

min:i=1nmax{0,fifi1}+max{0,gigi2}s.t.fi+gi=aif,g0

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

注意到 gi=aifi,因此可以消去。得:

min:i=1nmax{fifi1}+max{0,aifiai2+fi2}s.t.fiaif0

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

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

min:i=1n(yi+zi)s.t.yififi1yifi+fi10ziaifiai2+fi2zi+fifi2aiai2fiaif,y,z0

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

max:i=1n(aiai2)YiZis.t.Xi1Yi1Xi+Xi+1+YiYi2Zi0X,Y,Z0

注意到确定 X,Y 以后,有 ZiXi+Xi+1+YiYi2。因此 Zi=max{0,Xi+Xi+1+YiYi2}

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

这样:最大化 i=1n(aiai2)Yimax{0,Xi+Xi+1+YiYi2} 就可以直接 dp 了。

时间复杂度 O(n)

World Tour Finals 2022 Day1 D. Welcome to Tokyo!

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

我们直接令 aii 是否选择 0/1。然后:

max:i=1mmin{1,j=lirjaj}s.t.ai1i=1naik

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

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

max:i=1mbis.t.ai1bi1bij=liriaj0i=1naik

对偶:令四条限制的对偶变量分别为 Xi,Yi,Zi,C,得:

min:i=1nXi+i=1mYi+kCs.t.Xii[lj,rj]Zj+C0Yi+Zi1

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

根据解的整数性以及我们的最优化方向:Yi+Zi1 可以拆成:YiZi=1

因此 Zi=1Yi。所以第一条限制变为:Xim+i[lj,rj]Yj+C0

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

那么我们的目标函数变成了 min:i=1mYi+kC,而第一条约束变为了 i,mi[lj,rj]YjC

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

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

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

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

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

考虑 CC+1 的时候发生的变换。实际上也就是对每个点的 inout 之间多新连一条边出来。

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

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

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

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

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

代码

未完待续
posted on   Cry_For_theMoon  阅读(219)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
 
点击右上角即可分享
微信分享提示