案例094 最小最大后悔
案例094 最小最大后悔
摘要:5 个候选区域、4 个需求情景(写字楼爆单 / 老小区爆单 / 雨天普涨 / 节假日),单量矩阵为构造的示例数据,落在 13—34 单/日。后悔定义为"该情景事后最优(列最大)减去实际单量",用 \(R_{\max}\ge\max_{i'}R_{i'j}-\sum_iR_{ij}y_i\) 对 4 个情景逐条展开,模型是 6 变量、5 约束的 MILP,Gurobi 在 0.000 s、根节点即定案(0 次分支):选 B 老城住宅区,后悔上限 10.0 单。三准则给出三个答案——期望最大选 A(25.00 单,最坏后悔 13),min-max 后悔选 B(24.00 单,10),max-min 选 C(最差 21 单,最坏后悔 12);"最稳"的 B 反而最差单量不如 C,说明稳健不等于最坏。灵敏度给出三条线:后悔界对波动幅度严格线性(λ=0.6 时 6.4、λ=1.9 时 18.1);CVaR 的临界置信水平在 β=0.75—0.80 之间,β→1 时退化为 min-max;情景数 K 从 4 增到 32,后悔界从 11.28 按 \(\sqrt{2\ln K}\) 升到 15.92,8 情景下界为 12 而实际平均后悔仅 7.38,差额就是保守的保费。
关键词:最小最大后悔;min-max regret 线性化;鲁棒决策;CVaR;机会约束;情景生成;区域驻点
1 问题提出
外卖平台的区域调度有个绕不开的动作:前一天晚上决定第二天把运力(骑手、站点、备用电动车)押在哪个区域。押中了,单量 34 单、骑手跑满;押错了,眼看着隔壁区域爆单,自己这边骑手空转。这就是先决策、后见世界:明天是"写字楼爆"还是"老小区爆",做决定时并不知道。
决策规则有很多种,本案只问三种。赌一把——按期望单量选,A 商务区 25.00 单最高;最坏情况下最好(max-min)——让最少那天的单量最大,C 大学城最差也有 21 单;最小最大后悔(min-max regret)——不做"事后诸葛亮"的梦,只要求"回头看时别输得太难看"。三者在本案给出三个不同的答案,这才是问题有意思的地方。后悔的定义必须说清楚:情景 \(j\) 下的后悔是该情景的事后最优减去你的实际单量,即 \(r_{ij}=\max_{i'}R_{i'j}-R_{ij}\)。基准是列最大,不是列平均,也不是你自己的历史平均。用列平均做基准,后悔就退化成"比平均差多少",那就不是后悔了;用行内最大做基准,则每个区域的后悔都是 0,模型彻底失灵。
2 数学模型
设候选区域集合 \(\mathcal{I}=\{1,\dots,5\}\),情景集合 \(\mathcal{J}=\{1,\dots,4\}\),\(R_{ij}\) 为区域 \(i\) 在情景 \(j\) 的单量(单/日),\(y_i\in\{0,1\}\) 表示选 \(i\) 驻点,\(R_{\max}\) 为最大后悔。
后悔与目标。
式 (2) 右边那个 \(\max_{i'}R_{i'j}\) 是常数(在建模前就能算出来,等于第 \(j\) 列的最大值),所以整条约束是线性的;情景集有限,\(\max\) 就展开成 \(|\mathcal{J}|\) 条约束。这是 min-max 后悔能被 MILP 直接吃下去的全部原因——取最大的是有限个已知常数,不是决策变量。若基准也随决策变,问题立刻变成非凸。
三个对照模型。 期望最大等价于最小平均后悔:
max-min 最大化最坏情景的单量:
CVaR 与机会约束。 引入情景概率 \(\pi_j\)、置信水平 \(\beta\),后悔的 CVaR 用 Rockafellar-Uryasev 形式:
机会约束把"后悔不超过 \(\rho\)"的概率按住,\(z_j\) 标记被违反的情景:
\(\beta\to 1\) 时式 (6) 的目标趋近 \(\max_j r_{ij}\),也就是说min-max 后悔是 CVaR 的极限情形,不是另一种哲学。
3 Gurobi 求解实现
数据是构造的示例,不是真实平台流水,构造逻辑如下:按城市功能把运力市场切成 5 块——A 中央商务区(写字楼密集,工作日午间单量尖峰)、B 老城住宅区(老龄化、居家做饭,恶劣天气反而涨)、C 大学城(学生作息,节假日留校点单)、D 新区产业园(团餐为主,工作日稳)、E 城郊居住区(通勤族,晚间为主)。4 个情景按需求驱动力设定:S1 写字楼爆单(会议与加班)、S2 老小区爆单(下雨不出门)、S3 雨天普涨(全城 +10% 上下)、S4 节假日(写字楼空城、学生留校、居民出游)。数值落在 13—34 单/日:工作日 18—34 单,节假日最低压到 13 单,行内极差 8—21 单。
表 1 5 区域 × 4 情景单量矩阵(单/日,构造的示例数据)
| 区域 | 写字楼爆单 | 老小区爆单 | 雨天普涨 | 节假日 | 均值 | 最差 | 最大后悔 |
|---|---|---|---|---|---|---|---|
| A 商务区 | 34 | 22 | 31 | 13 | 25.00 | 13 | 13 |
| B 老住宅 | 24 | 30 | 22 | 20 | 24.00 | 20 | 10 |
| C 大学城 | 22 | 21 | 26 | 26 | 23.75 | 21 | 12 |
| D 产业园 | 19 | 26 | 25 | 23 | 23.25 | 19 | 15 |
| E 城郊 | 18 | 25 | 20 | 22 | 21.25 | 18 | 16 |
| 列最大 | 34 | 30 | 31 | 26 | — | — | — |
表 1 最后一行是后悔的基准。四个情景的最优分别由 A、B、A、C 拿到——没有哪个区域在所有情景都最优,这正是后悔存在的前提。
模型只有 6 个变量(5 个 0-1 加 1 个连续)和 5 条约束,Gurobi 在 0.00 s、根节点即定案(0 次分支),40 个模型(三准则 + 18 点 \(\lambda\) + 9 点 \(\beta\) + 30 点机会约束 + 前沿)合计 1.5 s。
三个必须踩过的坑:(1)基准要按列取。写成 \(\max_{i,j}R_{ij}\)(全局最大 34)会让每个区域的后悔都被抬高同一个常数,解不变但目标值失真;写成行内最大则后悔恒为 0。
(2)\(R_{\max}\) 只需下界。目标是最小化 \(R_{\max}\),它的最优值必然顶到最紧的那条约束上,不需要额外的等式;加 \(R_{\max}\ge 0\) 只是为了让"所有区域都在某情景最优"的退化情形不发散。
(3)别用平均后悔冒充后悔。平均后悔与期望单量只差一个常数 \(\frac{1}{|\mathcal{J}|}\sum_j\max_{i'}R_{i'j}\) 的相反数,两者给出同一个解——表 1 里 A 的平均后悔 5.25 最小,恰好也是期望最大。想让"后悔"真正区别于"期望",就必须取 \(\max\) 而不是 \(\sum\)。
4 结果分析
4.1 结构:谁在哪个世界里赢

