案例 156 商圈禁停区:合法化只花 0.94 元,违停要赔 18.0 元
案例 156 商圈禁停区:合法化只花 0.94 元,违停要赔 18.0 元
摘要:体育西路侧整段禁停,违停罚 20 元/次、被查概率 30%,单次期望 6 元。规则给的出路是"去合法停靠点",代价是多走 150 m(2 min、0.40 元)。本文把 8 个取餐商家、3 个合法停靠点建成选址-指派混合整数模型:\(y_j\) 决定启用哪个停靠点,\(z_{ij}\) 决定商家由谁服务,\(u_i=1-\sum_j z_{ij}\) 表示只能违停。求解结果:全违停每趟 18.00 元;按题面上限 2 个停靠点,有 2 个商家覆盖不到、每趟 5.23 元;放宽到 3 个全开,每趟只要 0.94 元。合法化的价格是 17.06 元/趟,而"限 2 个"这个上限本身每趟要多付 4.28 元——真正的浪费不在违停,在那条拍脑袋的选址上限。临界被查概率只有 1.1%,现实是 30%,差 28 倍。
关键词:选址-指派;禁停区;期望违停成本;覆盖半径;边际价值
1 问题提出
1.1 问题是什么
体育西路两侧划为禁停区,交警与城管联合巡查,违停一次罚 20 元。骑手一趟要跑 3 个取餐点,若每个都停在商家门口,被查就是 20 元;若停到合法停靠点,人要走过去、再走回来。商圈范围 200 m \(\times\) 300 m,3 个合法停靠点的位置与 8 个商家的坐标见表 1、图 1。
表 1 8 个商家与 3 个停靠点的坐标(单位:m)
| 商家 | 坐标 | 单量 | 商家 | 坐标 | 单量 |
|---|---|---|---|---|---|
| M1 | (88, 40) | 3 | M5 | (86, 160) | 4 |
| M2 | (112, 68) | 5 | M6 | (114, 190) | 7 |
| M3 | (92, 96) | 2 | M7 | (90, 222) | 3 |
| M4 | (110, 128) | 6 | M8 | (112, 258) | 5 |
| 停靠点 A | (24, 44) | — | 停靠点 B | (176, 132) | — |
| 停靠点 C | (30, 250) | — | 步行速度 | 75 m/min | — |
距离用曼哈顿距离乘 1.2 的街区绕行系数,单次停靠的步行成本为 \(\rho d_{ij}/v\),\(\rho=0.2\) 元/min。24 个"商家—停靠点"对里,只有 9 对在 150 m 步行上限内,其余 15 对视为走不到。
1.2 为什么要优化
- 违停的钱是"或有"的,走路的钱是"确定"的。人脑对 30% 的罚款不敏感,对"多走 150 m"却非常敏感,于是系统性地高估违停的便利、低估它的期望成本。
- 停靠点不是想开就开。商圈只有 3 个合法位,谁服务哪几家、开几个,是一个带覆盖约束的选址-指派问题,凭"就近"直觉排出来的方案会漏掉整片商家。
- 上限会变成隐藏成本。"最多用 2 个"看起来是管理约束,实际上把 2 个商家推给了违停,每趟多付 4.28 元——这笔钱不出现在任何一张罚单上。
1.3 Gurobi 如何求解
模型是纯 0-1 的选址-指派:3 个 \(y_j\)、9 个 \(z_{ij}\)、8 个 \(u_i\),共 20 个变量、18 条约束。规模小到根节点即可闭合,因此可以把"改上限、改概率、改罚款"都做成重解:\(K=0\ldots3\) 四次、概率扫描 14 点 \(\times\) 3 档罚款、\(K\) 家族 14 点 \(\times\) 4、帕累托 7 个子集,共 109 次求解,全部在 2 s 内跑完。
2 数学模型
2.1 符号说明
| 符号 | 含义 | 取值 |
|---|---|---|
| \(i\in I\) | 取餐商家,\(|I|=8\) | M1—M8 |
| \(j\in J\) | 合法停靠点,\(|J|=3\) | A、B、C |
| \(d_{ij}\) | 商家 \(i\) 到停靠点 \(j\) 的步行距离 | 82—144 m |
| \(v,\ \rho\) | 步行速度、时间价值 | 75 m/min、0.2 元/min |
| \(F,\ p\) | 违停罚款、被查概率 | 20 元、30% |
| \(s_i\) | 商家 \(i\) 的巡逻强度系数,\(\bar s=1\) | 0.7—1.3 |
| \(y_j\) | 是否启用停靠点 \(j\) | \(\{0,1\}\) |
| \(z_{ij}\) | 商家 \(i\) 是否由停靠点 \(j\) 服务 | \(\{0,1\}\) |
| \(u_i\) | 商家 \(i\) 是否只能违停 | \(\{0,1\}\) |
| \(K\) | 停靠点启用上限 | 题面 2 |
2.2 目标函数
一次停靠若走合法,成本只有步行时间;若违停,成本是罚款的期望。目标把两者放在同一把尺子上:
代入本案,左侧系数落在 0.22—0.38 元之间,右侧是 6 元(\(s_i=1\) 时):
两者相差约 16 倍。式 (2) 是本题的全部结论:只要违停被查概率超过 \(\rho d/(Fv)\),合法停靠就严格占优,而这个门槛只有 1.1%。
2.3 约束条件
每个商家必须"有着落"——要么指派给某个已启用的停靠点,要么违停:
指派必须门控在启用的停靠点上(\(z_{ij}\le y_j\) 是本题的关键线性化,少了它模型会"用不存在的停靠点"):
停靠点数量与步行可达性:
式 (5) 的后半句不是"优化",是"物理上做不到":走 150 m 要 2.0 min,取餐早凉了。正是这条硬约束,让"限 2 个"变成"必须违停"。
2.4 规模与性质
20 个 0-1 变量、18 条约束,是典型的设施选址-指派(facility location-assignment)结构。\(z\) 与 \(u\) 在给定 \(y\) 后各自独立,模型等价于"枚举 \(2^{3}=8\) 个子集、每个子集解一次指派",所以 \(Z(K)\) 关于 \(K\) 单调不增且边际递减——图 8 与图 10 会验证这一点。\(u_i\) 的系数 \(Fps_i\) 是本模型的"罚金价格",它随 \(p\) 线性变化,构成第 4.5 节的灵敏度主轴。
3 Gurobi 求解实现
3.1 建模要点
y = m.addVars(NB, vtype=GRB.BINARY) # 是否启用停靠点
u = m.addVars(NM, vtype=GRB.BINARY) # 只能违停
z = {(i, j): m.addVar(vtype=GRB.BINARY)
for i in range(NM) for j in range(NB) if D[i, j] <= R_COV} # 只建可达的弧
m.addConstr(gp.quicksum(y[j] for j in range(NB)) <= K)
for i in range(NM):
m.addConstr(gp.quicksum(z[i, j] for j in range(NB) if (i, j) in z) + u[i] == 1)
for (i, j), v in z.items():
m.addConstr(v <= y[j]) # 门控:没开点就不能指派
m.setObjective(gp.quicksum(RHO * D[i, j] / V * z[i, j] for (i, j) in z)
+ gp.quicksum(FINE * p * s[i] * u[i] for i in range(NM)), GRB.MINIMIZE)
一个实现细节:\(z\) 只为 \(d_{ij}\le150\) 的对建变量,超限的对根本不进模型,而不是加大 \(M\) 去"惩罚"。这样 15 条不可达弧从变量层面消失,模型规模从 35 降到 20,也让"覆盖不全"这件事在结果里直接表现为 \(u_i=1\),不用回头查解。
3.2 求解结果
表 2 停靠点上限对成本的影响(8 次停靠合计 / 每趟折算)
| 上限 \(K\) | 启用 | 违停商家 | 步行成本 / 元 | 违停期望 / 元 | 合计 / 8 次 | 每趟 / 元 |
|---|---|---|---|---|---|---|
| 0 | — | 8 | 0.00 | 48.00 | 48.00 | 18.00 |
| 1 | B | 4 | 1.37 | 24.00 | 25.37 | 9.51 |
| 2 | B、C | 2 | 1.94 | 12.00 | 13.94 | 5.23 |
| 3 | A、B、C | 0 | 2.52 | 0.00 | 2.52 | 0.94 |
题面上限 \(K=2\) 的最优解是启用 B、C,2 个商家(M1、M2)没有任何可达停靠点,只能违停。三个方案每趟分别是 18.00 / 5.23 / 0.94 元。
4 结果分析
4.1 结构:3 个点管 8 家店

