案例 057 电动车没电了

案例 057 电动车没电了

摘要:外卖小哥的电动车标称满电 48 km(实测 36—60 km 都跑过),一个班次 20 单的取送里程合计 109.6 km,按载重折算要耗掉 236.7% 的电——一管电跑不完,必须在半路换电。本文把「哪几单、在第几管电里跑、什么时候换」写成一个 0-1 规划:\(x_{i}\) 选单、\(z_{il}\) 把订单分配到第 \(l\) 管电、\(r_{l}\) 决定该管电末端是否换电,电量沿分段递推(式 2、式 3),并同时受 15% 安全边际、3.5 km 回程余量和 420 min 班次时长三重约束。三种策略对比:不换电硬跑只完成 9 单、净收入 83.7 元;固定「每 5 单换一次」完成 19 单、204.6 元;优化换电时机与位置完成 20 单、211.6 元。换电本身不值钱(一次折价 1.8 元),值钱的是把两次换电插在恰好跑空的那一单之后:固定规则白扔 1 单,优化解一单不剩。

关键词:续航约束;换电路径;电量递推;混合整数规划;外卖配送;灵敏度分析

1 问题提出

1.1 问题是什么

一个午晚高峰连跑的班次,系统推来 20 单,合计取送里程 109.6 km,毛收入 215.2 元。车是 48V/24Ah,满电标称 48 km(满载 12 份时更短);按每公里 2.2% 的电耗折算,20 单要耗 236.7%——两管电都不够,必须换电。换一次电 3 min、绕行 1.2 km,月卡不限次,所以换电次数本身不是成本,次数背后的时间与绕行才是。

每单的里程 \(d_{i}\) 在 3.0—8.0 km、收入 \(w_{i}\) 在 6.5—14.5 元之间,耗电 \(c_{i}\) 随载重(份数 \(q_{i}\))上浮。9 单的送达点 300 m 内有换电柜(柜距 0.1—1.1 km),换电只能在这些单之后顺路完成——这就是「换电位置」的由来:柜不在你需要的地方,而在某一单的旁边。

表 1 八单代表数据(全 20 单见 data_057.csv,耗电按 48 km 满电折算)

订单 区域 \(d_{i}\) /km \(w_{i}\) /元 \(q_{i}\) /份 柜距 /km \(c_{i}\) /% 300 m 有柜
O01 天河 4.00 8.5 2 0.25 8.5 是
O03 越秀 7.25 13.5 4 1.10 15.8 否
O05 海珠 8.00 14.5 5 0.90 17.6 否
O07 海珠 6.50 12.0 3 0.45 14.0 是
O10 海珠 7.00 12.5 4 0.55 15.3 否
O13 海珠 7.50 13.0 4 0.60 16.4 否
O17 海珠 6.80 14.0 5 0.50 15.0 是
O19 越秀 6.20 13.2 4 1.00 13.5 否

1.2 为什么要优化

第一,不换电一定跑不完。一管电扣掉 15% 的保底和 7.3% 的回程,实际只剩 77.7% 可用;20 单要 236.7%,差不多要三管电才够。图 3 里不换电只完成 9 单。

第二,换电时机错了就是白换。电量还剩 60% 就换,等于把 60% 的电倒掉;跑空了才换,又可能停在离柜 800 m 的地方推车。固定规则「每 5 单换一次」不看电量也不看柜的位置,实测比优化解少 1 单。

第三,回程是被忽略的那一段。送完最后一单还得骑 3.5 km 回取餐区(7.3% 的电),漏算这段就是「送到最后一单刚好没电」——本模型把 \(e_{L-1}\ge h\) 写成硬约束。

1.3 Gurobi 如何求解

变量三组:\(x_{i}\in\{0,1\}\) 接不接、\(z_{il}\in\{0,1\}\) 该单放在第 \(l\) 管电、\(r_{l}\in\{0,1\}\) 该管电末端换不换。电量用连续变量 \(u_{l}\)(换电前)与 \(e_{l}\)(换电后)沿管递推,换电那一刻的「复位」用大 M 线性化(式 3)。预处理先把 \(r_{l}\) 锁死:只有柜距合格的订单 \(i\in S\) 落在第 \(l\) 管电里,\(r_{l}\) 才可能是 1,这一条把「位置」写进了约束而不是目标。目标只有两项(式 1):收入减去换电折价。分支定界在 0.1 s 内证到 gap 0;扫参共 70 次求解,总耗时 6 s 级。

