杭二学习Day3——专题(最大权闭合子图&高斯消元&线性规划——单纯形)

it2022-07-01  98

背景:

今天中午竟然下雨了。

最大权闭合子图:

晚上回去补。

高斯消元:

不就是一个 Θ ( n 2 ) \Theta(n^2) Θ(n2)大暴力吗? 题目传送门: luogu P3389 \text{luogu P3389} luogu P3389【模板】高斯消元法。 贴一份代码吧。

#include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int n; double a[110][110]; void gauss() { for(int i=1;i<=n;i++) { int p=i; for(int j=i+1;j<=n;j++) if(fabs(a[p][i])<fabs(a[j][i])) p=j; if(fabs(a[p][i])<1e-8) { printf("No Solution"); return; } for(int j=1;j<=n+1;j++) swap(a[i][j],a[p][j]); for(int j=i+1;j<=n;j++) { double d=a[j][i]/a[i][i]; for(int k=i;k<=n+1;k++) a[j][k]-=d*a[i][k]; } } for(int i=n;i>=1;i--) { for(int j=i+1;j<=n;j++) a[i][n+1]-=a[j][n+1]*a[i][j]; a[i][n+1]/=a[i][i]; } for(int i=1;i<=n;i++) printf("%.2lf\n",a[i][n+1]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n+1;j++) scanf("%lf",&a[i][j]); gauss(); }

单纯形:

一种神奇的操作。

题目传送门:

uoj P179. \text{uoj P179.} uoj P179.线性规划。

题意:

已知 a , b , c a,b,c a,b,c三个数组。 我们得到了一些第 i i i条式子形如 ∑ j = 1 n a i j x j ≤ b i \sum_{j=1}^{n}a_{ij}x_{j}≤b_i j=1naijxjbi约束条件。现在要找到 x j ≥ 0 x_j≥0 xj0的使 ∑ j = 1 n c j x j \sum_{j=1}^{n}c_jx_j j=1ncjxj最大的解以及这个结果。

正题:

这个问题被称为线性规划。 高中必修书有讲,但上面是画图求解。 作为一名优秀的 oier \text{oier} oier,我们肯定要会打暴力 啊。 没错,这是一种极为优秀的暴力——单纯形法求解线性规划。

Part1 \text{Part1} Part1

首先我们有标准式子,形如: max ⁡ 5 x 1 + 4 x 2 + 3 x 3 s.t. 2 x 1 + 3 x 2 + x 3 ≤ 5 4 x 1 + x 2 + 2 x 3 ≤ 11 3 x 1 + 4 x 2 + 2 x 3 ≤ 8 x 1 , x 2 , x 3 ≥ 0 \begin{aligned}\max 5x_1+4x_2+3x_3\\ \text{s.t.} 2x_1+3x_2+x_3&≤5\\ 4x_1+x_2+2x_3&≤11\\ 3x_1+4x_2+2x_3&≤8\\ x_1,x_2,x_3≥0\end{aligned} max5x1+4x2+3x3s.t.2x1+3x2+x34x1+x2+2x33x1+4x2+2x3x1,x2,x305118

[ 1 ] . [1]. [1].我们要求最小怎么办?

− ( max ⁡ ( − ( 5 x 1 + 4 x 2 + 3 x 3 ) ) ) = min ⁡ ( 5 x 1 + 4 x 2 + 3 x 3 ) -\left(\max \left(-\left(5x_1+4x_2+3x_3\right)\right)\right)=\min(5x_1+4x_2+3x_3) (max((5x1+4x2+3x3)))=min(5x1+4x2+3x3)

[ 2 ] . [2]. [2].如果 x i x_i xi可以为负怎么办?

x ′ − x ′ ′ x'-x'' xx代替 x i x_i xi,其中 x ′ , x ′ ′ ≥ 0 x',x''≥0 x,x0

[ 3 ] . [3]. [3].如果符号为 = = =怎么办?

2 x 1 + 3 x 2 + x 3 = 5 2x_1+3x_2+x_3=5 2x1+3x2+x3=5

x 4 ≥ 0 x_4≥0 x40,有: 2 x 1 + 3 x 2 + x 3 + x 4 ≥ 5 2x_1+3x_2+x_3+x_4≥5 2x1+3x2+x3+x45

[ 4 ] . [4]. [4].如果符号为 ≥ ≥ 怎么办?

2 x 1 + 3 x 2 + x 3 ≥ 5 2x_1+3x_2+x_3≥5 2x1+3x2+x35

