案例 053 一个骑手能带几单

案例 053 一个骑手能带几单

摘要:午高峰 60 min 内平台连续派下 12 单,骑手同时在手上的单量上限 K 从 1 试到 6。把"装满 K 单才封趟"的派单规则写进模型,每趟的出发时刻由该趟最后一单的到达时刻决定,骑手只能在趟内决定送达次序,于是 K 不再是"越大越好"的上界,而是一个会反噬的参数。以 12 单、总配送费 73.75 元、单均承诺 39 min 为基础,最优上限是 K=3:63.31 元、4 趟、0 单超时;K=1 只有 51.07 元(12 趟空驶),K=6 跌到 -65.92 元(2 趟、67% 超时)。平台默认 K=5 时净收益 20.07 元,改到 K=3 可多赚 43.25 元(215.5%)。收益曲线的拐点出现在 K=3 到 K=4 之间,边际收益由 +1.98 元翻负——多带一单省下的空驶,抵不过整趟压线超时的罚金。

关键词:在途单量上限;封趟派单;趟内排序;超时罚;参数扫描;外卖派单


1 问题提出

1.1 问题是什么

午高峰 11:30—12:40,12 单先后派到同一位骑手手上,第一单 0 min 到、最后一单 60 min 到,间隔约 5.5 min。每单有取餐时长、送达距离、配送费与承诺时刻,平均距离 2.5 km、单均占用 6.9 min、单均配送费 6.15 元。表 1 是完整档案。

平台的规则很硬:在途单量不到 K 就继续派,凑满 K 单才封趟出发;封趟之后这一趟的单必须全部送完才能接下一批。骑手能决定的只有"先送谁、后送谁"。K=1 时每单单独跑,K=6 时两趟拉完,中间差着 10 次往返。

表 1 12 单的派单到达时刻、距离、单均占用、配送费与承诺时刻

订单 区域 距离 km 取餐 min 到达 min 送达占用 min 配送费 元 承诺 min 最优趟次/次序
P01 商圈 2.4 1.5 0.0 6.5 6.04 39.4 1 / 3
P02 写字楼 1.3 1.2 5.5 3.9 5.11 44.3 1 / 2
P03 小区 3.6 2.0 11.0 9.6 7.06 51.2 1 / 1
P04 小区 2.0 1.4 16.5 5.6 5.70 55.7 2 / 2
P05 商圈 4.2 2.2 22.0 11.0 7.57 62.5 2 / 3
P06 写字楼 1.8 1.3 27.5 5.1 5.53 66.6 2 / 1
P07 小区 2.9 1.8 33.0 7.9 6.46 72.7 3 / 3
P08 商圈 1.1 1.0 38.5 3.3 4.94 77.2 3 / 2
P09 写字楼 3.3 2.1 44.0 9.0 6.80 84.0 3 / 1
P10 小区 2.2 1.5 49.5 6.1 5.87 88.8 4 / 3
P11 商圈 3.9 2.0 55.0 10.2 7.31 95.3 4 / 2
P12 写字楼 1.6 1.2 60.5 4.6 5.36 99.5 4 / 1

1.2 为什么要优化

第一,空驶是纯浪费。每趟封趟后要回商圈重新取餐,固定空驶 4.2 min,K=1 时 12 趟就是 50 min、按 0.45 元/min 折 22.7 元;K=6 时只剩 2 趟。

第二,封趟要等。K 越大,第一单等最后一单的时间越长:K=6 时第一单要干等 27.5 min 才发车,而它的承诺只有 38 min,还没出发就已经输在起跑线。

第三,趟内次序不是小事。同样 3 单,先送承诺紧的还是先送近的,超时分钟能差一倍。这是唯一真正属于骑手的决策,也是模型要解的部分。

1.3 Gurobi 如何求解

固定 K 后,趟的划分(按派单到达顺序每 K 单一组)和每趟的出发时刻都由规则决定,剩下的是一条"带截止时间的排序"问题:12 单、最多 6 个次序位,0-1 变量 36 个上下,约束是每单一个位、每位一单。目标里超时按分钟线性计罚(0.8 元/min),另加 2.0 元/单的差评固定罚,用辅助变量 \(T_{i}\) 与 \(V_{i}\) 线性化。单次求解毫秒级;K 扫描 6 点、罚金网格 18 点、承诺扫描 5 点,共 29 次求解,全部 OPTIMAL,墙钟 2 s。

