案例 023 同一家店出 5 单:一次排队带来的合并红利

案例 023 同一家店出 5 单:一次排队带来的合并红利

摘要:体育西一家茶餐厅一次出 5 单,取餐只排一次队(9 min),但送餐点分散、份数 1—2、分装 1.5 min/单。本文建立带聚点的 TSP 模型(商家必访一次且先于所有客户),用 Gurobi 求最优,并用 120 种顺序全枚举校验。结果表明:合并取餐路径 13.63 km、总时长 71.9 min,比分开取的 156.0 min 省 84.0 min(54%);省下的主要是 36 min 重复排队。同店单量从 3 增到 8,单均时长由 16.2 min 降到 10.7 min。

关键词:外卖配送;带聚点 TSP;同店拼单;排队时间;Gurobi


1 问题提出

1.1 问题是什么

体育西一家茶餐厅一次出 5 单,取餐只排一次队(9 min),但送餐点分散在 5 个方向,份数 1—2 份、分装 1.5 min/单、交付 2 min/单。

5 单必须全部取到才能出发(一次排队),排一条从出发点到商家、再送完 5 单回出发点的路径,使总时长最小。

表 1 同店五单

客户 坐标 /km 份数 距商家 /km
K1 (1.9, 1.4) 2 1.64
K2 (2.6, 0.5) 1 2.41
K3 (1.2, 2.6) 1 2.04
K4 (3.1, 2.1) 2 3.22
K5 (0.4, -1.5) 1 2.82

1.2 为什么要优化

  • 排队是固定成本:分开取要排 5 次队(45 min),合并只要 9 min;
  • 但合并要"等齐":5 单必须同时出餐,等餐时间变成了硬等待;
  • 顺序仍值钱:5 个点有 120 种顺序,最短 13.63 km、最长 21.41 km。

1.3 Gurobi 如何求解

带聚点的 TSP:商家 \(s\) 必须恰好访问一次,且先于所有客户。

\[\min\ Z=\sum_{(i,j)\in A}d_{ij}y_{ij}+\tau_q+\tau_p n \tag{1} \]

\[\sum_{j\ne i}y_{ij}=\sum_{j\ne i}y_{ji}=1,\qquad u_s+1\le u_i\ (i\in I) \tag{2} \]

模型 49 个变量、49 条约束,0.00 s 求得最优;120 种顺序全枚举作校验。

2 数学模型

2.1 符号说明

\(V=\{0,s\}\cup I\),0 为出发点、\(s\) 为商家、\(I\) 为 5 个客户;\(d_{ij}\) 为路网距离(直线 × 1.15),\(v=18\) km/h;\(\tau_q=9\) min 为一次排队、\(\tau_p=1.5\) min/单 为分装、\(\tau_s=2\) min/单 为交付;\(u_i\) 为顺序变量。

2.2 目标函数

\[\min\ Z=\sum_{(i,j)\in A}d_{ij}y_{ij}+\tau_q+\tau_p n+\tau_s n \tag{3} \]

2.3 约束条件

每点一进一出:

\[\sum_{j\ne i}y_{ij}=\sum_{j\ne i}y_{ji}=1,\qquad \forall i\in V \tag{4} \]

子回路消除与"先取餐":

\[u_i-u_j+|V|\,y_{ij}\le |V|-1,\qquad u_s+1\le u_i,\qquad \forall i\in I \tag{5} \]

\[y_{ij}\in\{0,1\},\qquad 1\le u_i\le |V| \tag{6} \]

2.4 规模与性质

7 个节点、42 条弧,0-1 变量 42 个、约束 49 条。带聚点 TSP 属 NP-难,但 5 个客户只有 120 种顺序,可全枚举校验;工程上常用的做法是先跑 Clarke-Wright 节约算法得快解、再作 MIPStart。

3 Gurobi 求解实现

3.1 建模要点

for i in range(NN):
    m.addConstr(y.sum(i, "*") == 1); m.addConstr(y.sum("*", i) == 1)
for i in range(1, NN):                    # MTZ 消子回路
    for j in range(1, NN):
        if i != j:
            m.addConstr(u[i] - u[j] + NN * y[i, j] <= NN - 1)
for i in range(2, NN):                    # 商家必须先于所有客户
    m.addConstr(u[1] + 1 <= u[i])

