Day 35 · 2026.07.27

运筹学

Operations Research — 在约束的世界里求最优
"Operations research is the art of giving bad answers to problems to which otherwise worse answers are given." — Thomas L. Saaty

线性规划与单纯形法

Linear Programming & the Simplex Method · 约束优化的骨架
Optimization
直觉版

想象一间工厂:几种产品共享有限的原料、工时、机器。每条资源限制都在决策空间里切一刀——「钢材不超过 100 吨」就是一个半空间;所有约束叠加后剩下的可行区域,是一块高维的多面体

利润是线性的,「利润相等」的等值面便是一族平行平面;沿利润增大的方向推它,最后离开多面体的那一点就是最优解。最优解必定落在顶点上——无穷多个可行点被压缩成有限个角落。单纯形法据此工作:站在一个顶点,找一条能让利润上升的棱走过去,直到四周再无上升方向;凸性保证此时局部最优即全局最优。

可行域(多面体) 目标方向 c 最优顶点 x₁ x₂
正式定义
$$\max_{x}\; c^\top x \quad \text{s.t.} \quad Ax \le b,\; x \ge 0$$

$x$ 是决策变量(各产品生产多少),$c$ 是单位利润,$A_{ij}$ 表示一单位产品 $j$ 消耗多少资源 $i$,$b$ 是资源存量。它的对偶问题是:

$$\min_{y}\; b^\top y \quad \text{s.t.} \quad A^\top y \ge c,\; y \ge 0$$

$y$ 的每个分量对应原问题的一条约束,含义是该资源的影子价格:多给一吨钢材,利润能涨多少。强对偶定理说:只要原问题有最优解,两边最优值相等

为什么美

对偶性是「同一件事的两种说法」在数学中的典范:原问题问「我最多能赚多少」,对偶问题问「这堆资源最少值多少钱」——答案必然相同,因为利润的天花板就是资源本身的价值。

更深的美在可验证性:任何可行的 $y$ 给出上界,任何可行的 $x$ 给出下界,两者相遇时最优性就被证明了,不必再搜索。顺带一提:单纯形法最坏情况是指数时间,实践中却几乎总走线性步数——理论保证与实践表现的错位,是运筹学的经典一课。

应用

航空机组排班(单个模型常有数十万变量)、电网机组组合——你交的电价本质就是一个对偶变量。计算机领域:整数规划先解 LP 松弛拿到界,这是分支定界的引擎;SVM 的对偶形式让核方法成为可能;强化学习可写成占用测度上的 LP,对偶变量恰好是价值函数——Bellman 方程与 LP 对偶是同一件事的两种写法。

一句话精华 · 思考题
线性规划的核心不是「算出来」,而是最优性可以被一张对偶证书当场验证。
你团队里瓶颈资源的影子价格是多少——多投一个人天,产出能涨多少?若某项资源的影子价格是 0,这说明了什么?

最大流与最小割

Max-Flow Min-Cut · 组合世界里的对偶
Graph · Combinatorics
直觉版

把网络想成水管系统:源点 $s$ 出水、汇点 $t$ 收水,每条管道有容量上限。最多能送多少水过去?

做法很朴素——不停寻找「还能再加一点水」的路径,加满一条再找下一条,直到找不到为止。奇妙的是终止那一刻:把网络一刀切成两半($s$ 一边、$t$ 一边),被切断的管道容量之和,恰好等于你送出去的水量。瓶颈从来不是某一条管子,而是某一组管子——一道割。

最小割 6 + 9 = 15 s a b c d t 10 8 3 6 9 7 9 最大流 = 15
正式定义
$$\max_{f}\; |f| \;=\; \min_{(S,T)}\; \sum_{u\in S,\, v\in T} c(u,v)$$

左边:在所有满足容量上限、且每个中间节点流入等于流出(流量守恒)的流 $f$ 里取最大值 $|f|$。右边:在所有把 $s$ 与 $t$ 分开的划分 $(S,T)$ 里,取「从 $S$ 指向 $T$ 的边容量之和」的最小值。定理说:两者永远相等

为什么美

这是 LP 对偶在组合世界里的化身,但多带了一个礼物:整数性。容量都是整数时,最大流一定存在整数解——不会冒出「流 2.5 个单位」这种在 LP 里合法、在现实中却无法解释的答案。根源是关联矩阵的全幺模性,它保证多面体的顶点全落在整点上。

