如何在保证取货点必先于对应送货点的约束下按距离排序地点?
如何在保证取货点必先于对应送货点的约束下按距离排序地点?
这确实是个很实际又有点棘手的问题,咱们来掰扯清楚:
首先,你提到的那种极端冲突场景——也就是存在两个订单A和B,A的取货点正好是B的送货点,同时A的送货点又是B的取货点——这种情况确实完全无解。因为要满足A的取货在送货前,就必须让A.pickup出现在A.delivery之前,但这又和B的约束(B.pickup = A.delivery必须出现在B.delivery = A.pickup之前)完全矛盾,两条约束互斥,根本找不到符合要求的排序。
但如果不存在这种完全互斥的订单组合,那还是有机会找到可行解的,不过这时候你原本的“单纯按距离排序”的思路就得调整了——因为约束优先级要高于单纯的距离排序,或者说要把距离排序和约束结合起来考虑,不能再做全局的无约束距离排序。
先看你当前的代码,它的逻辑是提取所有唯一地点后,直接按和第一个订单取货点的直线距离排序,完全没考虑“取货必先于对应送货”的约束,所以肯定会出现违反规则的情况:
interface Order { id: number; pickup: Location; delivery: Location; } interface Location { id: number; latitude: number; longitude: number; } // Function to calculate distance using the Haversine formula function getDistance(loc1: Location, loc2: Location): number { /** Implementation not important here **/ } function getSortedUniqueLocations(orderArray: Order[]): Location[] { if (orderArray.length === 0) return []; const uniqueLocations = new Map<string, Location>(); for (let i = 0; i < orderArray.length; i++) { const order = orderArray[i]; const pickup = order.pickup; const delivery = order.delivery; const pickupKey = `${pickup.latitude},${pickup.longitude}`; const deliveryKey = `${delivery.latitude},${delivery.longitude}`; if (!uniqueLocations.has(pickupKey)) { uniqueLocations.set(pickupKey, pickup); } if (!uniqueLocations.has(deliveryKey)) { uniqueLocations.set(deliveryKey, delivery); } } const locations = Array.from(uniqueLocations.values()); const firstLocation = orderArray[0].pickup; locations.sort((a, b) => getDistance(firstLocation, a) - getDistance(firstLocation, b)); return locations; }
如果要加入约束,这里给你几个可行的思路方向:
- 先明确依赖关系:把每个订单的
pickup和delivery建立一个“前置依赖”——delivery的前置是对应的pickup。所有地点的排序必须满足这个依赖链。 - 调整排序逻辑:不能直接全局排序,而是采用类似“贪心路径规划”的方式:以初始参考点(第一个订单的取货点)为起点,每次从当前可选的地点中选距离最近的那个。这里的“可选地点”指的是:要么是还没处理过的取货点,要么是已经处理过对应取货点的送货点。
- 冲突提前检测:在开始排序前,先检查是否存在那种互相颠倒的订单对,如果有直接返回无解提示,避免做无用功。
总结一下:不是所有场景都无解,但存在明确的冲突场景;你的当前代码完全没考虑约束,需要结合依赖关系和路径规划的思路来改造,单纯的距离排序必须让位于“取货先于送货”的硬约束。
备注:内容来源于stack exchange,提问作者Andyally
相关产品推荐
相关产品推荐