两边同乘 − 1 -1 1,得: → − 2 x 1 − 3 x 2 − x 3 ≤ − 5 →-2x_1-3x_2-x_3≤-5 2x13x2x35

Part2 \text{Part2} Part2

考虑将式子化为等式,有: z = max ⁡ 5 x 1 + 4 x 2 + 3 x 3 s.t. 2 x 1 + 3 x 2 + x 3 − x 4 = 5 4 x 1 + x 2 + 2 x 3 − x 5 = 11 3 x 1 + 4 x 2 + 2 x 3 − x 6 = 8 x 1 , x 2 , x 3 , x 4 , x 5 , x 6 ≥ 0 \begin{aligned}z=\max 5x_1+4x_2+3x_3\\ \text{s.t.} 2x_1+3x_2+x_3-x_4&=5\\ 4x_1+x_2+2x_3-x_5&=11\\ 3x_1+4x_2+2x_3-x_6&=8\\ x_1,x_2,x_3,x_4,x_5,x_6≥0\end{aligned} z=max5x1+4x2+3x3s.t.2x1+3x2+x3x44x1+x2+2x3x53x1+4x2+2x3x6x1,x2,x3,x4,x5,x60=5=11=8 这个操作称为松弛。

移一下项,有: z = − ( 5 x 1 + 4 x 2 + 3 x 3 ) s.t. x 4 = 5 − ( 2 x 1 + 3 x 2 + x 3 ) x 5 = 11 − ( 4 x 1 + x 2 + 2 x 3 ) x 6 = 8 − ( 3 x 1 + 4 x 2 + 2 x 3 ) x 1 , x 2 , x 3 , x 4 , x 5 , x 6 ≥ 0 z=-(5x_1+4x_2+3x_3)\\ \begin{aligned}\text{s.t.} x_4&=5-(2x_1+3x_2+x_3)\\ x_5&=11-(4x_1+x_2+2x_3)\\ x_6&=8-(3x_1+4x_2+2x_3)\end{aligned}\\ x_1,x_2,x_3,x_4,x_5,x_6≥0 z=(5x1+4x2+3x3)s.t.x4x5x6=5(2x1+3x2+x3)=11(4x1+x2+2x3)=8(3x1+4x2+2x3)x1,x2,x3,x4,x5,x60

对于左边这些新加进来的变量,我们称为基变量;右边这些旧的变量,我们称为非基变量。

Part3 \text{Part3} Part3

开始求解了。 做法就是:令这些非基变量为 0 0 0,就得到了基本可行解: { x 1 , x 2 , x 3 , x 4 , x 5 , x 6 } = { 0 , 0 , 0 , 5 , 11 , 8 } \{x_1,x_2,x_3,x_4,x_5,x_6\}=\{0,0,0,5,11,8\} {x1,x2,x3,x4,x5,x6}={0,0,0,5,11,8}。 许多时候,这已经是 x x x的一组解,尽管不一定是最有的。 但是有例外: max ⁡ x 1 + x 2 s.t. x 1 + 3 x 2 ≤ − 2 x 1 , x 2 ≥ 0 \max x_1+x2\\ \begin{aligned}\text{s.t.}x_1+3x_2≤-2 \end{aligned}\\ x_1,x_2≥0 maxx1+x2s.t.x1+3x22x1,x20

z = − ( x 1 + x 2 ) s.t. x 3 = − 2 + ( x 1 + 3 x 2 ) x 1 , x 2 ≥ 0 z=-(x_1+x2)\\ \begin{aligned}\text{s.t.}x_3=-2+(x_1+3x_2) \end{aligned}\\ x_1,x_2≥0 z=(x1+x2)s.t.x3=2+(x1+3x2)x1,x20 x 1 , x 2 = 0 x_1,x_2=0 x1,x2=0时,有: { x 1 , x 2 , x 3 } = { 0 , 0 , − 2 } \{x_1,x_2,x_3\}=\{0,0,-2\} {x1,x2,x3}={0,0,2}。 此时不合法。

为什么不合法? 我们发现 b i < 0 b_i<0 bi<0时存在不合法方案(例子中的 − 2 < 0 -2<0 2<0)。 此时我们就要判断是否有解。 若 b i < 0 b_i<0 bi<0,找到一个 a j < 0 a_j<0 aj<0,转换它们,不断重复直到所有的 b i b_i bi都大于 0 0 0。 若最后无法使所有的 b i > 0 b_i>0 bi>0(即当前 b i < 0 b_i<0 bi<0时无法找到 a j < 0 a_j<0 aj<0),那么无解。 转换的过程可以用高斯消元。


最新回复(0)