图 1 5 区域 × 4 情景单量矩阵(红星系该区域在该情景最优,顶部为列最大)
图 1 是全部事实的来源。A 在 S1 拿到 34 单、在 S3 拿到 31 单,是唯二的高点;代价写在最后一列——节假日只剩 13 单。B 没有尖峰,但四格都在 20 以上。C 的两头分得很开:平日 21—22 单,节假日 26 单。后悔就是把这张表的每一列"拍平"到列最大,再看每个区域被削掉多少。

图 2 期望单量—最大后悔平面(气泡面积为最差情景单量,三种准则的选点)
图 2 把五个候选点放进"期望—后悔"平面。左上角是理想但不存在的位置;A 在最右(期望最高)、B 在最上(后悔最低但不在顶部)、C 在右下(最差单量最高)。三点互不支配,所以"该选谁"没有唯一正确答案,只有偏好。这也是本案例最该讲清楚的一件事:三个准则不是三个精度,是三个偏好。

图 3 四种准则的期望单量与最坏后悔
图 3 给出四条准则的量化结果:期望最大选 A(期望 25.00、最坏后悔 13);min-max 后悔选 B(期望 24.00、最坏后悔 10);max-min 选 C(期望 23.75、最差单量 21、最坏后悔 12);等权平均(最小平均后悔)选 A,与期望最大完全重合——第四根柱子和第一根一模一样,不是巧合,是上一节那条常数差。"稳健不等于最坏":B 的最差单量只有 20,比 C 的 21 还低 1 单;B 稳的不是最坏世界,是"最坏世界里的差距"。要最坏情景最好,该选 C;要后悔最小,该选 B。

