يوضّح هذا المثال كيفية استخدام loadDemands وloadLimits لإدارة قيود سعة المركبة في طلب بيانات من واجهة برمجة التطبيقات Route Optimization API.
للحصول على نظرة عامة كاملة حول المفاهيم، يمكنك الاطّلاع على مستند المفاهيم الأساسية حول طلبات التحميل والحدود.
مثال على الطلب
يوضّح المثال التالي سيناريو يجب فيه أن تنقل مركبة واحدة ذات حد أقصى للوزن ثلاث شحنات بأوزان مختلفة.
يحتوي هذا الطلب النموذجي على المَعلمات التالية ذات الصلة بالتحميل:
shipments[0]مع طلب تحميلamountيبلغ 50weightKg.shipments[1]مع طلب تحميلamountيبلغ 10weightKg-
shipments[2]مع طلب تحميلamountيبلغ 80weightKg -
vehicles[0]مع حدّ تحميل يبلغmaxLoadمن 100weightKg
يمكنك الاطّلاع على مثال على طلب يتضمّن متطلبات التحميل والحدود
{ "populatePolylines": false, "populateTransitionPolylines": false, "model": { "globalStartTime": "2023-01-13T16:00:00Z", "globalEndTime": "2023-01-14T16:00:00Z", "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0, "loadDemands": { "weightKg": { "amount": "50" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 15.0, "loadDemands": { "weightKg": { "amount": "10" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0, "loadDemands": { "weightKg": { "amount": "80" } } } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0, "loadLimits": { "weightKg": { "maxLoad": "100" } } } ] } }
مثال على إجابة
يعرض الردّ المسار المحسّن للمركبة. بما أنّ الحمولة الإجمالية لجميع الشحنات تتجاوز سعة المركبة، ينشئ المحسِّن تسلسلاً لعمليات الاستلام والتسليم لضمان عدم انتهاك loadLimits.
الاطّلاع على ردّ على الطلب يتضمّن متطلبات التحميل والحدود
{ "routes": [ { "vehicleStartTime": "2023-01-13T16:00:00Z", "vehicleEndTime": "2023-01-13T16:43:27Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T16:00:00Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "50" } } }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T16:02:30Z", "detour": "150s", "loadDemands": { "weightKg": { "amount": "10" } } }, { "startTime": "2023-01-13T16:08:55Z", "detour": "150s", "loadDemands": { "weightKg": { "amount": "-50" } } }, { "shipmentIndex": 1, "startTime": "2023-01-13T16:16:37Z", "detour": "343s", "loadDemands": { "weightKg": { "amount": "-10" } } }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T16:27:07Z", "detour": "1627s", "loadDemands": { "weightKg": { "amount": "80" } } }, { "shipmentIndex": 2, "startTime": "2023-01-13T16:36:26Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "-80" } } } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T16:00:00Z", "vehicleLoads": { "weightKg": {} } }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T16:02:30Z", "vehicleLoads": { "weightKg": { "amount": "50" } } }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-13T16:05:00Z", "vehicleLoads": { "weightKg": { "amount": "60" } } }, { "travelDuration": "212s", "travelDistanceMeters": 791, "waitDuration": "0s", "totalDuration": "212s", "startTime": "2023-01-13T16:13:05Z", "vehicleLoads": { "weightKg": { "amount": "10" } } }, { "travelDuration": "380s", "travelDistanceMeters": 1190, "waitDuration": "0s", "totalDuration": "380s", "startTime": "2023-01-13T16:20:47Z", "vehicleLoads": { "weightKg": {} } }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T16:29:37Z", "vehicleLoads": { "weightKg": { "amount": "80" } } }, { "travelDuration": "171s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "171s", "startTime": "2023-01-13T16:40:36Z", "vehicleLoads": { "weightKg": {} } } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "1407s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2607s", "travelDistanceMeters": 4812, "maxLoads": { "weightKg": { "amount": "80" } } }, "routeCosts": { "model.vehicles.cost_per_kilometer": 48.12, "model.vehicles.cost_per_hour": 28.966666666666665 }, "routeTotalCost": 77.086666666666659 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1407s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2607s", "travelDistanceMeters": 4812, "maxLoads": { "weightKg": { "amount": "80" } } }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T16:00:00Z", "latestVehicleEndTime": "2023-01-13T16:43:27Z", "totalCost": 77.086666666666659, "costs": { "model.vehicles.cost_per_hour": 28.966666666666665, "model.vehicles.cost_per_kilometer": 48.12 } } }
بما أنّ إجمالي loadDemands الشحنات الثلاث (50 + 10 + 80 =
140) يتجاوز loadLimits المركبة (100)، لا يمكن للمركبة استلام
جميع الشحنات في الوقت نفسه. يأخذ المحسِّن في الاعتبار فقط المسارات التي لا تكون فيها الشحنتان shipment[0] وshipment[2] في المركبة في الوقت نفسه، لأنّ هاتين الشحنتين تتجاوزان الحد الأقصى لحمولة المركبة عند جمعهما معًا.
يتضمّن المسار visits التالية لعدم تجاوز الحدّ الأقصى لحمولة المركبة:
- تم استلام الطلب من
shipment[0] - تم استلام "
shipment[1]" - تم تسليم "
shipment[0]" - تم تسليم "
shipment[1]" - تم استلام الطلب من
shipment[2] - تم تسليم "
shipment[2]"
تتغيّر حمولة المركبة على طول المسار، ويمكنك الاطّلاع على ذلك في مصفوفة transitions. على سبيل المثال، يعرض transitions[2] حمولة المركبة التي تبلغ 60 weightKg بعد استلام الشحنتَين الأوليَين (50 + 10).
توضّح السمة maxLoads في metrics أنّ الحد الأقصى للحمولة
التي تم نقلها في أي نقطة من المسار كان 80 weightKg، ما يؤكّد أنّ
الحلّ حافظ على الحمولة ضمن الحد الأقصى المسموح به للمركبة وهو 100 weightKg.
حدود التحميل الخفيف
يوضّح المثال التالي كيفية استخدام حد التحميل المرن لتحسين مسار يتضمّن مركبات متعددة. يقسّم الحلّ الشحنات بين المركبتَين لتجنُّب دفع غرامة بسبب تجاوز الحدّ الأقصى المسموح به للحمولة.
مثال على الطلب
يتضمّن هذا الطلب الآن ثلاث شحنات للتسليم فقط ومركبتَين تحملان loadLimits وsoftMaxLoad نفسهما.
المَعلمات الرئيسية لهذا المثال هي:
- تبلغ
loadDemandsالشحنات الثلاث 140weightKg(50- 60 + 30).
- تتوفّر مركبتان بقيمة
softMaxLoadتبلغ "100"weightKgوقيمةcostPerUnitAboveSoftMaxتبلغ 5.0.
مثال على طلب يتضمّن حدًّا أقصى مرنًا للتحميل
{ "populatePolylines": false, "populateTransitionPolylines": false, "model": { "globalStartTime": "2023-01-13T16:00:00Z", "globalEndTime": "2023-01-14T16:00:00Z", "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "loadDemands": { "weightKg": { "amount": "50" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "loadDemands": { "weightKg": { "amount": "60" } } }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "loadDemands": { "weightKg": { "amount": "30" } } } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0, "loadLimits": { "weightKg": { "maxLoad": "150", "softMaxLoad": "100", "costPerUnitAboveSoftMax": 5.0 } } }, { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0, "loadLimits": { "weightKg": { "maxLoad": "150", "softMaxLoad": "100", "costPerUnitAboveSoftMax": 5.0 } } } ] } }
مثال على إجابة
يحتوي الردّ الآن على مسارَين، واحد لكل مركبة. يحدّد المحسِّن أنّ استخدام كلتا المركبتَين أكثر فعالية من حيث التكلفة من استخدام مركبة واحدة وتحمُّل غرامة تجاوز الحدّ المرن.
الاطّلاع على ردّ على الطلب يتضمّن حدًّا أقصى لعدد الطلبات التي يمكن معالجتها
{ "routes": [ { "vehicleStartTime": "2023-01-13T16:00:00Z", "vehicleEndTime": "2023-01-13T16:13:31Z", "visits": [ { "startTime": "2023-01-13T16:03:53Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "-50" } } } ], "transitions": [ { "travelDuration": "233s", "travelDistanceMeters": 794, "waitDuration": "0s", "totalDuration": "233s", "startTime": "2023-01-13T16:00:00Z", "vehicleLoads": { "weightKg": { "amount": "50" } } }, { "travelDuration": "328s", "travelDistanceMeters": 1188, "waitDuration": "0s", "totalDuration": "328s", "startTime": "2023-01-13T16:08:03Z", "vehicleLoads": { "weightKg": {} } } ], "metrics": { "performedShipmentCount": 1, "travelDuration": "561s", "visitDuration": "250s", "totalDuration": "811s", "travelDistanceMeters": 1982, "maxLoads": { "weightKg": { "amount": "50" } } }, "routeCosts": { "model.vehicles.cost_per_kilometer": 19.82, "model.vehicles.cost_per_hour": 9.01 }, "routeTotalCost": 28.83 }, { "vehicleIndex": 1, "vehicleStartTime": "2023-01-13T16:00:00Z", "vehicleEndTime": "2023-01-13T16:21:43Z", "visits": [ { "shipmentIndex": 1, "startTime": "2023-01-13T16:05:54Z", "detour": "0s", "loadDemands": { "weightKg": { "amount": "-60" } } }, { "shipmentIndex": 2, "startTime": "2023-01-13T16:13:52Z", "detour": "473s", "loadDemands": { "weightKg": { "amount": "-30" } } } ], "transitions": [ { "travelDuration": "354s", "travelDistanceMeters": 1196, "waitDuration": "0s", "totalDuration": "354s", "startTime": "2023-01-13T16:00:00Z", "vehicleLoads": { "weightKg": { "amount": "90" } } }, { "travelDuration": "228s", "travelDistanceMeters": 808, "waitDuration": "0s", "totalDuration": "228s", "startTime": "2023-01-13T16:10:04Z", "vehicleLoads": { "weightKg": { "amount": "30" } } }, { "travelDuration": "221s", "travelDistanceMeters": 655, "waitDuration": "0s", "totalDuration": "221s", "startTime": "2023-01-13T16:18:02Z", "vehicleLoads": { "weightKg": {} } } ], "metrics": { "performedShipmentCount": 2, "travelDuration": "803s", "visitDuration": "500s", "totalDuration": "1303s", "travelDistanceMeters": 2659, "maxLoads": { "weightKg": { "amount": "90" } } }, "routeCosts": { "model.vehicles.cost_per_kilometer": 26.59, "model.vehicles.cost_per_hour": 14.48 }, "routeTotalCost": 41.07 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1364s", "visitDuration": "750s", "totalDuration": "2114s", "travelDistanceMeters": 4641, "maxLoads": { "weightKg": { "amount": "90" } } }, "usedVehicleCount": 2, "earliestVehicleStartTime": "2023-01-13T16:00:00Z", "latestVehicleEndTime": "2023-01-13T16:21:43Z", "totalCost": 69.90, "costs": { "model.vehicles.cost_per_kilometer": 46.41, "model.vehicles.cost_per_hour": 23.49 } } }
توضّح الحقول التالية كيفية تقسيم المحسِّن للشحنات بين المركبتين لإبقاء الأحمال أقل من الحد الأقصى المرن البالغ 100 weightKg.
- يتولّى المسار الأول (
vehicleIndex: 0) معالجة الشحنة التي تبلغ حمولتها 50weightKg. قيمةmaxLoadsهي "50"، وهي أقل من الحدّ المرن. - يتعامل المسار الثاني (
vehicleIndex: 1) مع الشحنات التي تبلغ 60 و30weightKg. قيمةmaxLoadsهي "90"، وهي أيضًا أقل من الحدّ المرن. - بما أنّ أيًا من المركبتَين لا تتجاوز الحدّ الأقصى المرن، لا تظهر أي غرامة
costPerUnitAboveSoftMaxفيrouteCostsلكلا المسارَين.