2 数学模型

2.1 符号说明

\(I\) 为订单集合(\(|I|=20\)),\(d_{i}\) 为取送里程、\(w_{i}\) 为收入、\(q_{i}\) 为份数、\(\tau_{i}\) 为占用时长(取送 2.5 min 加 20 km/h 骑行);\(l=0,1,\dots,L-1\) 为第 \(l\) 管电(\(L=\kappa+1\));\(u_{l}\) 为该管电跑完时的电量、\(e_{l}\) 为换电后的电量;\(c_{i}\) 为单均耗电、\(c_{s}\) 为换电绕行耗电;\(R\) 为满电续航、\(e_{\min}\) 为安全边际、\(h\) 为回程余量、\(T\) 为班次时长;\(\sigma\) 为换电折价、\(\kappa\) 为换电次数上限;\(S\) 为 300 m 内有柜的订单集合。

2.2 目标函数

\[\max\ Z=\sum_{i\in I}w_{i}x_{i}-\sigma\sum_{l=0}^{L-1}r_{l}\tag{1} \]

收入按单计,换电按次折价 \(\sigma=1.8\) 元(3 min 时间 + 1.2 km 绕行的机会成本)。\(\sigma\) 定得再高也换不来「少换一次」,因为第二管电是硬需求;它真正的作用是把「多余的换电」标价,让固定规则的浪费可量化。

2.3 约束条件

\[c_{i}=\frac{100\,d_{i}}{R}\left(1+0.14\,\frac{q_{i}}{12}\right),\qquad u_{l}=e_{l-1}-\sum_{i\in I}c_{i}z_{il}-c_{s}r_{l}\tag{2} \]

单均耗电与里程成正比、与满电续航成反比,载重按份数线性上浮 14%(空载 55 km、满载 48 km 的两点标定)。每管电从上一管电换完后的电量出发,减去该管电所有订单的耗电和一次绕行。

\[e_{l}=u_{l}+(100-u_{l})\,r_{l}\quad \text{等价于}\quad e_{l}\le u_{l}+100r_{l},\ \ e_{l}\ge u_{l}-100r_{l},\ \ e_{l}\ge 100r_{l}\tag{3} \]

换电即复位到 100%。这是唯一的非线性项,用三条大 M 约束等价替代:\(r_{l}=0\) 时 \(e_{l}=u_{l}\),\(r_{l}=1\) 时 \(e_{l}=100\)。大 M 取 100(电量量纲的上界),不用 1e6。

\[u_{l}\ge e_{\min}y_{l},\qquad e_{L-1}\ge h,\qquad \sum_{i\in I}\tau_{i}x_{i}+\tau_{s}\sum_{l=0}^{L-1}r_{l}\le T\tag{4} \]

安全边际按管生效(空管不受限);最后一管电跑完必须留够 3.5 km 回程;班次时长把订单占用与换电耗时加在一起。这三条是「硬」的:任何一条被违反,现实中就是推车、晚点或白跑。

\[\sum_{l=0}^{L-1}z_{il}=x_{i},\qquad \sum_{i\in I}z_{il}\le |I|\,y_{l},\qquad y_{l}\ge y_{l+1},\qquad r_{l}\le\sum_{i\in S}z_{il},\qquad \sum_{l}r_{l}\le\kappa\tag{5} \]

每单只能落在某一管电里;第 \(l\) 管电有单才算启用,且启用的管电必须连续(不能跳过第 1 管电直接用第 3 管);换电要求该管电里至少有一单在柜旁边;总换电次数不超过 \(\kappa\)。最后一条 \(r_{l}\le\sum_{i\in S}z_{il}\) 是整套模型的关键——它把「能不能换」和「换在哪一单之后」绑成了一件事。

2.4 规模与性质

20 个选单变量、20×3 个分配变量、3 组电量变量,约束约 64 条。规模很小,但结构是「背包 + 分段电量递推 + 位置耦合」,LP 松弛不紧(选单的 0-1 性与大 M 同时存在),靠分支定界在毫秒级收敛。与经典燃料约束 VRP 的差别在于:本模型不排序(同一管电内先后不改变耗电总量),只决定分组与分段点,因此规模从「路径枚举」降到「分组指派」。

3 Gurobi 求解实现

3.1 建模要点

换电位置约束直接写成集合约束,避免求解器去试「在没有柜的订单后换电」这种注定不可行的组合:

