בדוגמה הזו מוסבר איך להשתמש ב-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 וב-30 המשלוחים שלweightKg. הערך שלmaxLoadsהוא 90, וגם הוא נמוך מהמגבלה הגמישה. - מכיוון שאף אחד מכלי הרכב לא חורג מהמגבלה הגמישה שלו, בשדה
routeCostsשל שני המסלולים לא מוצג קנס מסוגcostPerUnitAboveSoftMax.