OptimizeToursRequest
aşağıdakiler için kısıtlamalar uygular:
- Kargolar, kargoların nasıl yapıldığını etkiler.
- Araç rotalarının hesaplanmasını etkileyen araçlar
- Hem araçları hem de kargoları dünya genelinde etkiliyor.
Bu kılavuzda, gönderimlerle ilgili önemli bir kısıtlamaya (zaman aralıkları) odaklanılmıştır.
Zaman aralıkları, gönderim etkinliklerine zamana dayalı sınırlar belirtmek için OptimizeToursRequest
mesajında (REST, gRPC) sağladığınız bir tür kısıtlamadır. Bu tür kısıtlamalar, bir gönderimin ne zaman ve nasıl yapılabileceğinin yanı sıra gönderim için araç atamasını da etkiler. Bu kısıtlamalarla birlikte optimizatör, gönderimin zaman kısıtlamalarını en iyi şekilde karşılayabilecek araçlara öncelik verir.
Gönderim kısıtlamaları: zaman aralıkları
Teslim alma veya teslimat işleminin ne zaman gerçekleşebileceğini Shipment.VisitRequest
mesajında aşağıdaki şekilde belirtirsiniz:
- İletideki
timeWindows
mülkünü kullanın (REST, gRPC) TimeWindow
mesajında (REST, gRPC) başlangıç ve bitiş zamanını belirtin.
Zaman aralığı kısıtlamaları içeren örnek istek
Bu örnekte, her biri kendi teslimat aralığına sahip üç farklı gönderim gösterilmektedir. Basitlik açısından bu örnekte yalnızca deliveries
için zaman aralıkları ayarlanmıştır ancak zaman aralıkları teslim alma işlemlerine de uygulanabilir. Birden fazla zaman aralığı belirtilebilir ancak bu örnekte her yayın için yalnızca bir tane VisitRequest
kullanılı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, tüm zaman aralığı kısıtlamalarını karşılarken istekte costPerHour
olarak belirtilen aracı çalıştırmak için gereken süreyi en aza indiren optimize ediciyi yansıtır. Başlangıç zamanı olarak 17:35:50'i kullanmak, ziyaretin zaman aralığı başlayana kadar aracın ziyaret konumunda beklemesi gerekmesini ortadan kaldırır. Bu, yanıtta sıfır waitDuration
değeri olarak görünür.
Örnek istek için zaman aralıkları içeren bir 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önderimlerin önce teslim edilmesi için aracın visits
'ünü sipariş etti.
shipments[2]
, 17:50'de teslim edildishipments[1]
, 18:00'de teslim edildishipments[0]
, 18:07'de teslim edildi
Örnek istek, yayınların bu aralıklarda tamamlanmasını gerektiren katı zaman aralığı kısıtlamaları belirtir. Bir gönderimin VisitRequests
zaman aralığından herhangi birinde tamamlanması mümkün değilse veya uygun maliyetli değilse optimizatör gönderimi atlar. Gönderimde penaltyCost
varsa optimizatör, yanıt olarak bildirilen maliyetlere metrics
ekler. Aksi takdirde, OptimizeToursResponse
mesajının (REST, gRPC) skippedMandatoryShipmentCount
özelliği artar.
shipment[1]
'nin zaman aralığını birkaç saat daha geçe (18:00 yerine 21:00'e) kaydırarak zaman aralıklarını değiştirirseniz sonuçlar aşağıdaki örneklerde gösterildiği gibi farklı olur.
Yerine getirilemeyen 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-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ığı ikinci örnek istek için zaman aralıkları içeren bir yanıtı görüntüleme
{ "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, gönderinin belirtilen zaman aralığında teslim edilmesi için gereken ek araç çalışma süresi, gönderinin ceza maliyetini aştığından daha sonraki zaman aralığı shipment[1]
'ün atlanmasına neden olmuştur.
shipment[1]
için ceza maliyeti metrics.costs
'te, dizini ise skippedShipments
'de görünür.
Gevşek zaman aralığı kısıtlamaları
Maliyet Modeli Parametreleri bölümünde kısaca belirtildiği gibi, zaman aralıkları yumuşak kısıtlamalar olarak uygulanabilir. Gevşek kısıtlamalar, katı kısıtlamalardan aşağıdaki açılardan farklıdır:
- Katı kısıtlamalar: İhlal edilemez ve optimizatör, bir gönderimi atlama anlamına gelse bile kısıtlamayı ihlal eden bir çözüm sunmaz.
- Yumuşak kısıtlamalar: İhlal edilebilir. Bu, optimizasyon aracının yumuşak bir kısıtlamayı ihlal eden bir çözüm sunabileceği anlamına gelir. Ancak optimizatör, her ihlal için bir maliyet de uygular. Bu maliyeti, zaman aralığında ek bir mülk olarak sağlarsınız. Genellikle, etkinliğin gerçekleştiği zaman aralığından önceki veya sonraki her saat için saat başına maliyet olarak kullanılır.
Sırasıyla startTime
veya endTime
yerine softStartTime
ya da softEndTime
kullanılarak ve costPerHourBeforeSoftStartTime
veya costPerHourAfterSoftEndTime
ayarlanarak zaman aralıkları yumuşatılır.
Teslim alma veya teslimat işleminin belirli bir zaman aralığında yapılması gerektiği ancak bu zaman aralığında teslim alma veya teslimat işleminin yapılmasının kesinlikle zorunlu olmadığı durumlarda yumuşak zaman aralığı kısıtlamalarını kullanın. İşletme hedeflerini ifade etmek için katı ve esnek zaman aralığı kısıtlamalarını birlikte kullanabilirsiniz. Örneğin:
- Sabit 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ı yumuşatılmıştır. Diğer gönderimlerin zaman aralığının bitiş zamanları da uzatıldı.
Sabit ve esnek 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 } ] } }
Örnek istek için katı ve esnek zaman aralıkları içeren bir yanıt
{ "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ı olan örnekte shipment[1]
tamamen atlanmışken, teslimat zaman aralığının yumuşatılması, zaman aralığı başlangıç zamanından önce teslim edilmesine neden olur. Benzer şekilde, diğer gönderimlerin bitiş zamanlarını esnetmek, shipment[2]
'ün zaman aralığı sona erdikten sonra teslim edilmesine olanak tanıdı.
Aynı zamanda hem maliyetler hem de toplam gönderim sayısı değişti:
totalCost
: 81.283 olan değer 64.797 olarak azaltıldı- tamamlanan toplam gönderi sayısı: 2 olan değer 3 olarak arttı
Zaman aralığı kısıtlamaları önceki örneğe kıyasla gevşetildiği için optimizatör daha ucuz bir çözüm buldu.
Son olarak metrics.costs
mülkü, kısıtlamanın çarpımına ve teslimat aralığının kaçırılmasının süresine göre oluşan gerçek maliyeti belirtmek için 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 yumuşak 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şletme kurallarınıza daha uygun olacak şekilde ayarlamak için kullanabilirsiniz. Bu durumda toplam maliyet, 20,0 olan shipment[1].penalty_cost
değerinden azdır. Optimizasyon aracı, gönderimi erken teslim etmenin gönderimi atlamaktan daha uygun maliyetli olduğunu belirledi.