自动发配送单调度算法(优化版)
为了在 PHP 后端服务中设计一个自动发配送单的功能,结合 闪送 ETA 接口(文档:https://open.ishansong.com/joinGuide/354),并综合考虑 用户期望送达时间、天气因子、道路拥堵因子、节假日因子 等多个影响因素,我们可以构建一个更智能、鲁棒的调度算法。
一、系统目标
- 时效性保障:确保订单在用户期望时间内送达。
- 动态调整 ETA:根据天气、路况、节假日等多因子修正预计到达时间。
- 自动派单:满足条件时自动调用闪送接口创建配送单。
- 容错机制:失败重试、人工干预等。
- 用户体验优化:提前预警延迟风险,提升用户满意度。
二、输入参数与数据结构(PHP 模拟)
1. 订单信息 Order
class Order {
public $orderId; // 订单ID
public $pickupAddress; // 取货地址 ['address', 'lat', 'lng']
public $deliveryAddress; // 配送地址 ['address', 'lat', 'lng']
public $deliveryTime; // 用户期望送达时间戳
public $productType; // 'cake' 或 'flower'
public $amount; // 订单金额
}
2. 多因子参数
weatherFactor
:天气影响因子(如雨天+30%,雪天+50%)trafficFactor
:道路拥堵因子(如高峰时段+20%)holidayFactor
:节假日影响因子(如春节+40%,国庆+20%)bufferTime
:平台预留缓冲时间(如10分钟)
三、算法流程设计(PHP 实现)
步骤 1:获取待处理订单
$orders = getPendingOrders(); // 获取所有待派送订单
步骤 2:按优先级排序订单
usort($orders, function($a, $b) {
$timeA = $a->deliveryTime - time();
$timeB = $b->deliveryTime - time();
if ($timeA != $timeB) return $timeA - $timeB;
$weightMap = ['flower' => 2, 'cake' => 1];
$weightA = $weightMap[$a->productType] ?? 0;
$weightB = $weightMap[$b->productType] ?? 0;
if ($weightA != $weightB) return $weightB - $weightA;
return $b->amount - $a->amount;
});
步骤 3:调用闪送 ETA 接口,并结合多因子计算实际 ETA
调用闪送 ETA 接口:
function callShanSongETA($start_lat, $start_lng, $end_lat, $end_lng, $city) {
// 使用 curl 请求闪送 ETA 接口
// 返回预估时间(单位:秒)
}
综合因子修正 ETA:
foreach ($orders as $order) {
$pickup = $order->pickupAddress;
$delivery = $order->deliveryAddress;
$eta = callShanSongETA(
$pickup['lat'], $pickup['lng'],
$delivery['lat'], $delivery['lng'],
'北京市'
);
if (!$eta) {
addToWaitingQueue($order);
continue;
}
// 获取当前天气、交通、节假日因子(可调用第三方API或配置表)
$weatherFactor = getCurrentWeatherFactor(); // 如返回 1.3 表示增加30%
$trafficFactor = getCurrentTrafficFactor(); // 如返回 1.2 表示增加20%
$holidayFactor = isHoliday() ? getHolidayFactor() : 1.0; // 节假日额外增加
// 计算实际 ETA(考虑天气 + 交通 + 节假日)
$adjustedEta = $eta * $weatherFactor * $trafficFactor * $holidayFactor;
$buffer = 600; // 缓冲时间 10 分钟(秒)
if ($adjustedEta <= ($order->deliveryTime - time() - $buffer)) {
dispatchToShanSong($order); // 执行发单操作
} else {
addToWaitingQueue($order); // 不满足时效要求,进入等待队列
}
}
步骤 4:调用闪送接口创建订单(发配送单)
闪送创建订单接口(参考文档):
接口地址:
POST /v1/order/create
function dispatchToShanSong($order) {
$params = [
'pickup_name' => '商家名称',
'pickup_phone' => '13800000000',
'pickup_address' => $order->pickupAddress['address'],
'pickup_lat' => $order->pickupAddress['lat'],
'pickup_lng' => $order->pickupAddress['lng'],
'delivery_name' => '用户姓名',
'delivery_phone' => '13900000000',
'delivery_address' => $order->deliveryAddress['address'],
'delivery_lat' => $order->deliveryAddress['lat'],
'delivery_lng' => $order->deliveryAddress['lng'],
'expect_time' => $order->deliveryTime, // 用户期望送达时间
'goods_type' => $order->productType == 'flower' ? 'FLOWER' : 'CAKE',
'city' => '北京市',
'weight' => 2.0,
'remark' => '请小心轻放',
];
$response = callShanSongCreateOrder($params);
if (isset($response['order_id'])) {
updateOrderStatus($order->orderId, 'dispatched', $response['order_id']);
} else {
addToWaitingQueue($order); // 发单失败进入等待队列
}
}
四、辅助函数与工具方法
function callShanSongCreateOrder($params) {
// 使用 curl 请求闪送创建订单接口
}
function updateOrderStatus($orderId, $status, $thirdPartyId = null) {
// 更新数据库中的订单状态及第三方订单ID
}
function addToWaitingQueue($order) {
// 将订单加入延迟队列或等待重试
}
function getCurrentWeatherFactor() {
// 调用天气 API 获取当前城市天气影响因子
// 示例:下雨返回 1.3,晴天返回 1.0
}
function getCurrentTrafficFactor() {
// 调用地图或交通 API 获取当前拥堵系数
// 示例:高峰时段返回 1.2,正常返回 1.0
}
function isHoliday() {
// 判断是否为节假日(调用节假日 API 或本地配置)
}
function getHolidayFactor() {
// 根据不同节假日返回影响因子(如春节返回 1.4)
}
五、异常与容错机制
异常类型 | 处理方式 |
---|---|
ETA 查询失败 | 进入等待队列,定时重试 |
闪送下单失败 | 进入等待队列,支持手动干预 |
天气/交通/节假日极端情况 | 提前提示用户延时或切换配送方式 |
骑手取消订单 | 触发重新调度逻辑 |
六、扩展建议
- 路径优化:多个顺路订单合并路径,减少空驶。
- 多配送商支持:接入达达、蜂鸟等,提高容灾能力。
- 机器学习预测 ETA:基于历史数据训练模型,提升准确率。
- 订单分组策略:相同区域订单打包派发,提高效率。
- 节假日规则引擎:自定义节假日因子和运营策略。
总结
通过上述 PHP 算法设计,可以实现一个基于 闪送 ETA 接口 的自动发配送单功能,适用于蛋糕与鲜花类同城配送小程序。该系统具备以下特点:
- 结合 天气因子、道路拥堵因子、节假日因子 动态调整 ETA;
- 支持 用户期望送达时间 控制发单时机;
- 实现 自动发单 + 容错机制 + 扩展性强 的调度系统。
完整流程如下:
订单获取 → 排序 → 获取原始 ETA → 加入天气/交通/节假日因子 → 判断是否满足送达时间 → 发单到闪送
↓
失败 → 进入等待队列
该方案可用于微信小程序后台服务,作为核心调度模块使用。
版权属于:大卫科技Blog
本文链接:http://www.iyuu.cn/archives/528/
转载时须注明出处