has = CS <= 0.15 + 0.85*rho                     # 柜距阈值随覆盖密度变化
allow = has if mode == "opt" else np.zeros(K, bool)
for l in range(L):
    m.addConstr(gp.quicksum(z[i,l] for i in range(K)) <= K*y[l])
    m.addConstr(r[l] <= gp.quicksum(z[i,l] for i in range(K) if allow[i]))
    m.addConstr(u[l] == ep - gp.quicksum(cons[i]*z[i,l] for i in range(K)) - csw*r[l])
    m.addConstr(e[l] <= u[l] + 100*r[l]); m.addConstr(e[l] >= u[l] - 100*r[l])
    m.addConstr(e[l] >= 100*r[l]);       m.addConstr(u[l] >= smin*y[l])

一个实现细节:如果把第 \(l\) 管电的订单数与该管的启用变量写成等式,而启用变量是 0-1,等式立刻退化成「每管电只能装一单」。必须写成「订单数不超过 \(|I|\) 乘启用变量」,把 \(y_{l}\) 当指示而不是计数。这个坑一开始让模型只跑了 3 单。

3.2 求解结果

表 2 三种换电策略的结果($\sigma=1.8$ 元/次,$\kappa=2$,班次 420 min)

策略 完成单量 毛收入 /元 换电次数 绕行 /km 净收入 /元 段末最低电量 /%
不换电硬跑 9 83.7 0 0.0 83.7 15.4
固定 5 单换一次 19 208.2 2 2.4 204.6 15.5
优化时机与位置 20 215.2 2 2.4 211.6 18.5

三行读下来:不换电 9 单 / 83.7 元;固定规则 19 单 / 204.6 元;优化 20 单 / 211.6 元。优化解把 20 单全收了,两次换电、绕行 2.4 km、总里程 109.6 km,段末最低电量 18.5%、回程余量 20.8%。固定规则同样是两次换电,却少 1 单、少 7.0 元——差在「第 5 单和第 10 单」这两个位置是拍脑袋定的。

4 结果分析

图 1 三管电的实际路径:第 1、2 管电末端各换一次电,第 3 管电收工回取餐区

4.1 三管电的路径 图 1 把优化解的三管电画在同一张*面图上:第 1 管电 7 单(实线),送完在 O01 旁边换电;第 2 管电 7 单(虚线),在 O04 旁边换第二次;第 3 管电 6 单(点划线)跑完回取餐区。换电点不在起点也不在终点,而是落在「这一管电刚好跑空、且旁边 300 m 有柜」的那一单之后——这正是优化解与固定规则的全部差别。

图 2 单均耗电与取送里程的气泡图,面积表示该单收入

4.2 耗电画像 图 2 横轴是单均里程、纵轴是单均耗电、气泡面积是收入。两者几乎共线(每公里 2.2%),离散只来自载重:同样 6 km,5 份的那单比 1 份只多耗 0.6 个百分点。不换电方案接得住的 9 单全部落在 6.3—13.5% 的窄带里;被它放弃的 11 单中,1 单单均耗电不到 10%(收入太低、不值当占额度),6 单超过 14%(一管电装不下几单)。瓶颈不是远*,是额度。

图 3 三种换电策略的净收入与完成单量

4.3 三策略对比 图 3 是本例的核心:9 单 / 83.7 元、19 单 / 204.6 元、20 单 / 211.6 元。不换电硬跑受一管电限制,只能收 9 单;一旦允许换电,单量天花板立刻抬到 20,剩下的差别只在「换得值不值」。优化比固定规则多 7.0 元,全部来自多接的那 1 单——同一批订单、同样两次换电,差别只在换电点卡在哪一单之后。

图 4 三种策略的剩余电量曲线:换电把曲线拉回 100%

4.4 电量曲线 图 4 的横轴是累计完成单数、纵轴是剩余电量,三条曲线在 15% 的安全边际线上方集体折断或复位。不换电那条一路降到 15.4% 就停住(再多一单就破线);两条换电曲线在换电处垂直弹回 100%,形成两个锯齿。锯齿的位置就是换电时机:优化解的两个齿落在第 7 单和第 14 单之后,固定规则的齿落在第 5 单和第 10 单之后——前者卡在电量见底的瞬间,后者总有一段电被白白倒掉。

图 5 满电续航对完成单量与段末最低电量的影响

