במדריך הזה מתארים את loadDemands
ואת loadLimits
, ואת הקשר ביניהם
אחר.
כפי שצוין במגבלות של חלונות זמן איסוף ואספקה,
הודעת OptimizeToursRequest
(REST, gRPC) מכילה מספר
מאפיינים שמציינים מגבלות לבעיה באופטימיזציה. כמה
המאפיינים של OptimizeToursRequest
מייצגים מגבלות טעינה.
לרכבים ולמשלוחים יש תכונות פיזיות שצריך להביא בחשבון כאשר לתכנן מסלול.
- כלי רכב: המאפיין
loadLimits
מציין את העומס המקסימלי לטפל ברכב. הצגת הפרטים של ההודעהVehicle
(REST, gRPC) התיעוד. - משלוחים: המאפיין
loadDemands
מציין את כמות הטעינה הנתונה הצריכה. הצגת הפרטים של ההודעהShipment
(REST, gRPC) התיעוד.
יחד, שני מגבלות אלה מאפשרים לכלי האופטימיזציה להקצות משלוחים לכלי רכב בצורה המתאימה ביותר, קיבולת הצי שלך ודרישות המשלוח.
שאר המסמך הזה עוסק בהרחבה ב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
.
למגבלות של מגבלת טעינה רכה יש כמה שימושים, כמו למשל:
- איזון בין כמות גדולה של כלי רכב לבין המספר המינימלי הדרוש מתי משתלם לעשות זאת
- הבעת העדפה של הנהג לגבי מספר הפריטים שאפשר לקנות בו בנוחות איסוף ומשלוח במסלול נתון
- טעינת כלי רכב מתחת לקיבולת הפיזית המקסימלית שלהם כדי להגביל בלאי להפחית את עלויות התחזוקה
מגבלות על עומסים כבדים וקלים אפשר להשתמש יחד. לדוגמה, קשה מגבלת עומס יכולה לבטא את המשקל המקסימלי של המטען שרכב יכול לשאת בצורה בטוחה או את המספר המקסימלי של פריטים שיתאימו לרכב בו-זמנית, בזמן מגבלת עומס קלים עשויה להיות המשקל המקסימלי או מספר הפריטים שנגבים היכולת של הנהג להתאים את כל הפריטים ברכב.