2 数学模型

2.1 符号说明

\(\mathcal{I}\) 为 12 单集合,\(\mathcal{I}_{w}\) 为第 \(w\) 趟的单集,\(n_{w}=|\mathcal{I}_{w}|\);\(f_{i}\) 配送费,\(a_{i}\) 派单到达时刻,\(h_{i}\) 单均送达占用(取餐 + 骑行),\(\bar{d}_{i}\) 承诺时刻,\(r\) 为趟内次序位,\(x_{i,r}\) 为 0-1 指派变量,\(T_{i}\) 为计罚超时,\(V_{i}\) 为是否超时,\(\tau_{w}\) 为封趟出发时刻,\(C_{i}\) 为送达时刻;\(R_{0}\) 为回商圈空驶,\(\gamma\) 为折返系数,\(\lambda\) 为超时罚系数,\(c_{f}\) 为差评罚,\(c_{0}\) 为空驶成本,\(\varphi\) 为在途负荷成本。

2.2 目标函数

\[\max\ Z=\sum_{i\in\mathcal{I}}f_{i}-\lambda\sum_{i}T_{i}-c_{f}\sum_{i}V_{i}-c_{0}R_{0}W-\varphi\sum_{w=1}^{W}(n_{w}-1)^{2}\tag{1} \]

第一项是 12 单的配送费合计(全部必送,拒单率上限见题源),第二项是超时罚,第三项是差评固定罚,第四项是每趟回商圈的空驶成本,第五项是在途负荷成本 \(\varphi(n_{w}-1)^{2}\)——手上单越多,餐越容易凉、汤越容易洒,按单量平方计。

2.3 约束条件

\[\sum_{r=1}^{n_{w}}x_{i,r}=1,\qquad \sum_{i\in\mathcal{I}_{w}}x_{i,r}=1,\qquad x_{i,r}\in\{0,1\}\tag{2} \]

每单恰好占一个次序位,每趟的每个位恰好一单,这就是一个指派矩阵。

\[\tau_{w}=\max_{i\in\mathcal{I}_{w}}a_{i}+R_{0}+\gamma\,(n_{w}-1)^{1.6},\qquad n_{w}=|\mathcal{I}_{w}|\tag{3} \]

封趟时刻取该趟最后一单的到达时刻,再加回商圈空驶与折返项。\(\gamma(n_{w}-1)^{1.6}\) 是超线性的:一趟 2 单只多 0.9 min,一趟 6 单要多 11.8 min,这是"多带单"的第一笔账。

\[C_{i}=\tau_{w(i)}+\sum_{q=1}^{r(i)}\sum_{j\in\mathcal{I}_{w(i)}}h_{j}\,x_{j,q}\tag{4} \]

送达时刻等于出发时刻加前 \(r\) 个位的占用之和,\(r(i)\) 是订单 \(i\) 所在的位次。

\[T_{i}\ \ge\ C_{i}-\bar{d}_{i}-M\,(1-x_{i,r}),\qquad T_{i}\ge 0\tag{5} \]

\[V_{i}\ \ge\ \frac{C_{i}-\bar{d}_{i}}{M}-(1-x_{i,r}),\qquad V_{i}\in\{0,1\}\tag{6} \]

式 (5) 让 \(T_{i}\) 取到该单的真实超时分钟(平台按分钟扣罚,不做封顶),式 (6) 用大 M 判断是否超时,\(V_{i}=1\) 时另计 2.0 元差评罚。两者只在 \(x_{i,r}=1\) 的那个位次上生效,其余位次被 100 的大 M 顶开。

\[W=\left\lceil N/K\right\rceil,\qquad \Delta_{K}=Z(K)-Z(K-1)\tag{7} \]

趟数由上限决定,边际收益 \(\Delta_{K}\) 就是曲线上相邻两点之差——这是本文真正要读的数。

2.4 规模与性质

