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 aktivitelerinin zamana dayalı sınırları belirtmek için OptimizeToursRequest
mesajında (REST, gRPC) sağladığınız bir kısıtlama türüdür. Bu kısıtlama türü, hem gönderinin ne zaman ve nasıl gerçekleştirilebileceğini hem de sevkiyat için aracın atanmasını 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 isteğe verilen yanıtı 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ı, 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]
, saat 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 optimize edici bunu yanıt olarak bildirilen maliyetlere ekler metrics
. Aksi takdirde, OptimizeToursResponse
mesajının (REST, gRPC) skippedMandatoryShipmentCount
özelliği artar.
shipment[1]
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. Bununla birlikte, optimize edici tüm ihlallere bir maliyet de 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
ya da softEndTime
kullanılarak ve costPerHourBeforeSoftStartTime
veya costPerHourAfterSoftEndTime
ayarlanarak 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 yumuşak 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 isteğe verilen zor ve geçici zaman aralıklarıyla verilen yanıtı inceleyin
{ "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 daha az olduğu için optimizatör daha ucuz bir çözüm buldu.
Son olarak, metrics.costs
özelliği, kısıtlamanın ürününe ve teslim aralığının kaçırıldığı sürenin uzunluğuna bağlı olarak tahakkuk eden 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 ve yumuşak kısıtlamalar arasındaki dengeyi görmek için maliyet analizi yapmanıza olanak tanır. Bu metrikleri, kısıtlamalarınızı belirli iş kurallarına daha uygun olacak şekilde ayarlamak için kullanabilirsiniz. Bu durumda toplam maliyet, 20,0 shipment[1].penalty_cost
değerinden daha az olur. Optimizasyon aracı, gönderimi erken teslim etmenin gönderimi atlamaktan daha uygun maliyetli olduğunu belirledi.