图 4 连续 60 天固定驻点于同一区域的累积后悔(灰底为后 30 天)
图 4 把"一天"拉成"两个月"。按情景概率抽 60 天,A 的累积后悔 188 单最低,B 是 396 单,E 最差 635 单。min-max 后悔在这 60 天里是输的——因为它保的是最坏世界,而最坏世界在样本里没出现几次。这不是模型错了,是它保的东西本来就不在这条时间线上:它卖的是保险,保险在没出事的时候一定是亏的。
4.2 灵敏度:波动、概率、情景数

图 5 情景波动幅度 λ 对最优后悔(左轴)与选中区域期望单量(右轴)的影响
图 5 把每个情景的单量绕行均值缩放:\(R_{ij}(\lambda)=\bar R_i+\lambda(R_{ij}-\bar R_i)\)。后悔界严格线性:λ=0.6 时 6.4,λ=1.9 时 18.1,正好是 10.67 倍的 λ。原因是后悔对单量的仿射变换是齐次的——列最大与行内偏离同比例缩放,\(\lambda\) 直接从 \(\max\) 里提出来。这解释了一件事:min-max 后悔对"全城单量普涨普跌"完全免疫,它只对情景之间的相对结构敏感。整条扫描线上选点始终是 B,说明基准情景的偏好序在 ±40% 的波动范围内是稳的。
表 2 CVaR 置信水平 β 的扫描(后悔的 CVaR,单位:单)
| β | 0.50 | 0.60 | 0.70 | 0.75 | 0.80 | 0.90 | 0.99 |
|---|---|---|---|---|---|---|---|
| 选中 | A | A | A | A | B | B | B |
| CVaR | 6.60 | 8.25 | 9.67 | 10.00 | 10.00 | 10.00 | 10.00 |
表 2 是概率进入模型的第一个入口。β=0.50 时只看中位数附近的后悔,选 A(CVaR 6.60);β 升到 0.70 仍是 A(9.67);临界值在 β=0.75—0.80 之间:β=0.75 时 A 与 B 的 CVaR 都是 10.00,β=0.80 起 B 独占。β=0.99 时模型已经看不到分布,只看最坏那一格,CVaR 退化成最大后悔 10.00,与式 (2) 完全一致。这就是"min-max 后悔 = CVaR(β→1)"的数值证据:不是两套理论,是同一条曲线上的两个点。
表 3 机会约束 P(后悔 ≤ ρ) ≥ 1−α 下的最优区域(α 行、ρ 列;B 期望 24.00 单,A 期望 25.00 单)
| α \ ρ | 10 | 11 | 12 | 13 | 14 | 16 |
|---|---|---|---|---|---|---|
| 0.00 | B | B | B | A | A | A |
| 0.10 | A | A | A | A | A | A |
表 3 是概率的第二个入口,结论更刺眼。α=0(硬约束)时,ρ=12 还能选 B(最坏后悔 10),ρ 一放宽到 13,A 立刻可行;α 只要给到 0.10,整行全部变成 A——因为 A 唯一的深坑在 S4 节假日,而 S4 的概率恰好就是 0.10,一个"例外额度"正好够把它豁免掉。机会约束在偏斜分布下几乎等于没有约束:它按概率给坏世界打折,而打折的那一格正是后悔最大的那一格。

