בדוגמה הזו אנחנו מראים איך משתמשים ב-loadDemands וב-loadLimits כדי לנהל את מגבלות הקיבולת של כלי רכב בבקשה ל-Route Optimization API.
סקירה כללית של המושגים מופיעה במסמך Load demands and limits key concepts.
דוגמה לבקשה
בדוגמה הבאה מוצג תרחיש שבו רכב בודד עם מגבלת משקל צריך לספק שלוש משלוחים במשקלים שונים.
בקשת הדוגמה הזו מכילה את הפרמטרים הבאים שקשורים לטעינה:
-
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) מטפל במשלוחweightKgמס' 50. הערך שלmaxLoadsהוא 50, שהוא מתחת למגבלה הרכה. - הנתיב השני (
vehicleIndex: 1) מטפל במשלוחים של 60 ו-30weightKg. הערך שלmaxLoadsהוא 90, שגם הוא נמוך מהמגבלה הרכה. - אף אחד מהרכבים לא חורג מהמגבלה הרכה, ולכן
routeCostsבשני המסלולים לא מופיע קנסcostPerUnitAboveSoftMax.