图 1 商圈平面:8 个取餐商家、3 个合法停靠点与最优指派
图 1 是模型的全部输入。体育西路(中间虚线带)两侧的 8 个商家几乎都贴着禁停线排布,3 个合法停靠点都退到街区纵深:A 在西北角、B 在东侧中段、C 在西南角。**最优指派(点线)呈现明显的"就近分区":北段归 A、中段归 B、南段归 C**,没有任何一个商家被跨区指派——这也是选址-指派问题在小规模下的典型形态,一旦 $d_{ij}$ 满足三角不等式,最优解自然分块。 ### 4.2 散点:合法与违停之间是一道断层
图 2 步行距离与单次停靠成本(气泡=单量),红线为违停期望
图 2 把 9 个可达对的步行成本铺开:最便宜的 0.22 元(82 m),最贵的 0.38 元(144 m)。**全部落在 0.38 元这条线以下,而违停的红线在 6 元——中间空了 16 倍的距离。**这道断层解释了为什么模型"必然选合法":不是模型偏爱合规,是数字差得太远。横轴原点那个叉号是违停:距离 0、成本 6 元,相当于白走 2250 m。 ### 4.3 方案对比:合法化的价格与上限的价格
图 3 四种停靠方案的每趟期望成本
图 3 的四根柱子是一条完整的"合法化路径":全违停 18.00 元 → 限 1 个 9.51 元 → 限 2 个 5.23 元 → 3 个全开 0.94 元。**从全违停走到全合法,每趟省 17.06 元,代价是每趟多走 6 段路(3 次停靠往返);这笔交易的价格是 0.94 元,回报是 18.00 元。**而题面的"最多 2 个"卡在第三根柱子上:明明只用 0.94 元就能全合法,规则硬要多付 4.28 元。 ### 4.4 时序:一趟 3 次停靠的时间账
图 4 同一趟 3 次停靠的时间分解(违停 vs 合法)
图 4 把两种做法拆到分钟。违停每站省下"往返步行",但被查时要现场处理(按 10 min、概率 30% 摊成 3.0 min 的期望块)。只算骑行与取餐,违停一趟 10.5 min,比合法 20.7 min 省 10.2 min,折 2.04 元;**把这 9 min 的期望处理时间加回去,违停变成 19.5 min,反而慢 1.2 min**。模型没算这 9 min,是保守口径,算上只会让合法更占优。走路省的 2.04 元对罚款期望 18 元,差 9 倍。 ### 4.5 主灵敏度:合法化是一道陡坡
图 5 被查概率与罚款对每趟成本的影响(右轴为合法化比例)
图 5 横轴是单次停靠被查概率(对数刻度),三条曲线对应罚款 10/20/40 元。曲线单调上升然后**封顶**:概率 0.2% 时一趟只要 0.12 元(没人查,全违停最划算);到 3.5% 已有 100% 的商家转合法;3.5% 全线合法,成本钉在 0.94 元。**封顶值就是"全合法"的步行成本 0.94 元,它是违停的代价上限**:查得再严,一趟也就 0.94 元;查得再松,一趟趋近 0。罚款从 10 元提到 40 元,只是把饱和点从 8.0% 提前到 1.8%。本案 30% 早在平台上,右轴的合法化比例也顶在 100%。 ### 4.6 二维视图:距离矩阵与指派
图 6 8 商家 $\times$ 3 停靠点的步行距离矩阵与最优指派
图 6 是距离矩阵:9 个格子有名有姓,15 个格子写着"超限"(灰底)。**最优指派(蓝框)总是落在同一行里数值最小的几格上**,比如 M4 的 84 m、M8 的 108 m。把每行的最小值挑出来相加,得到 2.52 元——这正是 3 个全开时的步行总成本,也是 LP 松弛的下界:在 $y$ 全开时指派问题没有整数间隙,MILP 与 LP 同值。 ### 4.7 第三维:上限越高,曲线越低
图 7 停靠点上限(0—3)与被查概率的交互
图 7 把 $K$ 作为族参数。概率低时四条曲线都贴着横轴(全违停,罚款期望趋近 0),概率升高后分层拉开:本案 30% 处 $K=0$ 是 18.0 元、$K=1$ 是 9.5 元、$K=2$ 是 5.2 元、$K=3$ 是 0.9 元。**分层间距随 $K$ 递减(8.49 → 4.29 → 4.28 元),是典型的边际收益递减:第一个停靠点救回 4 家,第二、三个各救回 2 家。**右轴的期望违停次数给出同一事实的另一种读法:$K=2$ 时每趟稳定背着 0.75 次违停。4.8 前沿:步行与违停的替代关系

