OptimizeToursRequest
, aşağıdakilerle ilgili kısıtlamalar uygular:
- Sevkiyatların nasıl yapıldığını etkileyen gönderimler
- Araç rotalarının hesaplanma şeklini etkileyen araçlar
- Tüm dünyada hem araçları hem de sevkiyatları etkiliyor.
Bu kılavuz, önemli bir gönderim kısıtlamasına, yani zaman aralıklarına odaklanmaktadır.
Zaman aralıkları, gönderim etkinlikleri için zamana dayalı sınırlar belirtmek amacıyla OptimizeToursRequest
mesajında (REST, gRPC) sağladığınız bir kısıtlama türüdür. Bu sınırlama türü, bir gönderinin ne zaman ve nasıl gerçekleştirileceğini ve gönderim için araç atamasını etkiler. Bu kısıtlamalarla optimize edici, sevkiyatın zaman kısıtlamalarını en iyi şekilde karşılayabilen araçları tercih eder.
Gönderim kısıtlamaları: zaman aralıkları
Shipment.VisitRequest
mesajında teslim alma veya teslimatın ne zaman yapılabileceğini aşağıdaki şekilde belirtirsiniz:
- İletideki
timeWindows
özelliğini (REST, gRPC) kullanın 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. Kolaylık sağlaması açısından bu örnekte zaman aralıkları yalnızca deliveries
için ayarlanır ancak zaman aralıkları teslim almalara da uygulanabilir. Birden fazla zaman aralığı belirtilebilir ancak bu örnekte her yayınlama VisitRequest
için yalnızca bir tane kullanılmaktadır.
Zaman aralıkları içeren örnek bir isteğe bakı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", "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, optimize edicinin tüm zaman aralığı kısıtlamalarını karşılarken istekte belirtilen aracı costPerHour
olarak çalıştırmak için gereken süreyi en aza indirdiğini gösterir. Başlangıç zamanı olarak 17:35:50'yi kullanmak, aracın ziyaret zaman aralığı başlayana kadar ziyaret konumunda bekleme ihtiyacını ortadan kaldırır. Bu değer, yanıtta sıfır waitDuration
değerleri olarak görünür.
Örnek isteğin yanıtını zaman aralıklarıyla inceleyin
{ "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ında araçtaki visits
sıralanmıştır. Böylece, en erken zaman aralıklarına sahip sevkiyatlar önce teslim edilir.
shipments[2]
, 17:50'de teslim ediliyorshipments[1]
, 18:00'de teslim ediliyorshipments[0]
, 18:07'de teslim edildi
Örnek istek, teslimatların bu zaman aralıkları içinde tamamlanmasını gerektiren sabit zaman aralığı kısıtlamalarını belirtir. Bir gönderimin VisitRequests
işleminin, zaman aralıklarından herhangi birinde tamamlanması uygun değilse veya maliyet açısından uygun değilse optimize edici gönderimi atlar. Gönderimde penaltyCost
varsa optimize edici bunu metrics
yanıtında bildirilen maliyetlere ekler. Aksi takdirde, OptimizeToursResponse
mesajının skippedMandatoryShipmentCount
özelliği (REST, gRPC) artar.
shipment[1]
aralığını birkaç saat sonraya kaydırarak (18:00'den 21:00'e) zaman aralıklarını değiştirirseniz sonuçlar aşağıdaki örneklerde gösterildiği gibi farklı olur.
Yerine getirilemeyen zaman aralıklarına sahip örnek bir isteği 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 } ] } }
Bir gönderinin atlandığı zaman aralıklarıyla ikinci örnek isteğe verilen yanıtı inceleyin
{ "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, kargonun teslimini belirtilen zaman aralığında tamamlamak için gereken ek araç çalışma süresi, gönderimin ceza maliyetini aştığından daha geç olan zaman aralığı shipment[1]
atlanmasına neden olmuştur.
shipment[1]
için ceza maliyeti metrics.costs
içinde ve dizini skippedShipments
içinde gösteriliyor.
Esnek zaman aralığı kısıtlamaları
Maliyet Modeli Parametreleri'nde kısaca belirtildiği gibi, zaman aralıkları soft kısıtlamalar olarak uygulanabilir. Yazılım kısıtlamaları, aşağıdaki gibi katı kısıtlamalardan farklıdır:
- Zor kısıtlamalar: İhlal edilemez ve optimize edici, bir gönderimi atlamak anlamına gelse bile, kısıtlamayı ihlal eden bir çözüm sunmaz.
- Hafif kısıtlamalar: İhlal edilebilir. Bu, optimize edicinin yumuşak kısıtlamayı ihlal eden bir çözüm sağlayabileceği anlamına gelir. Ancak optimize edici, ihlaller için bir maliyet uygular. Bu maliyeti zaman aralığında ek bir özellik olarak, genellikle etkinliğin gerçekleştiği zaman aralığından önceki veya sonraki her saat için saatlik maliyet olarak sağlarsınız.
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 teslimatların belirli bir zaman dilimi içinde gerçekleşmesi gerektiğinde esnek zaman aralığı kısıtlamaları kullanın ancak bu zaman dilimi içinde teslim alma veya teslimat kesinlikle zorunlu değildir. İşletme hedeflerini ifade etmek için zor ve yumuşak zaman aralığı kısıtlamalarını bir arada kullanabilirsiniz. Örneğin:
- Zor zaman aralığı: Müşterinin çalışma saatlerini belirtir (örneğin, 09:00-17:00 arası).
- Geçici zaman aralığı: Müşteriye gönderilen bildirimle eşleşen, teslimat veya teslim alma için zaman aralığını belirtir (ör. 09:00 - 13:00).
Bu örnekte, zaman aralığı çok geç başladığı için daha önce atlanan gönderimin başlangıç zamanı kısıtlaması yumuşatılmıştır. Diğer gönderimlerde de zaman aralıkları da yumuşatıldı.
Sabit ve yumuşak zaman aralıkları içeren örnek bir isteğe bakı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 } ] } }
Sabit ve geçici zaman aralıklarına sahip örnek isteğin yanıtını görün
{ "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 zor zaman aralığı kısıtlamalarına sahip olan örneğin shipment[1]
tamamen atlandığı durumlarda, teslim süresi aralığının yumuşatılması zaman aralığının başlangıç zamanından önce yayınlanmasına neden olur. Benzer şekilde, diğer gönderimlerin bitiş zamanlarının yumuşatılması, shipment[2]
ürününün, zaman aralığı sona erdikten sonra teslim edilmesini sağladı.
Aynı zamanda hem maliyetler hem de toplam gönderimler değişti:
totalCost
: 81,283'ten 64,797'ye düşürüldü- tamamlanan toplam gönderim sayısı: 2'den 3'e artırıldı
Optimize Edici, zaman aralığı kısıtlamaları bir önceki örneğe göre gevşetilmiş olduğundan daha ucuz bir çözüm bulmuştur.
Son olarak metrics.costs
özelliği, kısıtlama ürününe ve teslimat aralığının kaçırıldığı süreye göre tahakkuk eden gerçek maliyeti belirtmek için yeni bir anahtar 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 analizlerden yararlanarak kısıtlamalarınızı belirli iş kurallarınıza daha uygun olacak şekilde ayarlayabilirsiniz. Bu durumda toplam maliyet, 20,0 shipment[1].penalty_cost
değerinin altında kalır. Optimize Edici, gönderimi atlamadan erken teslim etmenin daha uygun maliyetli olduğunu belirledi.