于是一个定理坍缩了一整片定理:二分图最大匹配是它的特例(由此得 König 定理:最大匹配 = 最小点覆盖),Menger 定理也是它的投影。你以为在解不同的问题,其实一直在解同一个。

应用

图像分割:把像素当节点、相邻像素的相似度当容量,最小割就是最自然的前景/背景分界线——graph cut 是深度学习之前分割任务的主力,今天仍是条件随机场后处理的核心。此外还有跨机房流量工程、CDN 带宽调度、项目选择。问「这套架构最大能扛多少吞吐」,数学上就是在找最小割。

一句话精华 · 思考题
系统的能力,等于把它切成两半的最便宜的那一刀。
你负责的系统里「最小割」是什么——哪一(不是哪一个)组件同时失效才会切断服务?你的冗余加在割上了,还是加在本来就不紧的地方?

排队论与 Little 定律

Queueing Theory & Little's Law · 等待的数学
Applied Probability
直觉版

高速公路平均利用率 90%,听起来还有余量,实际却走走停停。为什么?因为车不是均匀到达的。平均够用,不代表每一刻都够用;瞬时的拥挤会积压,而积压需要「闲暇」才能消化——利用率越高,闲暇越少,积压越散不掉。

于是排队的痛苦不是线性增长,而是当利用率 $\rho$ 逼近 1 时向无穷爆炸:从 50% 涨到 60% 你几乎无感,从 90% 涨到 95% 等待时间直接翻倍。

ρ=0.5 ρ=0.8 ρ=0.9 ρ→1 0 W ρ 等待时间 ∝ 1/(1−ρ)
正式定义
$$L = \lambda W$$

$L$ 是系统中平均滞留的顾客数,$\lambda$ 是平均到达率(个/秒),$W$ 是每位顾客的平均逗留时间。对最简单的 M/M/1 队列(泊松到达、指数服务时间、单服务台):

$$W = \frac{1}{\mu-\lambda} = \underbrace{\frac{1}{\mu}}_{\text{纯服务}} \cdot \underbrace{\frac{1}{1-\rho}}_{\text{拥塞放大}},\qquad \rho=\frac{\lambda}{\mu}$$

$\mu$ 是服务率,$1/\mu$ 是「没人排队时」你本该花的时间,后面那个因子就是排队的放大倍数:$\rho=0.9$ 放大 10 倍,$\rho=0.99$ 放大 100 倍。

为什么美

Little 定律的普适性近乎不讲道理:它不需要知道到达与服务服从什么分布、是否先来先服务、有几个窗口。只要系统长期稳定就成立。原因是它本质上是一条守恒律——把「顾客数 × 时间」这块面积用两种方式积分:一种按人切,一种按时刻切。假设极少而结论极强,这在数学里非常稀有。

Kingman 公式更进一步:等待时间还正比于到达与服务的变异系数 $(c_a^2+c_s^2)/2$。降方差与加容量因此是同一件事的两个旋钮——这解释了为什么削峰填谷、统一请求大小、隔离长尾任务,常常比加机器更有效。

应用

这是分布式系统容量规划的地基:为什么 SRE 把 CPU 目标定在 60–70% 而不是 95%;为什么 P99 尾延迟由 $\rho$ 而非均值主导;负载均衡里「两选一」(power of two choices)为何能大幅削减队长。LLM 推理服务的 continuous batching 与 KV cache 争用是多类排队问题——吞吐与尾延迟的取舍就是在这条双曲线上选点。

一句话精华 · 思考题
利用率的最后 10%,是用趋于无穷的等待买回来的。
若服务方差降低一半、容量完全不变,用户感知的延迟会如何变化?为什么「削峰」常常比「扩容」便宜,团队却总是先选扩容?

调度与近似保证

Scheduling & Approximation Guarantees · 在困难面前换问题
Combinatorial Optimization
直觉版

把 $n$ 个任务分给 $m$ 台机器,让最后一台完工的时刻(makespan)尽量早。只要两台机器,它就等价于「把一堆数分成两堆使两堆之和尽量接近」——NP 困难。

