Rozwiąż problem dotyczący projektu i planowania sieci dostawy liniowej (LSNDSP) na podstawie podanego parametru DesignShippingNetworkRequest
.
LSNDSP to złożony problem optymalizacyjny mający na celu znalezienie optymalnego projektu i harmonogramu sieci dostaw liniowych. Celem jest zminimalizowanie całkowitych kosztów obsługi sieci przy jednoczesnym zaspokojeniu jak największego zapotrzebowania na transport ładunkowy między portami.
LSNDSP można podzielić na 2 główne podproblemy: projektowanie sieci i planowanie. Podproblem związany z projektem sieci określa zestaw portów obsługiwanych przez sieć, liczbę statków, które mają zostać wdrożone na każdej trasie, oraz trasy, którymi pokonują statki. Podproblem związany z harmonogramem określa harmonogramy żeglowania statkami z uwzględnieniem czasu potrzebnego na przepłynięcie między portami, czasu potrzebnego na załadowanie i rozładunek ładunku oraz zapotrzebowanie na transport ładunku między portami.
Mówiąc prościej, LSNDSP jest problemem wyboru portów do obsługi, liczby statków i zaplanowania rozmieszczenia statków tak, by koszty obsługi sieci były jak najmniejsze, a jednocześnie maksymalne przychody z realizacji zapotrzebowania na ładunek. Trudny podkomponent LSNDSP to trasa ładunku, która określa, jakie potrzeby należy spełnić i które trasy należy przypisać do ładunku w celu zmaksymalizowania przychodów.
Żądanie HTTP
POST https://optimization.googleapis.com/v1/shipping:designShippingNetwork
Adres URL używa składni transkodowania gRPC.
Treść żądania
Treść żądania zawiera dane o następującej strukturze:
Zapis JSON |
---|
{ "requestId": string, "solverParameters": { object ( |
Pola | |
---|---|
requestId |
Problem lub identyfikator prośby. |
solverParameters |
Parametry rozwiązania. |
ports[] |
Lista portów, z których można skorzystać w usługach na statku. Żądanie może zawierać tylko identyfikatory portów znajdujące się na tej liście. |
legCandidates[] |
Lista potencjalnych kandydatów do dodania do usług na statku. Prośba może zawierać tylko te identyfikatory, które znajdują się na tej liście. |
vesselClasses[] |
Lista klas statków świadczących usługi transportowe. Pamiętaj, że wszystkie statki tej samej klasy są w pełni wymienne. Żądanie może zawierać tylko identyfikatory klas statków z tej listy. |
commodityDemands[] |
Lista potencjalnych zapotrzebowania na towary (tj. kontenery) do zaspokojenia przez usługi transportowe. |
vesselServices[] |
Jako punkt wyjścia do optymalizacji można udostępnić sieć prawidłowych usług statków (zwykle obecny stan sieci). |
Treść odpowiedzi
Odpowiedź zawiera rozwiązanie dla instancji LSNDSP przekazanej w żądaniu. Zawiera prawidłową sieć usług transportowych i ścieżek popytu towarowego. Całkowity popyt towarowy przelatujący przez każdy etap nie może przekroczyć pojemności klas statku obsługującego ten etap. Warto pamiętać, że brak usług statków bez zaspokajania zapotrzebowania jest zawsze możliwym rozwiązaniem problemów z projektem i harmonogramem przesyłania linii lotniczych.
W przypadku powodzenia treść żądania zawiera dane o następującej strukturze:
Zapis JSON |
---|
{ "requestId": string, "vesselServices": [ { object ( |
Pola | |
---|---|
requestId |
Identyfikator żądania, z którym powiązana jest ta odpowiedź. |
vesselServices[] |
Sieć usług transportowych. Łączna liczba używanych statków dla każdej klasy statku nie może przekraczać liczby statków dostępnych dla tej klasy. |
commodityDemandPaths[] |
Lista wszystkich ścieżek popytu na towary, przez które realizowany jest pozytywny popyt na towary. Pamiętaj, że niektóre identyfikatory popytu na towary mogą nie zostać uwzględnione, jeśli nie zostanie wysłany żaden popyt. Można też częściowo zaspokoić popyt na towary. W przypadku każdego popytu na towar łączna ilość zrealizowanej ilości nie może przekraczać całkowitego popytu. I wreszcie, commodityDemandPaths zależy od usług vesselServices (patrz definicja CommodityDemandPath). |
SolverParameters
Parametry, które kontrolują pojedyncze rozwiązanie LSNDSP.
Zapis JSON |
---|
{ "timeLimit": string } |
Pola | |
---|---|
timeLimit |
Maksymalny czas, jaki rozwiązanie powinno poświęcić na rozwiązanie problemu. Ta wartość nie jest sztywnym limitem i nie uwzględnia opłat za komunikację. Oczekiwany czas oczekiwania na rozwiązanie problemu może nieznacznie przekraczać tę wartość. Czas trwania w sekundach z maksymalnie 9 cyframi po przecinku, kończącym się cyframi „ |
Port
Port, np. terminal lub wszystkie terminale portu.
Zapis JSON |
---|
{ "id": string, "minimumPortStayDuration": { object ( |
Pola | |
---|---|
id |
Unikalny identyfikator przypisany do tego gniazda. |
minimumPortStayDuration |
Minimalny czas trwania pobytu na prośbę o port. Większość badań przyjmuje stałą wartość, ponieważ porty zazwyczaj przypisują więcej dźwigów do większych statków o dużej liczbie ruchu, ponieważ zajmują one więcej miejsca. |
minimumTransshipmentDuration |
Minimalny czas przeładunku w danym porcie, w tym czas rozładowywania kontenera i załadunku go na inny statek. |
transshipmentCost |
Koszt transportu kontenera. Zwykle będzie ona niższa niż suma załadunku i rozładunku, ponieważ transport nie wymaga dokumentów celnych w porcie. |
vesselClassCosts |
Koszty związane z wywołaniem tego portu zmapowane na identyfikator klasy statku. Klasa statku może zadzwonić do tego portu tylko wtedy, gdy ma wpis na tej mapie. Obiekt zawierający listę par |
Czas działania
Czas trwania (pobyt w porcie/przesyłce, tranzyt na żądanie) jest zdefiniowany z dokładnością do godziny.
Zapis JSON |
---|
{ "hours": string } |
Pola | |
---|---|
hours |
Liczba godzin określających czas trwania. |
VesselCost
Koszt statku za dzwonienie i nocleg w tym porcie jest definiowany jako liniowa funkcja czasu pobytu (fixedCost
+ hourlyCost
* godz.).
Zapis JSON |
---|
{ "fixedCost": number, "hourlyCost": number } |
Pola | |
---|---|
fixedCost |
Stały koszt połączenia z tym portem. |
hourlyCost |
Koszt godzinowy za pobyt w tym porcie. |
LegCandidate
Kandydat do obsługi łodzi. Między tymi samymi 2 portami może występować kilka etapów, np. reprezentujących różne trasy oceaniczne lub prędkości statków.
Zapis JSON |
---|
{
"id": string,
"departurePortId": string,
"arrivalPortId": string,
"duration": {
object ( |
Pola | |
---|---|
id |
Unikalny identyfikator przypisany do tego etapu kandydu. |
departurePortId |
Identyfikator portu wylotu. |
arrivalPortId |
Identyfikator portu przylotu. |
duration |
Czas trwania nogi. |
vesselClassCosts |
Koszt przypisania tego etapu do określonej klasy statku. Może to być koszt eksploatacji statku, koszt zasobnika i koszt czarteru. Klasa statku może przepłynąć przez ten etap tylko wtedy, gdy ma wpis na tej mapie. Obiekt zawierający listę par |
VesselClass
Klasa statku, czyli grupa statków o tych samych właściwościach. Nie da się rozróżnić dwóch statków tej samej klasy.
Zapis JSON |
---|
{ "id": string, "containerCapacity": string, "vesselCount": string } |
Pola | |
---|---|
id |
Unikalny identyfikator przypisany do tej klasy statku. |
containerCapacity |
Pojemność klasy statku (w kontenerach). |
vesselCount |
Liczba statków w tej klasie statku. |
CommodityDemand
Popyt towarowy, czyli potencjalny popyt, który spedytor ma zaspokoić.
Zapis JSON |
---|
{
"id": string,
"originPortId": string,
"destinationPortId": string,
"containerCount": string,
"freightRate": number,
"maximumTransitDuration": {
object ( |
Pola | |
---|---|
id |
Unikalny identyfikator przypisany do tego popytu na towary. |
originPortId |
Identyfikator portu początkowego. |
destinationPortId |
Identyfikator portu docelowego. |
containerCount |
Maksymalna liczba kontenerów do wypełnienia. |
freightRate |
stawka frachtu na kontener (która może obejmować karę za niewykorzystany popyt); Powinno to zmniejszyć koszty ładowania i rozładowywania poszczególnych kontenerów w miejscu początkowym i docelowym. |
maximumTransitDuration |
Maksymalny czas przewozu (jeśli został ustawiony, wartość musi być liczbą dodatnią). Czas przewozu jest zdefiniowany od momentu, gdy pierwszy statek obsługujący dany zapotrzebowanie opuści port wylotu do czasu, gdy ostatni statek obsługujący to zapotrzebowanie pojawi się do portu docelowego. |
VesselService
Usługa statków, która może służyć do zaspokajania zapotrzebowania związanego z towarami. WAŻNE: obecnie zakładamy, że usługi są udostępniane z częstotliwością tygodniową, a czas pobytu w portach nie może przekraczać tygodnia. Weź pod uwagę następującą sekwencję etapów obsługi statku: vesselServiceLegs { legCandidateId: "0->1" originExitTime {} destinationArrivalTime { day: 3 hourOfDay: 12 } } vesselServiceOfLegs { legCandidateId: "1->0" origin Duration time {day: 4 } destinationArrival times {day: 4 } destinationArrivalTime
Zapis JSON |
---|
{
"vesselClassId": string,
"vesselServiceLegs": [
{
object ( |
Pola | |
---|---|
vesselClassId |
Identyfikator klasy statku wykonujący usługę. |
vesselServiceLegs[] |
W przypadku prawidłowej usługi rejsowej obowiązują te właściwości: 1. Pole nie może być puste. 2. Identyfikator destinationPortId i originPortId kolejnych etapów musi być taki sam (łącznie z ostatnim i pierwszym etapem). |
VesselServiceLeg
Jeden etap transportu statku.
Zapis JSON |
---|
{ "legCandidateId": string, "originDepartureTime": { object ( |
Pola | |
---|---|
legCandidateId |
Identyfikator przypisanego uczestnika etapu. |
originDepartureTime |
Godzina odjazdu z portu wylotu według harmonogramu tygodniowego. |
destinationArrivalTime |
Godzina przybycia do portu docelowego według harmonogramu tygodniowego. |
ScheduleTime
Rozkład czasu (odlot statku/na żądanie/przyloty) jest zdefiniowany zgodnie z tygodniową częstotliwością o danej godzinie.
Zapis JSON |
---|
{ "day": string, "hourOfDay": integer } |
Pola | |
---|---|
day |
Dzień zgodnie z harmonogramem. Dzień 0 to pierwszy możliwy dzień. |
hourOfDay |
Godzina w harmonogramie powinna być liczbą całkowitą z zakresu od 0 do 23 włącznie. |
CommodityDemandPath
Różne usługi i porty, z których korzysta dana część danego popytu na towary. Stosowane poniżej indeksy zależą od kolejności usług statków w odpowiedzi i kolejności etapów obsługi w poszczególnych usługach na statku.
Zapis JSON |
---|
{
"commodityDemandId": string,
"containerCount": string,
"vesselServiceLegIds": [
{
object ( |
Pola | |
---|---|
commodityDemandId |
Identyfikator popytu towarowego został zrealizowany. |
containerCount |
Liczba kontenerów przechodzących przez tę ścieżkę. W przypadku każdego popytu na towar łączna ilość zrealizowanej ilości nie może przekraczać całkowitego popytu. |
vesselServiceLegIds[] |
Lista identyfikatorów etapów obsługi statków pokonywanych przez tę ścieżkę. W przypadku prawidłowej ścieżki popytu na towar obowiązują te właściwości: 1. Identyfikator wyjazdu pierwszego etapu musi być zgodny z wartością originPortId w przypadku popytu na towary. 2. Identyfikator destinationPortId ostatniego etapu musi być zgodny z wartością destinationPortId w przypadku popytu na towar. 3. Kolejne etapy przyjazdu i wyjazdu PortId muszą być takie same. 4. Jeśli maksymalny czas przewozu został podany w przypadku tego popytu na towary, maksymalny czas przewozu powinien być dłuższy niż łączny czas trwania ścieżki lub równy. |
VesselServiceLegId
Jeden etap obsługi statków używany w ścieżce popytu na towary. Weźmy na przykład 2 usługi na statku. Pierwsza składa się z 3 nóg (zindeksowanych 0, 1 i 2), a drugich (zindeksowanych 0 i 1). Dodatkowo pierwszy etap pierwszej usługi przybędzie do portu wylotu drugiego etapu. Ścieżka towarowa składająca się z 3 następujących identyfikatorów usług statków: {vesselServiceIndex: 0, vesselServiceLegIndex: 2} {vesselServiceIndex: 0, vesselServiceLegIndex: 0} {vesselServiceIndex: 1, vesselServiceLegIndex: 1, vesselServiceLegIndex: 0, vesselServiceLegIndex: 2} {vesselServiceIndex: 0, vesselServiceLegIndex: 0} {vesselServiceIndex: 1, vesselServiceLegIndex: 1, vesselServiceLegIndex: 0, vesselServiceLegIndex: 2} {vesselServiceIndex: 0} {vesselServiceLegIndex: 1, vesselServiceLegIndex
Zapis JSON |
---|
{ "vesselServiceIndex": integer, "vesselServiceLegIndex": integer } |
Pola | |
---|---|
vesselServiceIndex |
Indeks usług statków. |
vesselServiceLegIndex |
Indeks odcinka linii lotniczej zindeksowanej przez: |