案例 041 先送近的还是先送快超时的:最近优先、EDD 与模型最优的排序准则比较

案例 041 先送近的还是先送快超时的:最近优先、EDD 与模型最优的排序准则比较

摘要:17:30 取齐 5 单,O1 只剩 6 min 到期但距 1.2 km,O2 还有 25 min 但只距 0.4 km,经验派与算法派给出的顺序相反。本文把配送顺序写成位置指派 MILP:\(x_{i,k}\) 定位置、\(z_{i,j,k}\) 定相邻对、\(t_k\) 递推到达时刻,目标为 3.5 元/单的超时罚加 0.6 元/km 的里程成本。三条准则同场比较:最近优先 5.96 km、1 单超时、总代价 7.08 元;EDD 7.11 km、0 超时、4.27 元;模型最优 6.53 km、0 超时、3.92 元。120 个排列全枚举验证 MIP 最优性。给出两个临界:急单余量须 \(\ge 1.78\) 倍直达时间、超时罚须 \(\le 0.34\) 元/单,直觉准则才不会亏。

关键词:外卖配送;排序准则;EDD;超时罚;Gurobi


1 问题提出

1.1 问题是什么

17:30,骑手在珠江新城一家商场取齐 5 单。两单最扎眼:O1 珠江新城西塔,只剩 6 min 到期,距离 1.2 km;O2 体育西小区,还剩 25 min,距离只有 0.4 km。经验派说"先送近的,4 分钟就回来了",算法派说"先送快到期的"。两种说法都只说了一半。

数据见表 1。按 20 km/h 折算 3 min/km,单点直达时间写在最后一列:每一单单送都来得及,最紧的 O1 也有 2.4 min 余量。矛盾全在"串行"上——送 O2 要 1.2 min 路 + 1.0 min 交接,再折向 O1 又要 2.6 min,等到 O1 楼下已是第 6.42 min。

表 1 五单数据(时刻以 17:30 为零点,速度 20 km/h)

订单 送达点 x / km y / km 距商家 / km 剩余时限 / min 直达 / min 停靠 / min 配送费 / 元
O1 珠江新城西塔 1.15 0.34 1.20 6 3.60 1.5 9.5
O2 体育西小区 0.30 0.26 0.40 25 1.19 1.0 6.0
O3 五羊新城 -1.05 1.35 1.71 26 5.13 1.5 8.0
O4 杨箕地铁口 0.65 0.62 0.90 12 2.69 1.0 6.5
O5 猎德大桥北 2.05 1.40 2.48 32 7.45 2.0 9.0

核心问题:5 单的访问顺序有 \(5!=120\) 种。不是"先送谁"的一句话,而是在超时单数、总里程、总收入三者之间选一个兑换率。

图 1 五个送达点的空间结构与三条准则给出的路线

1.2 为什么要优化

  1. 直觉会把最紧的单排到第 3 位:最近优先的路线是 O2 → O4 → O1 → O5 → O3,O1 被推后到第 3 位,6.42 min 才到,晚 0.42 min。
  2. EDD 不误单,但多跑路:路线 O1 → O4 → O2 → O3 → O5,0 超时,里程 7.110 km,比最优多 0.583 km。
  3. 最优解既近又不误:路线 O2 → O1 → O4 → O5 → O3,里程 6.527 km、0 超时,两者兼得——因为它不是"先近"也不是"先急",而是先把近单里最紧的那个解决掉。
  4. 代价差得开:最近优先总代价 7.08 元,模型最优 3.92 元,差 3.17 元(81%)。

图 2 五单的直达时间与剩余时限(气泡=配送费,对角线以下才来得及)

1.3 三条准则怎么算

  • 最近优先(Nearest):每步从当前位置选欧氏距离最小的未送单,同距按时限早者优先,\(O(n^2)\)。
  • EDD(Earliest Due Date):按剩余时限升序,\(O(n\log n)\)。它在单机 \(1\|L_{\max}\) 下最优,但本题的目标是 \(\sum\) 型(超时单数 + 里程),且有顺序相关的行驶时间,EDD 的最优性不再成立。
  • 模型最优(MIP):把位置指派 \(x_{i,k}\)、相邻对 \(z_{i,j,k}\)、到达时刻 \(t_k\) 放进一个 MILP,直接用 Gurobi 求。

