يشرح هذا الدليل loadDemands
وloadLimits
وطريقة ارتباطهما
ببعضهما البعض.
كما هو موضّح في قيود فترة الاستلام والتسليم، تحتوي رسالة OptimizeToursRequest
(REST وgRPC) على عدد من السمات التي تحدّد قيودًا على المشكلة التي يتم تحسينها. تمثّل العديد من
سمات OptimizeToursRequest
قيود التحميل.
للمركبات والشحنات خصائص مادية يجب وضعها في الاعتبار عند التخطيط لمسار.
- المركبات: تحدد السمة
loadLimits
الحد الأقصى للحمولة التي يمكن للمركبة التعامل معها. يمكنك الاطّلاع على مستندات (REST وgRPC) الخاصة برسالةVehicle
. - الشحنات: تحدد السمة
loadDemands
مقدار الحِمل الذي تستهلكه شحنة معيّنة. يمكنك الاطّلاع على مستندات (REST وgRPC) الخاصة برسالةShipment
.
يتيح هذان الشرطان معًا للمحسّن إمكانية تعيين الشحنات للمركبات بشكل مناسب بطريقة تناسب قدرة أسطولك ومتطلبات الشحن بشكل أفضل.
تتناول بقية هذا المستند loadLimits
وloadDemands
بالتفصيل.
طلبات التحميل والحدود: الأنواع
أنت تعبِّر عن كل قيد من قيود الطلب على التحميل والحدّ الأقصى من حيث النوع.
يمكنك تقديم مجموعتك الخاصة من أنواع التحميل، مثل الأمثلة التالية:
- الوزن
- الحجم
- القياسات الخطية
- أسماء السلع أو المعدّات التي يتم نقلها
يستخدم هذا الدليل weightKg
كنوع من الأمثلة.
يستخدم كل من Shipment.loadDemands
وVehicle.loadLimits
النوع المؤقت map
للبروتوكولات، مع مفاتيح string
التي تمثل أنواع التحميل.
تستخدم قيم Shipment.loadDemands
رسالة Load
(REST وgRPC).
تحتوي الرسالة Load
على سمة amount
واحدة تمثّل السعة
المطلوبة لإنجاز الشحنة بالنوع المحدّد.
تستخدم قيم Vehicle.loadLimits
رسالة LoadLimit
(REST وgRPC). تتضمّن الرسالة LoadLimit
عدة خصائص، ويمثّل maxLoad
الحدّ الأقصى لسعة حمولة المركبة في النوع المحدّد.
تستهلك السمة loadDemands
للشحن قيمة loadLimits
الخاصة بالمركبة المخصّصة لها فقط إذا كان لدى الاثنين مفاتيح مطابقة من نوع حمولة البيانات. على سبيل المثال، شحنة تشمل
loadDemands
مما يلي:
"loadDemands": {
"weightKg": {
"amount": 50
}
}
يجب توفير 50 وحدة تحميل في النوع weightKg
لإكمال عملية الشحن. مركبة مع loadLimits
مما يلي:
"loadLimits": {
"weightKg": {
"maxLoad": 100
}
}
قد تتمكّن من إكمال الشحنة لأنّ نوع maxLoad
للمركبة في النوع weightKg
أكبر من أو يساوي loadDemands
الخاص بالشحن في النوع weightKg
. في المقابل، إنّ المركبات التي تشمل loadLimits
من:
"loadLimits": {
"equipmentRackStorage": {
"maxLoad": 10
}
}
تكون سعة weightKg
غير محدودة ضمنيًا بسبب عدم توفّر
حد أقصى يبلغ weightKg
، لذلك لا تكون المركبة محدودة
بوزن الطلب على الشحنة.
نقل الحمولة بين الشحنات والمركبات
عندما يتم استلام الشحنات وتسليمها بواسطة المركبات، يتم نقل
loadDemand
الشحنة بين الشحنة والمركبة. يمكنك الاطّلاع على
حِمل المركبات في الرسالة OptimizeToursResponse
(REST،
gRPC)routes.transitions
لمركبة معيّنة. التسلسل هو على النحو
التالي:
- يتم تحديد سعة الحمولة المطلوبة للشحن على أنّها
loadDemand
. - يتم استلام الشحنة بواسطة المركبة المخصصة لها وتزيد قيمة
vehicleLoads
للمركبة بمقدار مبلغloadDemand
للشحن. يتم تمثيل عملية النقل هذه بعلامةvisits.loadDemands
إيجابية في رسالة الردّ. - تُسلِّم المركبة الشحنة وتنخفض قيمة
vehicleLoads
للمركبة بمقدار قيمةloadDemand
للشحنة التي تم تسليمها. يتم تمثيل عملية النقل هذه بعلامة سلبيةvisits.loadDemands
في رسالة الرد.
لا يمكن أن يتجاوز نطاق vehicleLoads
للمركبة loadLimits
المحدَّد في أي وقت على مسارها.
مثال كامل يشمل طلبات التحميل وحدوده
الاطّلاع على مثال لطلب يتضمّن طلبات التحميل والحدود
{ "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 } } } ] } }
يحتوي نموذج الطلب على عدة معلَمات مرتبطة بالتحميل:
- طلب الحمولة في
shipments[0]
هو 50weightKg
. - طلب الحمولة في
shipments[1]
هو 10weightKg
. - طلب الحمولة في
shipments[2]
هو 80weightKg
. - الحد الأقصى لتحميل التطبيقات في "
vehicles[0]
" هو 100weightKg
.
عرض رد على الطلب يتضمّن طلبات التحميل والحدود
{ "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 } } }
تؤثر قيود التحميل المضافة على ترتيب visits
:
- تم استلام "
shipment[0]
". - تم استلام "
shipment[1]
". - تم تسليم
shipment[0]
- تم تسليم
shipment[1]
- تم استلام "
shipment[2]
". - تم تسليم
shipment[2]
يوضّح هذا الطلب أنّه لا يمكن للمركبة إكمال ثلاث شحنات في الوقت نفسه لأنّ إجمالي loadDemands
شحن يتجاوز loadLimits
للمركبة.
يتضمّن كل إدخال في visits
التغيير في حمولة المركبة الناتج عن إكمال Visit
. تمثل قيم التحميل الموجبة تحميل الشحنة بينما
تمثل القيم السالبة تفريغ الشحنة.
يشمل كل إدخال في "transitions
" إجمالي حِمل المركبات خلال
"Transition
". على سبيل المثال، تحمل transitions[2]
، حمولة weightKg
من 60،
يمثل التحميل المجمَّع لكل من shipment[0]
وshipment[1]
.
يتضمن كائنات المقاييس routes[0].metrics
وmetrics.aggregatedRouteMetrics
السمة maxLoads
. قيمة النوع weightKg
هي 80، وهو ما يمثّل الجزء من مسار المركبة الذي نقل shipments[2]
إلى
موقع التسليم.
قيود حدود التحميل الأولي
كما هو الحال مع الفترات الزمنية الموضّحة في القيود المفروضة على فترة الاستلام والتسليم، فإنّ قيود حدود التحميل لها صيغ ثابتة وسلسة. تعبّر السمة maxLoad
لرسالة LoadLimit
عن قيد صارم: يجب ألا تحمل المركبة أبدًا حمولة تتجاوز القيمة maxLoad
في النوع المحدّد. تفرض السمتان softMaxLoad
وcostPerUnitAboveSoftMax
قيدًا بسيطًا،
وتتحمّل كل وحدة تتجاوز softMaxLoad
تكلفة
costPerUnitAboveSoftMax
.
هناك عدة استخدامات لقيود التحميل البسيط، مثل:
- موازنة الشحنات عبر مركبات أكثر من الحد الأدنى اللازم عندما يكون ذلك موفرًا من حيث التكلفة
- مع التعبير عن تفضيل السائق لعدد العناصر التي يمكنه استلامها وتسليمها على مسار معين بشكل مريح
- تحميل المركبات أقل من الحد الأقصى للقدرة المادية للحد من الاستهلاك وتقليل تكاليف الصيانة
يمكن استخدام قيود حدود التحميل الثابت والخفيف معًا. على سبيل المثال، قد يعبر حد التحميل الثابت عن الحد الأقصى لوزن البضائع التي يمكن للمركبة حملها بأمان أو الحد الأقصى لعدد العناصر التي تلائم كل مركبة في المرة الواحدة، بينما قد يكون حد التحميل الناعم هو الحد الأقصى للوزن أو عدد العناصر التي قد تفرض على قدرة السائق على ملاءمة كل شيء في المركبة.