运筹学的态度不是「解不了就放弃」,而是换一个问题:不求最优,求「保证离最优不远」。最朴素的做法——任务来一个就丢给当前最空的机器——已能保证不超过最优的 $2-1/m$ 倍;若先按耗时从大到小排序(LPT),保证收紧到 $4/3$ 左右。先放大石头、再用沙子填缝,这条日常直觉可以被严格证明。

任意顺序:makespan = 9 M1 M2 M3 9 LPT(先大后小):makespan = 8 = 最优 M1 M2 M3 8
正式定义
$$C_{\max}^{\text{LPT}} \;\le\; \left(\frac{4}{3}-\frac{1}{3m}\right) C_{\max}^{*}$$

$C_{\max}$ 是最大完工时间,上标 $*$ 表示最优值,$m$ 是机器数。这类不等式叫近似比:算法在任何输入上都不会差过最优的某个常数倍——不是平均意义,而是最坏意义的承诺。

证明只用两个下界:最优 makespan 至少是「总工作量 ÷ 机器数」,也至少是「最长的那个任务」;而最后完工的机器,开工时刻不会晚于平均负载。

为什么美

这是复杂性理论与工程实践握手的地方。NP 困难说「别指望算出最优」,近似算法接着说「那就把不精确变成有量化保证的不精确」。问题从「能不能解」变成「能保证多好」——这是问题定义层面的胜利。

它还附赠一个反直觉的礼物:Graham 异常。增加机器、缩短某个任务的耗时、放松一条依赖约束,都可能让 makespan 变长。在有调度的系统里,「局部改善必然带来全局改善」是错的。

应用

编译器的指令调度、GPU 上 kernel 排布与算子融合、Spark/Flink 的 DAG 调度、Kubernetes 与 Borg 的装箱与抢占。LLM 训练中流水线并行的 bubble 最小化就是带依赖的调度:为什么把 micro-batch 切细能填掉气泡,答案就在同一套下界分析里。

一句话精华 · 思考题
当最优不可得,「最坏也差不了多少」就成了新的最优。
你安排一天的工作时是否在用 LPT——先啃最大的那块?什么情况下它会失效?(提示:任务之间有依赖,或大任务的耗时估计本身就不准。)

深入思考

LP 的对偶变量是影子价格,Bellman 方程里的价值函数也是对偶变量——这个对应能推多远?
强化学习的 LP 表述中,原问题在「占用测度」上最大化期望回报,对偶变量恰是状态价值 $V(s)$,对偶约束正是 Bellman 不等式;互补松弛对应「最优策略只在取等号的动作上放概率」,即贪心。这解释了策略迭代为何酷似单纯形法:每次在某状态换一个动作(换基),单调改善、有限步收敛。但状态连续时 LP 变成无穷维,引入函数逼近后强对偶失效——深度 RL 的诸多不稳定,源头就在这个断裂处。
最大流最小割的「整数性奇迹」能推广到哪里?
根源是约束矩阵的全幺模性:任何方子式的行列式都是 $0,\pm 1$,于是多面体的顶点自动落在整点上,LP 松弛不必取整就是组合最优解。网络流、二分图匹配、最短路都有此性质。一旦加上「每个节点最多用一次」这类约束(一般图匹配、旅行商),矩阵不再全幺模,松弛会解出半整数解,只能靠割平面补救。经验法则由此而来:判断一个组合问题容易还是困难,往往等价于判断它的多面体长什么样。
运筹学算出的最优解,为什么现实中常常不被采用?
目标函数是现实的一个投影,投影必然丢东西:鲁棒性、公平性、人的偏好、为下一期保留的灵活性。一个刚好卡在所有约束边界上的最优解,参数稍有扰动就可能崩得比平庸而稳健的解更惨——这正是鲁棒优化与随机规划诞生的理由。Saaty 那句话说的就是这件事:它的价值不在「最优」二字,而在逼你把隐含的权衡写成显式的目标与约束。
这四个概念背后是同一个思想吗?
是的,这个思想叫「界」。LP 对偶给出可验证的上下界;最大流最小割是这个界在组合结构上取到相等;近似算法放弃取等,但保证比值有限;排队论给的是随机意义下的界。运筹学的气质由此显现:它很少追求「精确解出世界」,而是不断问「我能证明什么一定成立」。对做系统的人来说这比任何具体算法更可迁移——容量规划、SLO 制定、成本估算,本质都是给不确定的现实划一条站得住的界。