三者都在同一套评价函数下打分,保证可比。

2 数学模型

2.1 符号说明

订单 \(i,j\in\{1,\dots,5\}\),位置 \(k\in\{0,\dots,4\}\);\(0\) 号点为商家(17:30 位置),位置 \(-1\) 代表出发点。\(D_i\) 剩余时限,\(s_i\) 停靠交接耗时,\(\tau_{ij}\) 弧上行驶时间(\(=3d_{ij}\)),\(d_{ij}\) 弧长,\(C_i\) 送达时刻,\(u_i\in\{0,1\}\) 是否超时,\(\ell_i\) 超时分钟数。\(\pi=3.5\) 元/单,\(c_k=0.6\) 元/km。

2.2 目标函数

\[\min\; \pi\sum_{i}u_{i} + c_k\sum_{(i,j)}d_{ij}y_{ij} + \varepsilon\sum_{i}\ell_{i} \tag{1} \]

前两项就是题目给的"3.5 元/单 × 超时单数 + 0.6 元/km × 里程",第三项系数 \(\varepsilon=0.01\),只在超时单数与里程都相同时用来挑"晚得更少"的解,量级比前两项小两个数量级,不改变最优解的结构。

2.3 约束条件

位置指派与相邻对:

\[\sum_{k}x_{i,k}=1,\qquad \sum_{i}x_{i,k}=1 \tag{2} \]

\[\sum_{i}z_{i,j,k}=x_{j,k},\qquad \sum_{j}z_{i,j,k}=x_{i,k-1},\qquad \sum_{i,j}z_{i,j,k}=1 \tag{3} \]

时刻递推(\(s_{-1}=0\)):

\[t_{k}=t_{k-1}+\sum_{i,j}\left(s_{i}+\tau_{ij}\right)z_{i,j,k} \tag{4} \]

到达时刻与超时判定(大 M 线性化 \(C_i=\sum_k t_k x_{i,k}\)):

\[v_{i,k}\le M x_{i,k},\quad v_{i,k}\le t_{k},\quad v_{i,k}\ge t_{k}-M(1-x_{i,k}),\quad C_{i}=\sum_{k}v_{i,k} \tag{5} \]

\[C_{i}\le D_{i}+M u_{i},\qquad \ell_{i}\ge C_{i}-D_{i},\qquad \ell_{i}\ge 0 \tag{6} \]

\[x_{i,k},z_{i,j,k},u_{i}\in\{0,1\},\qquad t_{k},v_{i,k},\ell_{i}\ge 0 \tag{7} \]

式 (4) 因为每个位置只有一个前驱、一个后继,\(t_k\) 被唯一定死,同时天然排除了子回路,不必另加 MTZ;式 (5) 用 \(v_{i,k}\) 把"到达时刻 × 是否在该位置"这个乘积线性化,\(C_i\) 才能进 (6);式 (6) 是软超时——\(u_i=1\) 时 \(C_i\) 可以超过 \(D_i\) 任意多,所以任何数据都可行,不会出现"时限太紧就无解"。

2.4 规模与性质

5 单 5 位置,0-1 变量 135 个(\(x\) 25、\(z\) 105、\(u\) 5),约束 150 条,非零 754 个;Gurobi 墙钟 0.021 s、gap 0.0e+00。因为规模小,我把 120 个排列全部枚举了一遍:最优 3.9161 与 MIP 目标 3.9161 完全一致,这既是正确性校验,也顺手给出图 8、图 9 需要的完整解空间。

性质上这是一个带顺序相关准备时间的单机排序问题:里程是"准备时间",超时单数是"惩罚计数"。\(1\|\sum U_j\) 已有 Moore-Hodgson 精确算法,但它假设 \(\tau_{ij}\) 只依赖 \(j\);本题 \(\tau_{ij}\) 依赖前后两单,等价于 \(1|s_{ij}|\sum U_j\),是 NP-难 的,EDD 只是启发式。

3 Gurobi 求解实现

3.1 建模要点

