يوضّح هذا المثال كيفية استخدام 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لكلا المسارين.