案例 047 两个平台同时派单:双开冲突与切换成本

案例 047 两个平台同时派单:双开冲突与切换成本

摘要:午高峰 11:30—11:36,美团推 3 单、饿了么推 2 单,5 张单的取送方向交叉、取餐时刻相互咬合,其中 5 对存在方向相反或同时取餐的硬冲突。骑手最多接 3 单、总耗时不超过 75 min,双开要额外付出 4.0 元固定成本。本文把"接哪几家、接哪几张"写成带配对惩罚的 0-1 规划:目标为毛收入减去双开固定成本、冲突罚金与空驶成本,冲突用配对变量 \(y_{ij}\) 线性化。四种策略实测:只接美团净收益 16.62 元、只接饿了么 14.60 元、按利润密度贪心 13.86 元(毛收入最高却最差)、联合优化 21.68 元。联合方案比单平台高 5.06 元(30.4%),比贪心高 7.82 元;而双开成本一旦超过 9.1 元,最优解立刻退回单平台。双开不是多接一单,而是先买一张 4.0 元的门票,再为每次冲突付一次绕行的钱;门票涨到 9.1 元,这门生意就不做了。

关键词:多平台派单;二分匹配;冲突惩罚;双开成本;0-1 规划;切换成本


1 问题提出

1.1 问题是什么

午高峰两部手机同时响。美团(A 组)推 3 单,饿了么(B 组)推 2 单,五张单全部落在 11:30—11:36 这 6 分钟里,取餐点在石牌村、岗顶、体育西、珠江新城、天河南之间打转,取送方向角散布在 6 度到 276 度之间。骑手只有一个人:最多接 3 单,来回总耗时压在 75 min 以内。

表 1 同一午高峰两个平台推送的 5 张单(时间窗 11:30—11:36)

订单 平台 取餐→送达 方向角 ° 取餐 收入 元 耗时 min 空驶 km 冲突数 密度 元/min
01 美团 石牌村→珠江新城 270 11:30 12.0 21 0.9 2 0.57
02 美团 岗顶→天河北 63 11:33 9.0 17 1.1 3 0.53
03 美团 体育西→客村 276 11:35 7.5 19 1.5 2 0.39
04 饿了么 珠江新城→员村 6 11:36 10.5 23 1.2 1 0.46
05 饿了么 天河南→岗顶 90 11:34 6.5 15 0.8 2 0.43

表 1 的"冲突数"是这样数出来的:方向角相差 130 度以上算方向相反,接了就要掉头;取餐时刻相差 3 min 以内、取餐点却相距 2 km 以上算同时取餐,接了必然迟到。两者合计 5 对。

1.2 为什么要优化

第一,毛收入最高的方案往往最差。五张单的密度集中在 0.395—0.571 元/min 之间,按密度贪心会一次抓满 3 单、毛收入 31.5 元;但这三张单互相之间有两处冲突,扣完门票、罚金与绕行只剩 13.86 元。

第二,双开有固定成本。两部手机、两份保证金、两套超时规则,一天的摊销摊到午高峰就是 4.0 元。这笔钱与接几单无关,只与"是否同时开两家"有关,所以它是一张入场券,不是按单计费。

第三,单平台不是保守,而是放弃。只接美团 01、03 净收益 16.62 元,只接饿了么 04、05 净收益 14.60 元;一家 16 元、一家 15 元,说明任何一家都喂不饱这 75 分钟。

1.3 Gurobi 如何求解

五张单、5 个配对变量、一个双开指示变量,规模只有 11 个二进制。Gurobi 的分支定界在 0.05 s 内收敛,MIPGap 设为 \(10^{-9}\)。真正的价值不在求解,而在参数扫描:双开成本扫 7 点、时间预算扫 7 点、成本与罚金 4 行 5 列共 20 点,全部求解墙钟 2 s。

2 数学模型

2.1 符号说明