固定 K 时变量不超过 40 个 0-1 变量、30 条约束,是带截止时间的指派问题。真正的难点不在求解规模,而在K 不是决策变量:它是平台规则,骑手只能在其下做排序。因此 K 扫描得到的是"规则曲线",不是"松弛曲线",曲线才有拐点。

3 Gurobi 求解实现

3.1 建模要点

封趟时刻、折返项都是常数,先在循环外算好再进约束,模型里只剩排序:

start = A[idx].max() + R0 + GAM*(m-1)**1.6
for r in range(m):
    cum = gp.quicksum(H[j]*xs[j,q] for q in range(r+1) for j in idx)
    for i in idx:
        md.addConstr(T[i] + 100*(1-xs[i,r]) >= start + cum - DUE[i])

cum 是"送到第 r 位时累计占用",随 r 递增,于是位次越靠后越容易触发超时;大 M 取 100 而不是 1e6,避免数值病态。所有 K 的求解都判 Status == GRB.OPTIMAL,29 次全部通过。

3.2 求解结果

表 2 上限 K 从 1 到 6:趟数、超时单数、超时分钟、整班跨度与净收益

K 趟数 W 超时单数 超时合计 min 整班跨度 min 净收益 元 边际 元
1 12 0 0.0 69.3 51.07 —
2 6 0 0.0 80.4 61.33 +10.26
3 4 0 0.0 88.3 63.31 +1.98
4 3 1 0.4 99.8 60.94 -2.38
5 3 6 37.6 80.4 20.07 -40.87
6 2 8 138.6 117.6 -65.92 -85.99

K=1 到 K=3 净收益从 51.07 升到 63.31,K 再往上掉到 -65.92。最优 K=3 时 4 趟、0 单超时、超时合计 0.0 min、整班 88 min;默认 K=5 时超时 6 单、合计 37.6 min,净收益只剩 20.07 元。

4 结果分析

图 1 最优化 K=3 时的四趟配送路径与客户分布

4.1 路径结构 图 1 是 K=3 的四趟路径。四趟把 12 个点按派单顺序切成四个扇区,每趟从商圈出发绕一圈回来,单趟 3 单、路线不长。切法是被规则定死的,骑手能改的只有扇区内部的先后——这正是模型里那 30 多个 0-1 变量的全部意义。

图 2 12 单的距离—送达占用关系(气泡为配送费)

4.2 数据全景 图 2 横轴距离、纵轴单均占用、气泡是配送费、颜色是到达时刻。远近与占用近似线性(\(h_i\approx p_i+2.1d_i\)),配送费也随距离涨,所以"远单"既贵也慢,P05(4.2 km)是全场最贵也最慢的一单。K=3 时 12 单全部按时送达,趟内次序对收益没有影响,模型出现多重最优——这正是"小上限把排序问题变简单"的证据;一旦 K 涨到 5,位次立刻决定谁吃罚(图 9)。

图 3 在途上限 K 从 1 到 6 的班次净收益

4.3 六种上限的净收益 图 3 是核心对比。K=1 的 51.07 元是"12 趟空驶"的代价,K=3 的 63.31 元是峰值,K=6 的 -65.92 元说明"两趟拉完"根本不成立。浅蓝是其余上限,灰色最优、红色默认。曲线的形状是"左陡右崩":左边被空驶拖住,右边被超时拖住。

图 4 最优上限与平台默认上限的累计净收益

4.4 累计过程 图 4 把两条曲线摊在时钟上。最优 K=3 在 0—60 min 稳步爬升,默认 K=5 前半段几乎不动(在等凑满 5 单),后半段虽然斜率更陡但已经追不回来。最终最优停在 63.31 元,默认停在 20.07 元。等待不是免费的:省下的空驶,被"发车晚"吃掉了。

图 5 主灵敏度:净收益随 K 先升后降,超时单数同步跳变

4.5 主灵敏度 图 5 左轴净收益、右轴超时单数。收益从 51.07 升到 63.31 再掉到 -65.92,超时单数从 0 跳到 67%,两级台阶正好卡在 K=3 到 K=5 之间。超时单数不是渐变的,是跳变的:趟内位次一多,第 4 位之后几乎必超时。