x  = m.addVars(N, N, vtype=GRB.BINARY)          # x[i,k] 订单 i 在位置 k
z  = m.addVars(...)                             # z[i,j,k] 位置 k-1 是 i、位置 k 是 j
m.addConstr(t[k] == t[k-1] + quicksum((s[i] + tau[i,j]) * z[i,j,k]))
m.addConstr(C[i] <= due[i] + M * u[i])          # 软超时:只有 0-1 计数
m.setObjective(3.5 * quicksum(u) + 0.6 * km + 0.01 * quicksum(l))

三个实现细节:其一,位置指派而不是顺序变量,\(x_{i,k}\) 让"第几位"变成显式下标,代价函数里所有 \(t_k\) 都能直接引用;其二,相邻对 \(z_{i,j,k}\) 只用来算里程与推进时刻,由 (3) 三个等式自动保证它是 \(x\) 的乘积,不必再写线性化约束;其三,超时写成"计数 + 软约束",\(u_i\) 只管"有没有晚",晚多晚少交给 \(\ell_i\),这与平台按单罚款的口径一致。

3.2 求解结果

表 2 三条准则的指标对比

准则 访问顺序 超时单数 总里程 / km 总延误 / min 总代价 / 元 净收入 / 元
最近优先 O2 → O4 → O1 → O5 → O3 1 5.963 0.42 7.08 31.92
EDD O1 → O4 → O2 → O3 → O5 0 7.110 0.00 4.27 34.73
模型最优 O2 → O1 → O4 → O5 → O3 0 6.527 0.00 3.92 35.08

模型最优:顺序 O2 → O1 → O4 → O5 → O3,6.527 km、0 超时,总代价 3.92 元、净收入 35.08 元。它比最近优先少 3.17 元(其中超时罚 3.50 元,里程反而省 0.34 元),比 EDD 少 0.35 元(全部是里程,0.583 km)。

图 3 三条准则的总代价分解(超时罚 + 里程成本)

4 结果分析

4.1 结构与过程

图 1 三条线其实只差一个决策:O2 和 O1 谁先。最近优先(虚线)先拐向 0.4 km 的 O2,再回头北上,把 O1 挤到第 3 位;EDD(点划线)直奔 O1,代价是全程多绕 0.58 km;最优(实线)先 O2 再顺势斜插 O1——因为从 O2 到 O1 只有 0.86 km,而从商家直接去 O1 是 1.20 km,"先 O2 再 O1"比"直奔 O1"只多 0.05 km,却让 O2 提前 2.6 min 完成。

图 2 把每个点的紧张程度画在"直达时间—剩余时限"平面上:O1 贴着对角线(余量 2.4 min),O2 高高在上(余量 23.8 min)。这条对角线就是判据:点在线上方越多,越"可以等"。

图 4 是累计里程曲线。三条曲线的总长差别不大(6.53 / 7.11 / 5.96 km),但到达 O1 的时刻差得很远:EDD 第 1 位、最优第 2 位就解决了 O1,最近优先拖到第 3 位,正好越过 6 min 红线。

图 4 三条路线的累计里程与送达时刻(叉=超时送达)

4.2 灵敏度:急单还剩多久才不用管它

图 5 扫 O1 的剩余时限 \(D_1\) 从 3 到 12 min。\(D_1=3\) 时两条线重合成 7.11 元——谁都救不回来,改序也只多跑路;\(D_1\) 抬到 4.5 与 6,最优解先松口(4.27 → 3.92 元),最近优先还卡在原地(7.10、7.08);跨过 \(D_1=6.42\) min,两条线重新并到 3.58 元——最近优先自己就成了最优,右轴阶梯同时从 1 跳到 0。

临界值:最近优先把 O1 排在第 3 位,实际 6.42 min 才到,是直达时间 3.60 min 的 1.78 倍。所以判据不是"剩余时间够不够单送",而是"剩余时间 ≥ 1.78 × 直达时间"——急单的余量要留够接近两倍的单送时间,才排得进"先近后远"的队。

图 5 急单剩余时限对总代价与超时单数的影响

图 6 把时限与距离同时扫(4×5 = 20 个点)。正损失不是一整片红,而是一条斜向的窄带:带左侧 \(D\) 太紧,改序也救不回来(两条准则都晚,只差里程);带右侧 \(D\) 够松,最近优先根本不必救(两条准则同解)。带内才有"改序能救、直觉不救"的空间,本案(星标)正落在带里,最大损失 3.21 元。急单越远,这条带越往右挪——远单要更多的剩余时间才谈得上"救"。