4.5 续航灵敏度 图 5 左轴是完成单量、右轴是段末最低电量。续航从 36 km 提到 60 km,优化解的单量从 1 单调升到 6,在 48 km 附*拐*——这是一条典型的「约束切换」曲线:续航短时电池是瓶颈,续航长时班次时长(420 min)接手成为瓶颈。同一条线上不换电方案只从 7 升到 11 单,斜率更缓,因为它始终被一管电卡着。右轴的最低电量在 15.0—24.1% 之间波动而始终贴着 15%,说明最优解总把电用到见底。

图 6 续航 × 换电柜覆盖密度的净收入热图

4.6 续航 × 柜密度 图 6 是 5×7 热图,行是换电柜覆盖密度 \(\rho\)、列是满电续航。同一列上下五格完全相同(行方向没有任何差别,净收入的变化全部发生在列方向),说明柜密度在本案不构成瓶颈:一个班次只要两次换电、每次只需一座柜,9 单里有柜的比例已经够用。填色沿列方向从 168.6 元升到 211.6 元、在 48 km 处饱和,与图 5 的拐点完全对应。这条结论的价值在于排除:花力气去记更多换电柜,不如把续航从 36 km 提到 48 km。

图 7 班次可用时长对净收入与完成单量的影响(第三维)

4.7 班次时长(第三维) 图 7 左轴净收入、右轴单量,横轴是班次可用时长。从 330 min 放到 430 min,单量从 17 升到 20、净收入从 178.1 元升到 211.6 元,在 410 min 处封顶——再多的时长也换不来单,因为单池只有 20 单。这条曲线与图 5 是一对:续航决定「一管电能跑几单」,班次时长决定「一天能跑几管」,两者共同夹出 20 单这个上界。

图 8 换电次数上限与净收入的前沿,灰色为上界以上的不可达区

4.8 换电次数前沿 图 8 横轴是换电次数上限 \(\kappa\)、纵轴是净收入。\(\kappa=0\) 时 83.7 元(9 单),\(\kappa=1\) 时 154.9 元(15 单),\(\kappa=2\) 时 211.6 元(20 单),\(\kappa=3\) 起完全不动。灰色区是「上界以上」,任何策略都进不去。边际收益断崖式递减:第一次换电买回 6 单,第二次只买回 5 单,第三次一分不值——2 次就是本案的经济上限,与月卡不限次的常识相反。

图 9 单均耗电分布:入选与落选订单的对比

4.9 耗电分布 图 9 按 2 个百分点分组画耗电直方图。不换电方案接的 9 单挤在 10—14% 一档;被放弃的 11 单在两端散开:1 单在 10% 以下(短单收入低),6 单在 14% 以上(长单占额度),中间 4 单与入选订单重叠。这就是背包问题的典型形态:不是「远的不要」,而是「性价比不够的不要」——O05 单均耗电 17.6%、单价 14.5 元,照样入选。

图 10 三种策略的分区毛收入构成

4.10 分区收入构成 图 10 把三种策略的毛收入按天河、越秀、海珠堆叠。不换电只覆盖 天河 附*一片(83.7 元);固定规则铺到三个区(208.2 元);优化解三区都满(215.2 元)。换电买来的不是「更快的车」,而是「更宽的活动半径」:每换一次电,骑手就重新获得 85% 的电量额度,也就重新获得跨区接单的自由。

5 结论

  1. 续航是硬约束,不是成本项。 20 单要 236.7% 的电,一管电只有 85%(扣回程后 77.7%),不换电只能完成 9 单——这与「跑得慢」是两回事,慢可以补,没电只能推车。
  2. 换电次数的边际价值断崖式递减。 第一次换电买回 6 单,第二次 5 单,第三次 0 单;净收入从 83.7 元到 154.9 元再到 211.6 元。2 次是本案的经济上限。
  3. 固定规则的代价可以精确到元。 「每 5 单换一次」与优化解同样是 2 次换电、同样绕行 2.4 km,却少 1 单、少 7.0 元——差别只在换电点选在哪一单之后。
  4. 优化解的结构是「把电用到见底再换」。 段末最低电量 18.5%、结束余量 20.8%,两个数都贴着 15% 与 7.3% 的底线;续航从 36 到 60 km,最优解始终贴线运行。
  5. 柜密度不是本案瓶颈,续航与班次时长才是。 柜密度从 0.15 到 0.75 净收入不变(图 6 行方向全*),而续航的拐点在 48 km、班次时长的拐点在 410 min(图 5、图 7)。要提升单量,先换电池,再谈记柜子。

参考文献

[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:03  小青蛙电气  阅读(3)  评论(0)    收藏  举报