图 8 步行成本—违停成本的帕累托前沿与不可达阴影
图 8 把 8 种停靠点组合画在"步行成本—违停成本"平面上。**它们沿着一条 $x+y\approx$ 常数的斜线排列**:多走路就少违停,但替代率不是 1:1——违停的单价 6 元远高于走路的 0.38 元,替代率是 16:1。真正的最优点(星标)在左下角,等成本线以下那片阴影是"理论上更便宜但物理不可达"的区域:想让总成本低于 0.94 元,只能把某个商家搬到停靠点隔壁。 ### 4.9 分布:一趟到底会被罚几次
图 9 限 2 个停靠点时每趟成本的分布与累计概率
图 9 用二项结构把"运气"摊开:限 2 个停靠点时 2 个商家处于必然违停状态,一趟 3 次停靠里一次都碰不上的概率是 $(1-2/8)^{3}=42%$。分布分三段:不碰(成本 0.97 元)占 42%;违停了但没被查(成本 0—0.65 元)占 37%;**至少被罚一次(成本 20.0—60 元)占 21%**。绿色竖线是 3 个全开的 0.94 元:期望 5.23 元是它的 5.5 倍,而这 5 倍全部由那 21% 的尾巴撑起来;尾巴末端(3 次全违停全被查)要 60 元,是 0.94 元的 64 倍。放宽上限买的是"没有尾巴"。 ### 4.10 分解:钱花在走路还是花在罚款
图 10 每趟成本的构成分解与停靠点的边际节省
图 10 把四根柱子拆成两段。$K=0$ 时全是罚款(18.00 元);$K=3$ 时全是步行(0.94 元)。中间的转折点在 $K=2$:步行 0.73 元、罚款 4.50 元,罚款仍是走路的 6.2 倍。**边际节省的菱形线(右轴)单调下降:8.49、4.29、4.28 元/趟**——第 3 个停靠点仍值 4.28 元,按一天 20 趟算是 86 元/天、一个月 2228 元。这就是"限 2 个"的真实价格。 ## 5 结论 1. 违停的期望成本是 6 元/次,合法停靠的步行成本只有 0.22—0.38 元/次,两者相差 16 倍。**临界被查概率仅 1.1%,而体育西路是 30%,模型不存在"违停更划算"的解。** 2. 全违停每趟 18.00 元,合法化的最优方案每趟 0.94 元,**合法化的价格是 17.06 元/趟,回报 95%**。这笔钱买的不只是钱,还有图 9 里那条消失的长尾。 3. 题面"最多 2 个停靠点"的解是启用 B、C、每趟 5.23 元,2 个商家被迫违停。**放宽到 3 个全开,每趟 0.94 元,边际节省 4.28 元/趟,一个月 2228 元。**上限本身是成本项,而且是唯一一项没被计入任何账的成本。 4. 边际收益递减但始终为正:8.49、4.29、4.28 元/趟。只要"启用"不额外收费,**$K$ 应该放到覆盖全部商家为止,本题就是 3 个**。 5. 落到动作:一趟 3 次停靠全部停在 A/B/C,按图 6 的星标指派走;宁可多走 144 m(0.38 元),也不要为省 0.38 元去赌 6 元。**商圈禁停区的正确读法不是"哪里能停",而是"停错一次等于白干 30 min"。** ## 参考文献[1] Gurobi Optimization LLC. Gurobi Optimizer Reference Manual[Z]. 2024.
[2] Daskin M S. Network and Discrete Location: Models, Algorithms, and Applications[M]. 2nd ed. Hoboken: Wiley, 2013.
[3] 司守奎, 孙玺菁. 数学建模算法与应用[M]. 3 版. 北京: 国防工业出版社, 2021.
[4] 姜启源, 谢金星, 叶俊. 数学模型[M]. 5 版. 北京: 高等教育出版社, 2018.
复现方式:python batch_156.py;数据与结果见同目录 data_156.csv / results_156.json,图见 figs/

浙公网安备 33010602011771号