\(i,j=1,\dots,N\) 为订单,\(p(i)\) 为订单所属平台(美团记 A、饿了么记 B),\(w_{i}\) 为收入,\(t_{i}\) 为耗时,\(d_{i}\) 为从当前位置到取餐点的空驶里程,\(\kappa\) 为每公里空驶成本,\(F\) 为双开固定成本,\(\lambda\) 为每次冲突的罚金,\(e\) 为每对冲突订单的额外绕行里程,\(c_{ij}\in\{0,1\}\) 为冲突标记。决策变量:\(x_{i}\in\{0,1\}\) 表示接单,\(y_{ij}\in\{0,1\}\) 表示第 \(i,j\) 单的冲突同时被触发,\(u\in\{0,1\}\) 表示双开。

2.2 目标函数

净收益把毛收入、入场券、冲突罚金与绕行一起算清:

\[\max\ Z=\sum_{i=1}^{N}\big(w_{i}-\kappa d_{i}\big)x_{i}-F\,u-\sum_{(i,j)\in\mathcal{C}}\big(\lambda+\kappa e\big)y_{ij}\tag{1} \]

其中 \(\mathcal{C}\) 为冲突对集合。式 (1) 的第二项与单量无关,这是双开与"多接一单"最本质的区别:它是一次性投入,所以必须由增量收益来摊销。

2.3 约束条件

冲突是"两单都接才付"的逻辑与,用三条不等式定死:

\[y_{ij}\ge x_{i}+x_{j}-1,\qquad y_{ij}\le x_{i},\qquad y_{ij}\le x_{j},\qquad \forall (i,j)\in\mathcal{C}\tag{2} \]

双开指示同理,只要 A 组与 B 组各有一单被接,\(u\) 就被顶到 1:

\[u\ge x_{i}+x_{j}-1,\qquad \forall i\in A,\ j\in B\tag{3} \]

体力与时间是硬约束:

\[\sum_{i=1}^{N}x_{i}\le 3,\qquad \sum_{i=1}^{N}t_{i}x_{i}\le 75\tag{4} \]

\[x_{i},\,y_{ij},\,u\in\{0,1\}\tag{5} \]

单平台策略不必另建模型,只需加上"另一平台全不接":

\[x_{i}=0,\qquad \forall i:\ p(i)\ne \hat{p}\tag{6} \]

2.4 规模与性质

\(N=5\)、\(|\mathcal{C}|=5\),整数变量 11 个。若把配对项整块删掉,模型退化为一个按密度排序取前缀的背包——这正是贪心策略的适用边界;一旦加入 \(F\) 与冲突项,密度序就不再单调,贪心会在第一处交叉上翻车。式 (1) 的系数矩阵每列最多出现在 3 条约束里,全幺模性被式 (2) 破坏,所以必须走分支定界。

3 Gurobi 求解实现

3.1 建模要点

冲突对只有 5 个,直接枚举比写指示约束更省事:

for k, (i, j) in enumerate(PAIRS):
    m.addConstr(y[k] >= x[i] + x[j] - 1)
    m.addConstr(y[k] <= x[i]); m.addConstr(y[k] <= x[j])
for i, j in XPAIR:                       # A 组 x B 组的笛卡尔积
    m.addConstr(u >= x[i] + x[j] - 1)
m.setObjective(gp.quicksum((wv[i] - KAP*D0[i])*x[i] for i in range(N))
               - fsw*u - gp.quicksum((lam + KAP*EIJ)*y[k] for k in range(len(PAIRS))),
               GRB.MAXIMIZE)

一个实现细节:\(u\) 必须设成二进制而不是连续变量。若放松到 \([0,1]\),在 \(F>0\) 且交叉项约束并存时,\(u\) 仍会被顶到 1,本例结果不变;但当 \(F<0\)(补贴)时松弛解会退化为 \(u=0\) 的伪解,模型的语义就丢了。

3.2 求解结果

表 2 四种策略的毛收入、冲突、空驶与净收益(单位:元 / km / 次)

策略 单量 毛收入 冲突次数 空驶 km 净收益
只接美团(单平台) 2 19.5 0 2.4 16.62
只接饿了么(单平台) 2 17.0 0 2.0 14.60
利润贪心(不看冲突) 3 31.5 2 7.2 13.86
联合优化(本文模型) 3 30.0 0 3.6 21.68