一条实现细节:"先取餐"只用一条 \(u_s+1\le u_i\) 就够,不要写 \(u_s<u_i\) 的严格不等。MIP 里不能出现严格不等式,必须写成整数差至少 1;\(u\) 是连续变量时也成立,因为 \(u_s,u_i\) 在最优解处会被 MTZ 推成整数。

3.2 求解结果

表 2 合并与分开的对比

指标 分开取(5 趟) 合并取(1 趟)
里程 / km 30.29 13.63
骑行 / min 101.0 45.4
排队 / min 45 9
分装 / min 0 7.5
总时长 / min 156.0 71.9

合并省 84.0 min(54%),其中排队省 36 min、空驶省 56 min,代价是多 7.5 min 的分装。

4 结果分析

4.1 空间结构与份数

图 1 里商家在出发点东北 1.1 km,5 个客户散在三个方向:K1、K2 在东南,K3、K4 在东北,K5 在西南。最优路径是"商家 → K1 → K4 → K3 → K2 → K5 → 出发点",先从近处顺时针收一圈、最后单跑西南角。

图 1 合并取餐的配送路径

图 2 用"距商家距离—份数"看这 5 单:K4 最远(3.22 km)且有 2 份,K5 只需 1 份但要绕到西南。份数与距离并不成正比——这就是为什么最优解不按份数排。

图 2 各客户距商家的距离与份数

4.2 省在哪

图 3 把总时长拆开:分开取 156.0 min,减掉 36 min 的重复排队、减掉 56 min 的空驶,得到合并方案。排队是最大的一块:5 趟各排一次,光排队就 45 min。

图 3 分开取与合并取的时长分解

图 4 用累计曲线比较:合并方案在商家处"停一次、跳 5 级",之后一路小步;分开方案要爬 5 次台阶,每次都先回出发点。两条曲线的差距在第二次排队时就定型了。

图 4 两种方式的累计完成单数

4.3 分装与排队的灵敏度

图 5 扫分装时间:0.5 min/单 时总时长 66.9 min、等待占比 17%;3.0 min/单 时涨到 79.4 min、占比 30%。分装每多 0.5 min/单,总时长就多 2.5 min——5 单的线性叠加。

图 5 总时长与等待占比随分装时间的变化

图 6 同时扫分装与排队:横带随分装加深,纵带随排队加深,等值线是标准的"正交网格"——两个参数完全可加,没有交互。星标(1.5, 9)落在中间色带。

图 6 总时长关于分装与排队时间的热图

4.4 单量、前沿与顺序分布

图 7 把同店单量从 3 加到 8:总时长由 48.7 min 升到 86.0 min,而单均时长从 16.2 min 降到 10.7 min。同店单越多,"一次排队"被摊得越薄——这就是拼单的经济学。

图 7 总时长与单均时长随同店单量的变化

图 8 把排队时间从 4 扫到 15 min:总时长从 66.9 升到 77.9 min,顶部灰区是超过 60 min(一节课)的部分。排队超过 -2 min 就送不进一节课的窗口。

图 8 总时长随排队时间的变化

图 9 是 120 种访问顺序的里程分布:均值 18.22 km、最短 13.63 km、最长 21.41 km。最优顺序比均值省 4.59 km(25%),比最差省 7.78 km。

图 9 120 种访问顺序的里程分布

图 10 把每单的时间拆成"骑行分摊 + 分装 + 交付":交付与分装合计固定,骑行是唯一随顺序变的部分。5 单里骑行只占 63%,固定开销占 37%——所以拼单的收益主要来自摊薄固定开销。

图 10 各单的骑行、分装与交付时间构成

5 结论

  1. 同店 5 单、一次排队 9 min 下,合并取餐路径 13.63 km、总时长 71.9 min,比分开取的 156.0 min 省 84.0 min(54%)。
  2. 省钱的主项是排队:5 趟各排一次要 45 min,合并只要 9 min;其次是空驶省 56 min。
  3. 代价是多 7.5 min 的分装,以及"等齐出餐"的硬等待——分装每多 0.5 min/单,总时长多 2.5 min。
  4. 同店单量从 3 加到 8,单均时长由 16.2 min 降到 10.7 min,拼单红利随单量摊薄。
  5. 访问顺序仍值钱:120 种顺序里最优比均值省 4.59 km;"先取餐"用 \(u_s+1\le u_i\) 一条约束即可,不能写严格不等。

参考文献

[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.py;数据与结果见同目录 .csv / .json,图见 figs/

posted @ 2026-11-10 08:33  小青蛙电气  阅读(4)  评论(0)    收藏  举报