想象一间工厂:几种产品共享有限的原料、工时、机器。每条资源限制都在决策空间里切一刀——「钢材不超过 100 吨」就是一个半空间;所有约束叠加后剩下的可行区域,是一块高维的多面体。
利润是线性的,「利润相等」的等值面便是一族平行平面;沿利润增大的方向推它,最后离开多面体的那一点就是最优解。最优解必定落在顶点上——无穷多个可行点被压缩成有限个角落。单纯形法据此工作:站在一个顶点,找一条能让利润上升的棱走过去,直到四周再无上升方向;凸性保证此时局部最优即全局最优。
$x$ 是决策变量(各产品生产多少),$c$ 是单位利润,$A_{ij}$ 表示一单位产品 $j$ 消耗多少资源 $i$,$b$ 是资源存量。它的对偶问题是:
$y$ 的每个分量对应原问题的一条约束,含义是该资源的影子价格:多给一吨钢材,利润能涨多少。强对偶定理说:只要原问题有最优解,两边最优值相等。
对偶性是「同一件事的两种说法」在数学中的典范:原问题问「我最多能赚多少」,对偶问题问「这堆资源最少值多少钱」——答案必然相同,因为利润的天花板就是资源本身的价值。
更深的美在可验证性:任何可行的 $y$ 给出上界,任何可行的 $x$ 给出下界,两者相遇时最优性就被证明了,不必再搜索。顺带一提:单纯形法最坏情况是指数时间,实践中却几乎总走线性步数——理论保证与实践表现的错位,是运筹学的经典一课。
航空机组排班(单个模型常有数十万变量)、电网机组组合——你交的电价本质就是一个对偶变量。计算机领域:整数规划先解 LP 松弛拿到界,这是分支定界的引擎;SVM 的对偶形式让核方法成为可能;强化学习可写成占用测度上的 LP,对偶变量恰好是价值函数——Bellman 方程与 LP 对偶是同一件事的两种写法。
把网络想成水管系统:源点 $s$ 出水、汇点 $t$ 收水,每条管道有容量上限。最多能送多少水过去?
做法很朴素——不停寻找「还能再加一点水」的路径,加满一条再找下一条,直到找不到为止。奇妙的是终止那一刻:把网络一刀切成两半($s$ 一边、$t$ 一边),被切断的管道容量之和,恰好等于你送出去的水量。瓶颈从来不是某一条管子,而是某一组管子——一道割。
左边:在所有满足容量上限、且每个中间节点流入等于流出(流量守恒)的流 $f$ 里取最大值 $|f|$。右边:在所有把 $s$ 与 $t$ 分开的划分 $(S,T)$ 里,取「从 $S$ 指向 $T$ 的边容量之和」的最小值。定理说:两者永远相等。
这是 LP 对偶在组合世界里的化身,但多带了一个礼物:整数性。容量都是整数时,最大流一定存在整数解——不会冒出「流 2.5 个单位」这种在 LP 里合法、在现实中却无法解释的答案。根源是关联矩阵的全幺模性,它保证多面体的顶点全落在整点上。
于是一个定理坍缩了一整片定理:二分图最大匹配是它的特例(由此得 König 定理:最大匹配 = 最小点覆盖),Menger 定理也是它的投影。你以为在解不同的问题,其实一直在解同一个。
图像分割:把像素当节点、相邻像素的相似度当容量,最小割就是最自然的前景/背景分界线——graph cut 是深度学习之前分割任务的主力,今天仍是条件随机场后处理的核心。此外还有跨机房流量工程、CDN 带宽调度、项目选择。问「这套架构最大能扛多少吞吐」,数学上就是在找最小割。
高速公路平均利用率 90%,听起来还有余量,实际却走走停停。为什么?因为车不是均匀到达的。平均够用,不代表每一刻都够用;瞬时的拥挤会积压,而积压需要「闲暇」才能消化——利用率越高,闲暇越少,积压越散不掉。
于是排队的痛苦不是线性增长,而是当利用率 $\rho$ 逼近 1 时向无穷爆炸:从 50% 涨到 60% 你几乎无感,从 90% 涨到 95% 等待时间直接翻倍。
$L$ 是系统中平均滞留的顾客数,$\lambda$ 是平均到达率(个/秒),$W$ 是每位顾客的平均逗留时间。对最简单的 M/M/1 队列(泊松到达、指数服务时间、单服务台):
$\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 争用是多类排队问题——吞吐与尾延迟的取舍就是在这条双曲线上选点。
把 $n$ 个任务分给 $m$ 台机器,让最后一台完工的时刻(makespan)尽量早。只要两台机器,它就等价于「把一堆数分成两堆使两堆之和尽量接近」——NP 困难。
运筹学的态度不是「解不了就放弃」,而是换一个问题:不求最优,求「保证离最优不远」。最朴素的做法——任务来一个就丢给当前最空的机器——已能保证不超过最优的 $2-1/m$ 倍;若先按耗时从大到小排序(LPT),保证收紧到 $4/3$ 左右。先放大石头、再用沙子填缝,这条日常直觉可以被严格证明。
$C_{\max}$ 是最大完工时间,上标 $*$ 表示最优值,$m$ 是机器数。这类不等式叫近似比:算法在任何输入上都不会差过最优的某个常数倍——不是平均意义,而是最坏意义的承诺。
证明只用两个下界:最优 makespan 至少是「总工作量 ÷ 机器数」,也至少是「最长的那个任务」;而最后完工的机器,开工时刻不会晚于平均负载。
这是复杂性理论与工程实践握手的地方。NP 困难说「别指望算出最优」,近似算法接着说「那就把不精确变成有量化保证的不精确」。问题从「能不能解」变成「能保证多好」——这是问题定义层面的胜利。
它还附赠一个反直觉的礼物:Graham 异常。增加机器、缩短某个任务的耗时、放松一条依赖约束,都可能让 makespan 变长。在有调度的系统里,「局部改善必然带来全局改善」是错的。
编译器的指令调度、GPU 上 kernel 排布与算子融合、Spark/Flink 的 DAG 调度、Kubernetes 与 Borg 的装箱与抢占。LLM 训练中流水线并行的 bubble 最小化就是带依赖的调度:为什么把 micro-batch 切细能填掉气泡,答案就在同一套下界分析里。