OptimizeToursRequest
, aşağıdakiler için kısıtlamalar uygular:
- Kargolar (kargoların nasıl gönderileceğini etkiler)
- Araçlar (araç rotalarının hesaplanma şeklini etkiler)
- Dünya genelinde hem araçları hem de gönderileri etkiler.
Bu kılavuzda temel bir kargo kısıtlaması olan zaman aralıklarına odaklanılmıştır.
Zaman aralıkları, gönderim etkinliklerine zaman tabanlı sınırlar belirlemek için OptimizeToursRequest
mesajında (REST, gRPC) sağladığınız bir kısıtlama türüdür. Bu tür kısıtlamalar, gönderimin ne zaman ve nasıl yapılabileceğinin yanı sıra gönderim için araç atamasını da etkiler. Optimizasyon aracı, bu kısıtlamalarla birlikte gönderinin zaman kısıtlamalarını en iyi şekilde karşılayabilen araçlara öncelik verir.
Kargo kısıtlamaları: zaman aralıkları
Teslim alma veya teslimatın ne zaman yapılabileceğini Shipment.VisitRequest
iletiyle aşağıdaki şekilde belirtirsiniz:
- İletideki
timeWindows
özelliğini kullanın (REST, gRPC) TimeWindow
mesajında başlangıç ve bitiş zamanını belirtin (REST, gRPC).
Zaman aralığı kısıtlamaları içeren örnek istek
Buradaki örnekte, her biri kendi teslimat aralığına sahip üç farklı gönderim gösterilmektedir. Bu örnekte, basitlik için yalnızca deliveries
üzerinde zaman aralıkları ayarlanmıştır ancak zaman aralıkları teslim alma işlemleri için de uygulanabilir. Birden fazla zaman aralığı belirtilebilir ancak bu örnekte teslimat başına yalnızca bir aralık kullanılmaktadır VisitRequest
.
Zaman aralıkları içeren örnek bir istek
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T19:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T18:30:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "endTime": "2023-01-13T18:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
Zaman aralığı kısıtlamaları içeren örnek yanıt
Örnek yanıtta, aracın başlangıç ve bitiş zamanı sırasıyla 17:35:50 ve 18:17:24'tür. Bu süreler, istekte belirtilen aracın costPerHour
olarak çalıştırılması için gereken süreyi en aza indirirken tüm zaman aralığı kısıtlamalarını karşılayan optimizasyon programını yansıtır. Başlangıç saati olarak 17:35:50'nin kullanılması,
ziyaretin zaman aralığı başlayana kadar aracın ziyaret yerinde bekleme ihtiyacını ortadan kaldırır. Bu, yanıtta sıfır waitDuration
değerleri olarak görünür.
Zaman aralıkları içeren örnek isteğe verilen yanıtı görme
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:35:50Z", "vehicleEndTime": "2023-01-13T18:17:24Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:35:50Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T17:38:20Z", "detour": "150s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:40:50Z", "detour": "300s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T17:50:09Z", "detour": "0s" }, { "shipmentIndex": 1, "startTime": "2023-01-13T18:00:00Z", "detour": "796s" }, { "startTime": "2023-01-13T18:07:35Z", "detour": "1520s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:35:50Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:38:20Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:40:50Z" }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T17:43:20Z" }, { "travelDuration": "341s", "travelDistanceMeters": 1312, "waitDuration": "0s", "totalDuration": "341s", "startTime": "2023-01-13T17:54:19Z" }, { "travelDuration": "205s", "travelDistanceMeters": 636, "waitDuration": "0s", "totalDuration": "205s", "startTime": "2023-01-13T18:04:10Z" }, { "travelDuration": "339s", "travelDistanceMeters": 1276, "waitDuration": "0s", "totalDuration": "339s", "startTime": "2023-01-13T18:11:45Z" } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "1294s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2494s", "travelDistanceMeters": 4595 }, "routeCosts": { "model.vehicles.cost_per_hour": 27.711111111111112, "model.vehicles.cost_per_kilometer": 45.95 }, "routeTotalCost": 73.661111111111111 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1294s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2494s", "travelDistanceMeters": 4595 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:35:50Z", "latestVehicleEndTime": "2023-01-13T18:17:24Z", "totalCost": 73.661111111111111, "costs": { "model.vehicles.cost_per_hour": 27.711111111111112, "model.vehicles.cost_per_kilometer": 45.95 } } }
Zaman aralıkları, en erken zaman aralığına sahip gönderilerin ilk olarak teslim edilmesi için aracın visits
sırasını belirlemiştir.
shipments[2]
, 17:50'de teslim ediliyorshipments[1]
saat 18:00'de teslim ediliyorshipments[0]
, 18:07'de teslim edildi
Örnek istekte kesin zaman aralığı kısıtlamaları belirtiliyor ve teslimatların bu aralıklar içinde tamamlanması isteniyor. Bir gönderinin VisitRequests
işlemini zaman aralıklarından herhangi birinde tamamlamak mümkün veya uygun maliyetli değilse optimizasyon aracı gönderiyi atlar. Gönderimde penaltyCost
varsa optimizasyon aracı bunu yanıtta bildirilen maliyetlere ekler
penaltyCost
.metrics
Aksi takdirde, OptimizeToursResponse
mesajının skippedMandatoryShipmentCount
özelliği (REST, gRPC) artar.
shipment[1]
penceresini birkaç saat sonraya (18:00'dan 21:00'a) kaydırarak zaman aralıklarını değiştirirseniz sonuçlar aşağıdaki örneklerde gösterildiği gibi farklı olur.
Karşılanamayan zaman aralıkları içeren bir istek örneğini inceleyin.
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T19:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T21:00:00Z", "endTime": "2023-01-13T21:30:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "endTime": "2023-01-13T18:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
Gönderimin atlandığı zaman aralıklarıyla ilgili ikinci örnek isteğe verilen yanıtı görme
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:37:49Z", "vehicleEndTime": "2023-01-13T18:09:49Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:37:49Z", "detour": "0s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:40:19Z", "detour": "150s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T17:49:38Z", "detour": "0s" }, { "startTime": "2023-01-13T18:00:00Z", "detour": "946s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:37:49Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:40:19Z" }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T17:42:49Z" }, { "travelDuration": "372s", "travelDistanceMeters": 1348, "waitDuration": "0s", "totalDuration": "372s", "startTime": "2023-01-13T17:53:48Z" }, { "travelDuration": "339s", "travelDistanceMeters": 1276, "waitDuration": "0s", "totalDuration": "339s", "startTime": "2023-01-13T18:04:10Z" } ], "metrics": { "performedShipmentCount": 2, "travelDuration": "1120s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1920s", "travelDistanceMeters": 3995 }, "routeCosts": { "model.vehicles.cost_per_kilometer": 39.95, "model.vehicles.cost_per_hour": 21.333333333333332 }, "routeTotalCost": 61.283333333333331 } ], "skippedShipments": [ { "index": 1 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 2, "travelDuration": "1120s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1920s", "travelDistanceMeters": 3995 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:37:49Z", "latestVehicleEndTime": "2023-01-13T18:09:49Z", "totalCost": 81.283333333333331, "costs": { "model.shipments.penalty_cost": 20, "model.vehicles.cost_per_hour": 21.333333333333332, "model.vehicles.cost_per_kilometer": 39.95 } } }
Bu örnekte, daha sonraki zaman aralığı, gönderinin teslimatının belirtilen zaman aralığında tamamlanması için gereken ek araç çalışma süresi, gönderinin ceza maliyetini aştığı için shipment[1]
'nın atlanmasına neden oldu.
shipment[1]
için ceza maliyeti metrics.costs
içinde, dizini ise skippedShipments
içinde gösterilir.
Esnek zaman aralığı kısıtlamaları
Maliyet modeli parametreleri bölümünde kısaca belirtildiği gibi, zaman aralıkları esnek kısıtlamalar olarak uygulanabilir. Esnek kısıtlamalar, katı kısıtlamalardan şu şekilde farklıdır:
- Kesin kısıtlamalar: İhlal edilemez ve optimizasyon aracı, gönderimin atlanması anlamına gelse bile kısıtlamayı ihlal eden bir çözüm sunmaz.
- Yumuşak kısıtlamalar: İhlal edilebilir. Bu nedenle, optimizasyon aracı yumuşak kısıtlamaları ihlal eden bir çözüm sunabilir. Ancak optimize edici, ihlaller için maliyet de uygular. Bu maliyeti, zaman aralığında ek bir özellik olarak sağlarsınız. Genellikle, etkinliğin gerçekleştiği zaman aralığından önceki veya sonraki her saat için saatlik maliyet olarak sağlanır.
Zaman aralıkları, sırasıyla startTime
veya endTime
yerine softStartTime
veya softEndTime
kullanılarak ve costPerHourBeforeSoftStartTime
veya costPerHourAfterSoftEndTime
ayarlanarak yumuşatılır.
Teslim alma veya teslimatın belirli bir zaman aralığında yapılması gerektiği ancak bu zaman aralığında teslim alma veya teslimatın kesinlikle gerekli olmadığı durumlarda esnek zaman aralığı kısıtlamaları kullanın. İşletme hedeflerini ifade etmek için hem kesin hem de esnek zaman aralığı kısıtlamalarını birlikte kullanabilirsiniz. Örneğin:
- Kesin zaman aralığı: Müşterinin çalışma saatlerini (ör. 09:00-17:00) gösterir.
- Esnek zaman aralığı: Teslimat veya teslim alma için müşteriye gönderilen bildirimle eşleşen zaman aralığını (ör. 09:00-13:00) belirtir.
Bu örnekte, zaman aralığı çok geç başladığı için daha önce atlanan gönderinin başlangıç zamanı kısıtlaması gevşetilir. Diğer gönderilerin zaman aralıklarının bitiş zamanları da esnetildi.
Kesin ve esnek zaman aralıkları içeren örnek bir istek görün
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "softEndTime": "2023-01-13T19:00:00Z", "costPerHourAfterSoftEndTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "softStartTime": "2023-01-13T21:00:00Z", "endTime": "2023-01-13T21:30:00Z", "costPerHourBeforeSoftStartTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "softEndTime": "2023-01-13T18:00:00Z", "costPerHourAfterSoftEndTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
Sert ve esnek zaman aralıkları içeren örnek isteğe verilen yanıtı görme
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:48:35Z", "vehicleEndTime": "2023-01-13T18:24:28Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:48:35Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T17:51:05Z", "detour": "150s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:53:35Z", "detour": "300s" }, { "startTime": "2023-01-13T18:00:00Z", "detour": "300s" }, { "shipmentIndex": 1, "startTime": "2023-01-13T18:07:42Z", "detour": "493s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T18:17:27Z", "detour": "873s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:48:35Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:51:05Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:53:35Z" }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-13T17:56:05Z" }, { "travelDuration": "212s", "travelDistanceMeters": 791, "waitDuration": "0s", "totalDuration": "212s", "startTime": "2023-01-13T18:04:10Z" }, { "travelDuration": "335s", "travelDistanceMeters": 1204, "waitDuration": "0s", "totalDuration": "335s", "startTime": "2023-01-13T18:11:52Z" }, { "travelDuration": "171s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "171s", "startTime": "2023-01-13T18:21:37Z" } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "953s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2153s", "travelDistanceMeters": 3455 }, "routeCosts": { "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667, "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332, "model.vehicles.cost_per_hour": 23.922222222222221, "model.vehicles.cost_per_kilometer": 34.55 }, "routeTotalCost": 64.797222222222217 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "953s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2153s", "travelDistanceMeters": 3455 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:48:35Z", "latestVehicleEndTime": "2023-01-13T18:24:28Z", "totalCost": 64.797222222222217, "costs": { "model.vehicles.cost_per_kilometer": 34.55, "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332, "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667, "model.vehicles.cost_per_hour": 23.922222222222221 } } }
Yalnızca katı zaman aralığı kısıtlamaları içeren örnekte shipment[1]
tamamen atlanırken, teslimat zaman aralığının esnetilmesi, zaman aralığı başlangıç zamanından önce teslim edilmesine neden olur. Benzer şekilde, diğer gönderilerin bitiş zamanlarının esnetilmesi, shipment[2]
ürününün zaman aralığı sona erdikten sonra teslim edilmesine olanak tanıdı.
Aynı zamanda hem maliyetler hem de toplam gönderimler değişti:
totalCost
: 81.283'ten 64.797'ye düştü- Tamamlanan toplam gönderim sayısı: 2'den 3'e yükseldi
Zaman aralığı kısıtlamaları önceki örneğe kıyasla gevşetildiği için optimize edici daha ucuz bir çözüm buldu.
Son olarak, metrics.costs
özelliği, kısıtlamanın ürününe ve teslimat aralığının kaçırıldığı süreye göre oluşan gerçek maliyeti belirten yeni bir anahtar da içerir. Yani:
costPerHourBeforeSoftStartTime
2,0 ve- Gerçek teslimat ile zaman aralığının başlangıcı arasındaki süre: 2,83583 saat
Sonuç:
model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time
:
5.6716666666666669.
Bu metrikler, katı kısıtlamalar ile esnek kısıtlamalar arasındaki dengeyi görmek için maliyet analizi yapmanıza olanak tanır. Bu analizleri, kısıtlamalarınızı belirli iş kurallarınıza daha iyi uyacak şekilde ayarlamak için kullanabilirsiniz. Bu durumda, toplam maliyet 20,0'ın altındadır.shipment[1].penalty_cost
Optimizasyon aracı, gönderimi atlamaktansa daha uygun maliyetli olduğunu belirledi.