贪心的毛收入 31.5 元是全场最高,净收益 13.86 元却是全场最低——差额 17.6 元全部喂给了 2 次冲突与 7.2 km 空驶。联合优化的毛收入只有 30.0 元,比贪心少 1.5 元,净收益反而多 7.82 元。

4 结果分析

图 1 双平台派单的空间结构与冲突对

4.1 冲突长在地图上 图 1 把五条取送方向画在同一张平面图上,红色虚线是冲突对。01 号与 02 号方向角 270 度对 63 度,一南一北,取餐点却只隔 0.9 km——这是"方向相反"最典型的形态:车头先朝南,再想掉头去北边,单程就多烧 2 km。02 与 04 则是"同时取餐":11:33 在岗顶、11:36 在珠江新城,直线 2.9 km,三分钟内跑不完。冲突不是抽象的配对,是地图上两条箭头打了个叉。

图 2 收益—耗时散点(气泡为空驶里程)

4.2 密度一样,价值不同 图 2 横轴耗时、纵轴收入、气泡是空驶里程。五张单贴着平均密度线 0.477 元/min 附近散开,谁也没比谁高多少;但气泡大小差一倍以上——04 号空驶 1.2 km、01 号只有 0.9 km,02 号只有 1.1 km,却背着两处冲突,绕行比谁都贵。密度只算"车上"的账,空驶与冲突算"车外"的账,只盯密度一定会选错。

图 3 四种策略的毛收入与净收益

4.3 四种策略 图 3 把毛收入与净收益并排。只接美团 16.62 元、只接饿了么 14.60 元,两家只差 2 元;贪心毛收入 31.5 元最高、净收益 13.86 元垫底;联合优化毛收入 30.0 元、净收益 21.68 元。注意两组数:贪心的毛收入比联合高 1.5 元,净收益却低 7.82 元——多接的那点流水,被 17.6 元的双开与冲突开销吃了个干净。这就是"贪心税"。

图 4 按推送时刻展开的累计净收益

4.4 累计视角 图 4 按推送时刻把决策摊开。贪心在 11:30 的第一张单上就先背了 4.0 元门票加两处冲突的账,起点是 -2.9 元,之后每一单都在还债,收在 13.86 元;联合优化在 11:35、11:36 连续两级台阶,从 6.9 元抬到 21.7 元。同一个午高峰,贪心把第一批单的力气全用在填坑上,联合优化把它用在爬坡上。

图 5 双开固定成本的断崖:净收益与单量

4.5 主灵敏度:双开成本 图 5 让 \(F\) 从 0 扫到 12 元。\(F=0\) 时净收益 25.68 元、接 3 单;随 \(F\) 上升,净收益沿斜率 \(-1\) 下滑(每一元入场券都从利润里直接扣走),到 9.1 元处出现断崖:最优解从"美团 2 单 + 饿了么 1 单"跳回"只接美团 2 单",单数从 3 掉到 2,净收益落到 16.62 元。断崖位置就是双开的盈亏平衡点——本例只有 9.1 元,连一小时的手机折旧都盖不住。

图 6 双开成本 × 冲突罚金的净收益热图

4.6 二维:成本与罚金 图 6 是 4 行 5 列的净收益热图。\(F=0\) 与 \(F=4\) 两行是一条横带:无论 \(\lambda\) 从 0 加到 5 元,净收益都锁在 25.7 与 21.7 元——因为这两档双开划算,而最优解本身零冲突,罚金无处可罚。真正的分岔在 \(F\ge8\):\(\lambda=0\) 时骑手会退回单平台并硬吃两处冲突,拿 19.5 元;\(\lambda\ge1.5\) 后冲突有了价,解立刻变干净:\(F=8\) 时退回双开 17.7 元,\(F=12\) 时退回零冲突的两单 16.6 元。两个参数是分层起作用的:\(F\) 决定要不要双开,\(\lambda\) 只在双开不划算时才决定"接多脏的单"。