图 6 K × 超时罚系数 的净收益热图

4.6 二维:K × 罚金 图 6 是 3 行 6 列热图,行是罚金倍数 0.6/1.0/1.4,星标为本案参数。左侧四列(K≤4)三行完全相同,因为这几档方案里根本没人超时,罚金再重也罚不到钱;右侧两列才动:K=5 从 32.5 元掉到 9.2 元,K=6 从 -21.6 元掉到 -110.3 元。罚金只惩罚"已经超时"的方案,它改变的是超时的代价,不是最优 K 的位置——K=3 在三种罚金下都赢。

图 7 默认上限 K=5 下承诺时长对净收益与超时单数的影响

4.7 第三维:把承诺放宽,K=5 能追上吗 图 7 固定默认 K=5,横轴承诺送达时长从 30 扫到 50 min。承诺 30 min 时净收益 -34.5 元(9 单超时),38 min 时 20.1 元,50 min 才爬到 62.1 元(0 单超时)。绿点线是 K=3 的 63.31 元。放宽承诺确实能把 K=5 从 -34.5 元的亏损里救回来,但最多爬到 62.1 元,始终差 K=3 一截——承诺治的是"超时罚",治不了"折返与负荷"这两笔账。

图 8 整班跨度—净收益前沿与整班拉长区

4.8 前沿与整班跨度 图 8 横轴整班跨度、纵轴净收益,右侧灰区是"整班拉长区"(超过 88 min)。K=1 在 69 min 处只拿到 51.1 元,K=6 拖到 118 min 反而只剩 -65.9 元——前沿在这里是"倒 U"而不是单调曲线,说明"多跑"和"多赚"在 K≥4 之后彻底脱钩。

图 9 逐单超时分钟的累计分布(K=3、5、6)

4.9 超时分布 图 9 是逐单超时分钟的累计分布。K=3 是一条贴着纵轴的竖线——12 单无一超时;K=5 有 6 单超时、合计 37.6 min,曲线在 1—8 min 之间抬升;K=6 有 8 单超时、合计 138.6 min,尾部一直拖到 20 min 以上。超时不是均匀分摊的:K=5 之后,一趟里排在第 4、5 位的单几乎注定要吃罚,这就是封趟的代价落在谁头上。

图 10 K 每增 1 单的边际收益与净收益水平

4.10 边际贡献 图 10 是边际收益的 stem。K=1→2 一次拿 +10.26 元(省下 6 趟空驶),K=2→3 只拿 +1.98 元(空驶已省得差不多,折返与负荷开始吃钱),K=3→4 首次转负(-2.38 元),K=4→5 一口气掉 -40.87 元。边际收益的零点就是最优 K 的定义:再加一单,省下的空驶 < 多出的折返 + 超时 + 负荷。

5 结论

  1. 最优在途上限 K=3,净收益 63.31 元;K=1 是 51.07 元、K=6 是 -65.92 元,曲线先升后降,极值唯一。
  2. 平台默认 K=5 时净收益 20.07 元,改到 K=3 多赚 43.25 元(215.5%),同时超时单从 6 单降到 0 单——收益和体验在这一点上不冲突。
  3. 边际收益序列为 +10.26(K=2)、+1.98(K=3)、-85.99(K=5)元。零点出现在 K=3 附近,K=1→3 的累计边际 12.24 元几乎全部来自空驶的节省。
  4. 两笔成本方向相反:空驶按趟数线性下降(每趟 1.89 元),折返按 \((n-1)^{1.6}\)、负荷按 \((n-1)^{2}\) 超线性上升,超时按趟内位次串行累积。前两笔可算,第三笔只能靠排序压。
  5. 罚金只对已超时的方案生效(K=6 在 0.6 倍罚金下 -21.6 元、1.4 倍下 -110.3 元,K≤4 三档罚金下不变)。把 K=5 的承诺从 38 放宽到 50 min,净收益从 20.1 元升到 62.1 元仍追不上 K=3——"上限"是规则,"承诺"是缓冲,两者都改不掉折返这笔硬账。

参考文献

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

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