图 6 后悔矩阵(颜色越深后悔越大,蓝框为 min-max 后悔选中的 B 行)
图 6 是 4 情景下拍平后的矩阵。A 的后悔是 0/8/0/13:两个 0 说明它在两个世界里是事后最优,13 说明它在一个世界里输得最惨;B 是 10/0/9/6,最大值只有 10。A 和 B 的差别不在"平均有多好",在"最坏那一格有多深"——A 的均值 25.00 比 B 的 24.00 高 1 单,代价是最坏那一格深了 3 单。这就是本案的交易:用 1 单/日的期望,买 3 单的后悔上限。情景每加一列,每行的最大值只会变大不会变小——后悔界对情景数是单调的,这就是下一张图的起点。

图 7 情景数 K 从 4 增到 32 时最小最大后悔界的均值(带 5%—95% 抽样带)与相对倍数
图 7 回答"情景越多会怎样"。按行均值加随机尖峰生成 K 个情景,每个 K 重复 150 次:K=4 时界的均值 11.28,K=8 时 13.70(×1.21),K=32 时 15.92(×1.41)。增长是对数型的——极值的期望随样本量按 \(\sqrt{2\ln K}\) 走,情景翻倍只让界涨 0.3—0.5 单,但永远不会回落。用显式的 8 情景矩阵(加 S5 补贴战、S6 高温、S7 开学季、S8 竞对退出)核对:后悔界从 10 升到 12,选点仍是 B,但 B 在那 8 个情景里的平均后悔只有 7.38,比界低 4.62 单。界保的从来不是平均值,差距就是保守的价格:情景越多,价格越贵,而买到的仍然是"某一个可能永远不来的世界"。
4.3 前沿、分布与分解

图 8 期望—后悔的帕累托前沿(混合驻点策略,右侧阴影为期望不可行区)
图 8 换个问法:把 \(y\) 放松成"按天轮换的比例"\(p_i\in[0,1]\),后悔界就成了 \(\max_j(\max_{i'}R_{i'j}-\sum_iR_{ij}p_i)\),仍然是线性的,于是可以得到一条连续前沿。前沿在 ρ=10 处的期望是 24.71 单——比纯策略 B 的 24.00 单多 0.71 单,后悔界同样是 10:混合策略用"今天 B、明天 A"的方式白拿了期望。继续放宽:ρ 从 10 到 11 只多换 0.10 单,11 到 13 再换 0.10 单,ρ=13 时顶到 25.00(纯 A)为止。后悔的边际价格约是 10:1——多让 1 单后悔,只换回 0.1 单期望;这也是为什么"再稳一点"和"再搏一点"的争论常常谈不拢:两边换的东西量级差一个数量级。

图 9 选中区域 B 的后悔频率(柱)与三个区域的后悔累计分布(线)
图 9 看分布。B 的后悔只在 0、6、9、10 四个值上取值,累计分布是四级台阶;A 的台阶跨到 13,C 跨到 12。三条 CDF 在 0.9 分位处交叉:分位低于 0.75 时 A 的曲线最靠左(大多数日子后悔更小),分位高于 0.85 时 B 的曲线在最左。这正好把表 2 的临界 β 画了出来——"谁更好"取决于你问的是第几分位。

