คู่มือนี้จะอธิบายถึง loadDemands
และ loadLimits
และความเกี่ยวข้องกับกันและกัน
ตามที่ได้กล่าวไว้ในข้อจำกัดช่วงเวลาในการรับสินค้าและการนำส่ง ข้อความ OptimizeToursRequest
(REST, gRPC) มีพร็อพเพอร์ตี้จำนวนมากที่ระบุข้อจำกัดเกี่ยวกับปัญหาที่เพิ่มประสิทธิภาพ พร็อพเพอร์ตี้ OptimizeToursRequest
หลายรายการแสดงถึงข้อจํากัดในการโหลด
ยานพาหนะและการจัดส่งมีคุณสมบัติทางกายภาพที่ต้องนำมาพิจารณาเมื่อวางแผนเส้นทาง
- ยานพาหนะ: พร็อพเพอร์ตี้
loadLimits
ระบุน้ำหนักสูงสุดที่ยานพาหนะรองรับ ดูเอกสารประกอบของข้อความVehicle
(REST, gRPC) - การจัดส่ง: พร็อพเพอร์ตี้
loadDemands
จะระบุจำนวนโหลดที่การจัดส่งหนึ่งๆ ใช้ ดูเอกสารประกอบของข้อความShipment
(REST, gRPC)
เมื่อพิจารณาข้อจำกัดทั้ง 2 ข้อนี้ร่วมกัน เครื่องมือเพิ่มประสิทธิภาพจะมอบหมายการจัดส่งให้กับยานพาหนะได้อย่างเหมาะสมในลักษณะที่สอดคล้องกับความจุของกองยานพาหนะและความต้องการในการจัดส่งมากที่สุด
ส่วนที่เหลือของเอกสารนี้กล่าวถึง 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
ของยานพาหนะที่กำหนดก็ต่อเมื่อสินค้าทั้ง 2 รายการมีคีย์ประเภทน้ำหนักบรรทุกที่ตรงกันเท่านั้น เช่น การจัดส่งที่มี 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]
คำสั่งซื้อนี้แสดงว่ายานพาหนะไม่สามารถดำเนินการจัดส่ง 3 รายการพร้อมกันได้ เนื่องจากยอดรวมของ 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
ข้อจำกัดขีดจำกัดการโหลดแบบซอฟต์โหลดมีประโยชน์หลายอย่าง เช่น
- การสร้างสมดุลระหว่างการขนส่งยานพาหนะมากกว่าจำนวนขั้นต่ำที่จำเป็น เมื่อทำได้คุ้มค่า
- เพื่อบอกจำนวนสิ่งที่คนขับต้องการที่จะไปรับและจัดส่ง บนเส้นทางที่กำหนดได้อย่างสะดวกสบาย
- ยานพาหนะบรรทุกสินค้าต่ำกว่าความจุทางกายภาพสูงสุดเพื่อจำกัดการสึกหรอและ ลดค่าใช้จ่ายในการบำรุงรักษา
สามารถใช้ข้อจำกัดขีดจำกัดการโหลดแบบฮาร์ดและซอฟต์ร่วมกันได้ ตัวอย่างเช่น ขีดจำกัดน้ำหนักบรรทุกอาจระบุถึงน้ำหนักสูงสุดของสินค้าที่พาหนะบรรทุกได้อย่างปลอดภัย หรือจำนวนสูงสุดของสินค้าที่จะใส่ในยานพาหนะได้ 1 ครั้ง ในขณะที่ขีดจำกัดการโหลดแบบเบาๆ อาจเป็นน้ำหนักสูงสุด หรือจำนวนสินค้าที่คิดภาษีจากความสามารถของคนขับที่จะบรรจุทุกอย่างลงในยานพาหนะได้