Panduan ini menjelaskan loadDemands
dan loadLimits
, serta hubungannya satu sama lain.
Seperti yang disebutkan dalam Batasan Jendela Waktu Pengambilan dan Pengiriman, pesan
OptimizeToursRequest
(REST, gRPC) berisi sejumlah
properti yang menentukan batasan pada masalah yang dioptimalkan. Beberapa properti
OptimizeToursRequest
mewakili batasan pemuatan.
Kendaraan dan pengiriman memiliki properti fisik yang harus dipertimbangkan saat merencanakan rute.
- Kendaraan: Properti
loadLimits
menentukan beban maksimum yang dapat ditangani kendaraan. Lihat dokumentasi pesanVehicle
(REST, gRPC). - Pengiriman: Properti
loadDemands
menentukan jumlah muatan yang digunakan oleh pengiriman tertentu. Lihat dokumentasi pesanShipment
(REST, gRPC).
Bersama-sama, kedua batasan ini memungkinkan pengoptimal menetapkan pengiriman ke kendaraan dengan tepat dengan cara yang paling sesuai dengan kapasitas armada dan permintaan pengiriman Anda.
Bagian selanjutnya dalam dokumen ini membahas loadLimits
dan loadDemands
secara mendetail.
Permintaan dan batas pemuatan: jenis
Anda menyatakan setiap permintaan beban dan batasan batas dalam hal jenis.
Anda dapat memberikan kumpulan jenis pemuatan Anda sendiri, seperti contoh berikut:
- bobot
- volume
- pengukuran linier
- nama item atau peralatan yang sedang diangkut
Panduan ini menggunakan weightKg
sebagai contoh jenis.
Shipment.loadDemands
dan Vehicle.loadLimits
menggunakan jenis Protocol Buffers
map
, dengan kunci string
yang merepresentasikan jenis beban.
Nilai Shipment.loadDemands
menggunakan pesan Load
(REST, gRPC).
Pesan Load
memiliki satu properti amount
yang menunjukkan kapasitas yang diperlukan untuk menyelesaikan pengiriman dalam jenis yang ditentukan.
Nilai Vehicle.loadLimits
menggunakan pesan LoadLimit
(REST,
gRPC). Pesan LoadLimit
memiliki beberapa properti, dengan maxLoad
mewakili kapasitas muatan maksimum kendaraan dalam jenis yang ditentukan.
loadDemands
pengiriman menggunakan loadLimits
kendaraan yang ditetapkan hanya jika keduanya memiliki kunci jenis muatan yang cocok. Misalnya, pengiriman dengan
loadDemands
:
"loadDemands": {
"weightKg": {
"amount": 50
}
}
memerlukan 50 unit muatan dalam jenis weightKg
agar pengiriman selesai. Kendaraan dengan loadLimits
:
"loadLimits": {
"weightKg": {
"maxLoad": 100
}
}
mungkin dapat menyelesaikan pengiriman, karena maxLoad
kendaraan dalam jenis
weightKg
lebih besar dari atau sama dengan loadDemands
pengiriman dalam
jenis weightKg
. Namun, kendaraan dengan loadLimits
:
"loadLimits": {
"equipmentRackStorage": {
"maxLoad": 10
}
}
secara implisit memiliki kapasitas weightKg
tidak terbatas karena tidak adanya batas beban weightKg
, sehingga kendaraan tidak dibatasi oleh permintaan berat pengiriman.
Transfer muatan antara pengiriman dan kendaraan
Saat pengiriman diambil dan diantarkan oleh kendaraan, loadDemand
pengiriman akan ditransfer antara pengiriman dan kendaraan. Anda dapat melihat muatan kendaraan dalam entri pesan OptimizeToursResponse
(REST, gRPC)routes.transitions
untuk kendaraan tertentu. Urutannya adalah sebagai
berikut:
- Kapasitas muatan yang diperlukan ditentukan untuk pengiriman sebagai
loadDemand
. - Pengiriman diambil oleh kendaraan yang ditetapkan dan
vehicleLoads
kendaraan bertambah sebesar jumlahloadDemand
pengiriman. Transfer ini diwakili oleh positifvisits.loadDemands
dalam pesan respons. - Kendaraan mengirimkan kiriman dan
vehicleLoads
kendaraan berkurang sebesar jumlahloadDemand
kiriman yang dikirim. Transfer ini diwakili oleh negatifvisits.loadDemands
dalam pesan respons.
vehicleLoads
kendaraan tidak boleh melebihi loadLimits
yang ditentukan di titik mana pun
di rutenya.
Contoh lengkap dengan permintaan dan batas beban
Lihat contoh permintaan dengan permintaan dan batas beban
{ "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 } } } ] } }
Contoh permintaan berisi beberapa parameter terkait pemuatan:
shipments[0]
memiliki permintaan pemuatan sebesar 50weightKg
.shipments[1]
memiliki permintaan beban 10weightKg
.shipments[2]
memiliki permintaan beban sebesar 80weightKg
.vehicles[0]
memiliki batas muat 100weightKg
.
Melihat respons terhadap permintaan dengan permintaan dan batas beban
{ "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 } } }
Batasan beban yang ditambahkan memengaruhi urutan visits
:
shipment[0]
diambilshipment[1]
diambilshipment[0]
dikirimshipment[1]
dikirimshipment[2]
diambilshipment[2]
dikirim
Pesanan ini menunjukkan bahwa tiga pengiriman tidak dapat diselesaikan oleh kendaraan secara bersamaan karena total loadDemands
melebihi loadLimits
kendaraan.
Setiap entri visits
mencakup perubahan beban kendaraan yang dihasilkan dari
penyelesaian Visit
. Nilai muatan positif mewakili pemuatan pengiriman, sedangkan nilai negatif mewakili pembongkaran pengiriman.
Setiap entri transitions
mencakup total muatan kendaraan selama
Transition
. transitions[2]
, misalnya, memiliki beban weightKg
sebesar 60,
yang merepresentasikan beban gabungan shipment[0]
dan shipment[1]
.
Objek metrik routes[0].metrics
dan metrics.aggregatedRouteMetrics
menyertakan
properti maxLoads
. Nilai untuk jenis weightKg
adalah 80, yang merepresentasikan
bagian rute kendaraan yang mengangkut shipments[2]
ke
lokasi pengirimannya.
Batasan batas beban lunak
Seperti halnya rentang waktu yang dijelaskan dalam Batasan Rentang Waktu Pengambilan dan Pengiriman, batasan batas muatan memiliki varian berat dan ringan. Properti maxLoad
pesan
LoadLimit
menyatakan batasan berat: kendaraan tidak boleh membawa beban yang melebihi nilai maxLoad
dalam jenis yang ditentukan. Properti softMaxLoad
dan costPerUnitAboveSoftMax
menyatakan batasan
ringan, dengan setiap unit yang melebihi softMaxLoad
akan dikenai biaya
costPerUnitAboveSoftMax
.
Batasan batas beban ringan memiliki beberapa kegunaan, seperti:
- menyeimbangkan pengiriman di lebih banyak kendaraan daripada jumlah minimum yang diperlukan jika hal tersebut hemat biaya
- mengekspresikan preferensi pengemudi untuk jumlah item yang dapat mereka ambil dan kirim dengan nyaman di rute tertentu
- memuat kendaraan di bawah kapasitas fisik maksimumnya untuk membatasi keausan dan mengurangi biaya pemeliharaan
Batasan beban keras dan beban lunak dapat digunakan bersama. Misalnya, batas muatan berat dapat menyatakan berat maksimum kargo yang dapat dibawa kendaraan dengan aman atau jumlah maksimum item yang dapat dimuat dalam kendaraan sekaligus, sementara batas muatan ringan dapat berupa berat atau jumlah maksimum item yang akan membebani kemampuan pengemudi untuk memuat semuanya ke dalam kendaraan.