图 10 各区域后悔的情景分解(堆叠),方框为 min-max 后悔选中的 B
图 10 把每个区域的后悔拆回情景。B 的 10 单里,S1 贡献 10(10)、S3 贡献 9、S4 贡献 6、S2 贡献 0;A 的 13 单几乎全部来自 S4(13 单,占 100%)。后悔的构成决定了它的性质:A 的后悔是"单点灾难"——只要节假日不出现,它一直是赢家;B 的后悔是"分散磨损"——每个情景都差一点,但没有一处塌方。前者适合"我赌明天不是节假日",后者适合"我不知道明天是什么"。
三个具体的误用方式,本案都能给出数字。第一,把"稳"理解成"最坏情况最好":B 的最差单量 20 反而低于 C 的 21,如果目标是"最坏那天别太惨",该选 C 而不是 B。第二,把后悔基准取成平均:一旦用列平均,最小平均后悔与最大期望是同一个解(都选 A),"后悔"这个框架就白引入了。第三,情景集失衡:8 情景里 B 的界从 10 涨到 12,而它在这 8 个情景下的平均后悔只有 7.38——界涨得比实际体验快,这正是"保守"的代数含义。反过来说,min-max 后悔真正擅长的是事后问责:无论明天哪个区域爆单,选 B 的人最多被问一句"你为什么不多押 10 单",而选 A 的人在节假日要被问"你为什么押了 34 单的运力"。这是 KPI 语言,不是收益语言——选哪个准则,本质上是在选"事后向谁解释"。
5 结论
(1)最优驻点:B 老城住宅区,后悔上限 10.0 单。模型 6 变量、5 约束,Gurobi 0.000 s、根节点即定案(0 次分支),全部 40 个模型合计 1.5 s,远低于 60 s 预算。
(2)后悔的基准必须是列最大。\(R_{\max}\ge\max_{i'}R_{i'j}-\sum_iR_{ij}y_i\) 对每个情景展开;基准是常数,所以 min-max 是纯 MILP,不需要任何非线性技巧;用平均做基准会退化成"期望最大",两者是同一个解。
(3)三准则三个答案:期望最大选 A(25.00 单,最坏后悔 13);min-max 后悔选 B(24.00 单,最坏后悔 10);max-min 选 C(最差 21 单,最坏后悔 12)。稳健不等于最坏——B 的最差单量比 C 还低 1 单,它稳的是"差距"而不是"下限"。
(4)概率进模型后,min-max 是极限:CVaR 的临界置信水平在 β=0.75—0.80(β=0.75 时 A、B 的 CVaR 都是 10.00),β→1 时 CVaR 退化为最大后悔;机会约束在偏斜分布下几乎失效,α 只要 0.10 就足以豁免 A 唯一的深坑(S4 概率恰为 0.10)。
(5)情景越多越保守:后悔界 K=4 时 11.28、K=8 时 13.70、K=32 时 15.92,按 \(\sqrt{2\ln K}\) 上升且永不回落;8 情景下 B 的界是 12 而其平均后悔只有 7.38,差出来的 4.62 单就是"买保险"的保费。混合驻点前沿在 ρ=10 处即可做到 24.71 单,比纯 B 多 0.71 单——真正的改进不在换准则,在允许轮换。
参考文献
[1] Gurobi Optimization LLC. Gurobi Optimizer Reference Manual[Z]. 2024.
[2] Kellerer H, Pferschy U, Pisinger D. Knapsack Problems[M]. Berlin: Springer, 2004.
[3] Martello S, Toth P. Knapsack Problems: Algorithms and Computer Implementations[M]. Chichester: John Wiley & Sons, 1990.
[4] 司守奎, 孙玺菁. 数学建模算法与应用[M]. 3 版. 北京: 国防工业出版社, 2021.
复现方式:python batch_094.py;数据与结果见同目录 .csv / .json,图见 figs/

浙公网安备 33010602011771号