图 6 急单时限与距离的二维灵敏度(色块=最近优先多花的代价)

4.3 第三维:罚率决定谁说了算

图 7 扫超时罚率 \(\pi\)。最近优先的损失是一条直线 \(\pi\cdot\Delta n+c_k\Delta d\),斜率正好是超时单数之差 1;EDD 的损失几乎贴着横轴(只有里程差 0.35 元)。

第二个临界值:两条线在 \(\pi^{*}=0.34\) 元/单处相交。低于这个价,超时几乎不疼,最近优先的短里程反而划算;高于这个价(平台实收 3.5 元/单,是临界值的 10 倍),"先送近的"每单净亏 3.16 元。

图 7 超时罚率对两条直觉准则损失的影响

4.4 解空间与前沿

图 8 把 120 个排列全画在"里程—超时单数"平面上。非支配前沿只有 3 个点:0 超时对应 6.527 km,1 超时对应 5.963 km,2 超时对应 5.911 km。最近优先(叉)就落在前沿上——它是"1 超时"档里最省的一条,问题不在走法,在于它拿 3.50 元换回了 0.564 km;按 0.6 元/km 算,这笔兑换是 0.34 元换 1 单,亏定了。EDD(方)在 0 超时那条线的右侧 0.583 km 处,它选对了"要不要晚",只是没选对"怎么走"。

图 8 里程—超时单数的解空间与非支配前沿(阴影=不可达区)

图 9 的分布更能说明直觉的处境:120 个排列的代价中位数 11.71 元,最好 3.92、最差 16.70;最近优先排第 9 名(前 8%),EDD 第 4 名(前 3%)。两条直觉准则都进了前 10%,却都进不了第 1——这正是"看着差不多、算起来差一截"的典型。

图 9 120 个排列的总代价分布与三条准则的位置

4.5 逐单余量

图 10 把每条准则下"余量占时限的比例"逐单列出(负值即超时)。最近优先只有 O1 一根红柱(0.42 min),其余四单余量最少也有 2.61 min——它的失败不是"全盘皆输",而是"把唯一一个没有余量的单排到了第 3 位";EDD 与最优都是全绿,差别只在柱子的高低(EDD 的余量分布更不均匀)。

图 10 三条准则下逐单的时间余量占时限比例(负值即超时)

5 结论

三条准则在同一组 5 单上给出三个答案:

  1. 最近优先(O2 → O4 → O1 → O5 → O3):5.963 km、1 单超时、总代价 7.08 元、净收入 31.92 元。它输在"只看下一段路,不看这一单还剩几分钟"。
  2. EDD(O1 → O4 → O2 → O3 → O5):7.110 km、0 超时、总代价 4.27 元、净收入 34.73 元。它抓住了主要矛盾(超时),代价是多绕 0.583 km。
  3. 模型最优(O2 → O1 → O4 → O5 → O3):6.527 km、0 超时、总代价 3.92 元、净收入 35.08 元。

什么时候直觉准则够用,两个临界值说清楚了:

  • 时限临界:急单剩余时间 \(\ge 1.78\times\) 直达时间(本案 6.42 min 对 3.60 min)时,最近优先不会误单,只差里程;
  • 罚率临界:超时罚 \(\le 0.34\) 元/单时,"先近后远"的短里程能盖过误单损失。

两条都不满足(本案就是),唯一安全的原则是"先解决余量最薄的那一单",而不是"最近的"或"最急的"。再往前一步:近单与急单重合时(\(\rho=d_i/d_j\) 大且 \(D_i/D_j\) 小),所有准则都会给出同一答案——那才是经验真正管用的场景。


参考文献

[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.

[5] Pinedo M L. Scheduling: Theory, Algorithms, and Systems[M]. 5th ed. Cham: Springer, 2016.

[6] Moore J M. An n job, one machine sequencing algorithm for minimizing the number of late jobs[J]. Management Science, 1968, 15(1): 102-109.


复现方式:python batch.py;数据与结果见同目录 .csv / .json,图见 figs/

posted @ 2026-11-11 18:01  小青蛙电气  阅读(3)  评论(0)    收藏  举报