W tym przewodniku opisano loadDemands
i loadLimits
oraz ich związek z każdym z nich
inne.
Jak wspomnieliśmy w sekcji Ograniczenia związane z czasem odbioru i dostawy,
Komunikat OptimizeToursRequest
(REST, gRPC) zawiera liczbę
właściwości, które określają ograniczenia dotyczące optymalizowanego problemu. Kilka
Właściwości OptimizeToursRequest
odpowiadają ograniczeniom obciążenia.
Pojazdy i ładunki mają właściwości fizyczne, które trzeba wziąć pod uwagę podczas planowania trasy.
- Pojazdy: właściwość
loadLimits
określa maksymalne obciążenie jaki może obsłużyć samochód. Zobacz komunikatVehicle
(REST, gRPC) dokumentacji. - Przesyłki: właściwość
loadDemands
określa obciążenie danej konsumpcji. Zobacz komunikatShipment
(REST, gRPC) dokumentacji.
Połączenie tych dwóch ograniczeń pozwala optymalizatorowi odpowiednio przypisywać przesyłki do pojazdów w sposób najlepiej dopasowany pojemności floty i zapotrzebowania na wysyłkę.
W pozostałej części tego dokumentu opisano szczegółowo loadLimits
i loadDemands
.
Żądania i limity związane z obciążeniem: typy
Wyrażasz każde żądanie obciążenia i ograniczenie limitu za pomocą typu.
Możesz podać własny zestaw typów wczytywania, np. w tych przykładach:
- waga
- głośność
- pomiary liniowe
- nazwy przenoszonych towarów lub sprzętu
W tym przewodniku przykładowy typ to weightKg
.
Zarówno Shipment.loadDemands
, jak i Vehicle.loadLimits
używają buforów protokołów
typu map
, a klucze (string
) reprezentujące typy obciążenia.
Wartości Shipment.loadDemands
używają komunikatu Load
(REST, gRPC).
Wiadomość Load
ma pojedynczą właściwość amount
, która reprezentuje pojemność
jest wymagane do zrealizowania wysyłki określonego typu.
Wartości Vehicle.loadLimits
używają komunikatu LoadLimit
(REST,
gRPC). Wiadomość LoadLimit
ma kilka właściwości, w tym maxLoad
reprezentująca maksymalną nośność pojazdu w określonym typie.
loadDemands
przesyłki używa przypisanego do niej przypisanego pojazdu (loadLimits
) tylko wtedy,
mają pasujące klucze typu obciążenia. Na przykład przesyłka z
loadDemands
z:
"loadDemands": {
"weightKg": {
"amount": 50
}
}
wymaga 50 jednostek obciążenia typu weightKg
, aby przesyłka została zrealizowana
. Pojazd z loadLimits
z:
"loadLimits": {
"weightKg": {
"maxLoad": 100
}
}
może być w stanie zrealizować dostawę, ponieważ maxLoad
pojazdu w
Typ weightKg
jest większy niż lub równy loadDemands
przesyłki w
typu weightKg
. Jednak pojazd, który ma loadLimits
z:
"loadLimits": {
"equipmentRackStorage": {
"maxLoad": 10
}
}
domyślnie ma nieograniczoną pojemność weightKg
z powodu braku
Limit obciążenia wynosi weightKg
. W takim przypadku pojazd nie jest ograniczony przez
na wagę.
Przenoszenie ładunków między przesyłkami a pojazdami
W miarę odbierania i dostarczania przesyłki przez samochody,
loadDemand
– przesiadka między wysyłką a pojazdem. Możesz zobaczyć,
ładunków pojazdu w komunikacie OptimizeToursResponse
(REST,
Wpis gRPC)routes.transitions
dla danego pojazdu. Sekwencja wygląda tak:
następujące:
- Wymagana pojemność ładunkowa jest zdefiniowana dla przesyłki jako
loadDemand
. - Przesyłka jest odbierana przez przypisany pojazd, a pojazd
vehicleLoads
zwiększa się o kwotęloadDemand
dostawy. Ten jest wyświetlane w odpowiedzi przez pozytywnevisits.loadDemands
. . - Pojazd dostarcza przesyłkę, a
vehicleLoads
– spadek od kwotyloadDemand
dostarczonej przesyłki. Ten transfer jest oznaczany jako ujemnevisits.loadDemands
w wiadomości z odpowiedzią.
vehicleLoads
pojazdu nie może w żadnym momencie przekraczać określonej wartości loadLimits
na swojej trasie.
Kompletny przykład wymagań i limitów obciążenia
Zobacz przykładowe żądanie z wymaganiami obciążenia i ograniczenia
{ "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 } } } ] } }
Przykładowe żądanie zawiera kilka parametrów związanych z obciążeniem:
shipments[0]
ma żądanie obciążenia równe 50weightKg
.- Zasób
shipments[1]
ma żądanie obciążenia równe 10weightKg
. - Zasób
shipments[2]
ma żądanie obciążenia równe 80weightKg
. - Limit obciążenia strony
vehicles[0]
wynosi 100weightKg
.
zobaczyć odpowiedź na żądanie z żądaniami obciążenia i ograniczenia
{ "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 } } }
Dodane ograniczenia obciążenia wpływają na kolejność visits
:
- Odebrano:
shipment[0]
- Odebrano:
shipment[1]
- Dostarczono
shipment[0]
- Dostarczono
shipment[1]
- Odebrano:
shipment[2]
- Dostarczono
shipment[2]
W niniejszym zamówieniu stwierdzono, że pojazd nie może zrealizować 3 przesyłek
w tym samym czasie, bo łączna wartość loadDemands
przekracza wartość pojazdu
loadLimits
Każda pozycja visits
obejmuje zmianę obciążenia pojazdu wynikających z
ukończenia Visit
. Dodatnie wartości obciążenia pokazują wczytywanie
wartości ujemne reprezentują wyładowywanie przesyłki.
Każda pozycja transitions
obejmuje całkowite obciążenie pojazdu w okresie
Transition
Przykładowo, weightKg
czas wczytywania danych transitions[2]
wynosi 60,
reprezentujący łączne obciążenia shipment[0]
i shipment[1]
.
Obiekty wskaźników routes[0].metrics
i metrics.aggregatedRouteMetrics
obejmują
właściwość maxLoads
. Wartość dla typu weightKg
wynosi 80, co reprezentuje
fragment trasy pojazdu, który po dojechał shipments[2]
na
lokalizacji dostawy.
Ograniczenia limitu częściowego obciążenia
Tak jak w przedziałach czasowych opisanych w sekcji Przedział czasu odbioru i dostawy
Ograniczenia i ograniczenia limitu obciążenia mają warianty sztywne i pozorne.
Właściwość maxLoad
wiadomości LoadLimit
wyznacza sztywne ograniczenie:
pojazd nie może przekraczać ładunku przekraczającego maxLoad
w określonych
typu. Właściwości softMaxLoad
i costPerUnitAboveSoftMax
wyrażają łagodną
, przy czym każda jednostka przekraczająca softMaxLoad
powoduje wywołanie
Koszt: costPerUnitAboveSoftMax
.
Ograniczenia łagodnego obciążenia mają kilka zastosowań, na przykład:
- zrównoważenie dostaw większej liczby pojazdów niż wymagana minimalna liczba kiedy jest to opłacalne.
- wyrażanie preferencji kierowcy w zakresie liczby przedmiotów, które może wygodnie odbiór i dostawa na określonej trasie
- ładowanie pojazdów poniżej ich maksymalnej pojemności fizycznej, aby ograniczyć zużycie obniżyć koszty utrzymania
Twarde i łagodne ograniczenia obciążenia mogą być używane razem. Na przykład trudny do limit obciążenia może określać maksymalną masę ładunku, który pojazd może bezpiecznie przewieźć lub maksymalną liczbę elementów, które można jednorazowo zmieścić w pojeździe. limit łagodnego obciążenia może być maksymalną wagą lub liczbą elementów podlegających opodatkowaniu, zmieścić w pojeździe wszystko, co się w nim znajduje.