图 7 时间预算灵敏度:净收益、单量与冲突

4.7 第三维:时间预算 图 7 把 \(T\) 从 40 min 扫到 75 min。\(T\le60\) 时只装得下"01+03"两张单(40 min),净收益卡在 16.62 元;到 65 min 档才容得下 3 单的 "01+03+04"(63 min),曲线一步跳到 21.68 元后走平。冲突次数在整段扫描中一直是 0——联合优化在任何时间预算下都不接冲突单,因为一次冲突的代价(2.5 元罚金加 2.0 km 绕行共 4.9 元)已经超过任何一对订单的增量收益。时间预算买到的是"更多单",不是"更脏的单"。

图 8 空驶—净收益的帕累托前沿与不可行子集

4.8 帕累托前沿 图 8 把 32 个子集全部画出来,横轴空驶、纵轴净收益。可行子集 26 个、不可行 6 个(灰叉,全是 4 单以上的组合,多数同时越过 75 min)。前沿只有 7 个点,从"零空驶零收入"一路抬到 21.68 元。联合优化解(红星)落在前沿上,空驶 3.6 km;贪心解(图中偏右下)用 7.2 km 空驶换回 13.86 元,被前沿严格支配。前沿的斜率就是"每公里空驶值多少钱",本例从原点到最优解这一段约 6.0 元/km,远高于 1.2 元的空驶成本——所以只要时间够,就该把单接满。

图 9 三百个扰动情景下的净收益累计分布

4.9 扰动下的分布 图 9 给每单的收入乘 ±12%、耗时乘 ±8% 的随机扰动,跑 300 个情景,三条曲线是三个固定决策的收益分布。联合优化的 5% 分位 18.3 元,高于贪心的 10.4 元与单平台的 14.1 元;中位数 21.6 元对 16.7 元。三条曲线几乎平行——决策的差距是平移,不是形状,说明结论对参数扰动稳健,不需要靠运气。

图 10 四种策略的净收益结构分解

4.10 结构分解 图 10 把四种策略的净收益拆成毛收入与四项扣减。只接美团几乎没有扣减(冲突 0 次、空驶 2.4 km),净收益只比毛收入少 2.9 元;贪心的四段扣减加起来 17.6 元,其中冲突罚金与绕行合计 9.8 元、门票 4.0 元、基础空驶 3.8 元;联合优化付了 4.0 元门票、0 元罚金、4.3 元空驶。双开的账要这样算:先付门票,再看罚金,最后看空驶——三笔都算完还有剩,才叫真的多赚。

5 结论

  1. 双开的价值是可以精确标价的:本例联合优化净收益 21.68 元,只接一家最好也只有 16.62 元,增量 5.06 元(30.4%);但这个增量全部来自 04 号一张单,一旦它被取消,双开立刻变成负收益。

  2. 双开成本存在断崖点。\(F\) 从 0 涨到 12 元,净收益沿 \(-1\) 斜率下滑,在 9.1 元处跳回单平台解,接单数从 3 掉到 2。把 9.1 元当作"双开值不值"的判定线,比凭感觉决定双开要可靠得多。

  3. 按利润密度贪心是最差的策略。它拿到最高的毛收入 31.5 元,却因为 2 次冲突与 7.2 km 空驶,净收益只剩 13.86 元,比联合优化低 7.82 元。密度的分母里没有冲突,所以密度越高越容易撞上冲突。

  4. 冲突罚金与双开成本作用分层。二维热图里 \(F\) 主导纵向分层、\(\lambda\) 只在 \(F\) 较高(8 元以上)时才影响横向取值;\(F\) 在利润区(0—4 元)时 \(\lambda\) 完全无效。调参时应当先定 \(F\),再定 \(\lambda\)。

  5. 联合优化在所有时间预算下都不接冲突单(冲突次数恒为 0),帕累托前沿的最优点只由"空驶—净收益"的斜率决定。骑手的真实决策规则可以简化为两条:双开成本低于 9.1 元才双开;每公里空驶的边际收益低于 6.0 元就该把这一单接满。


参考文献

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

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