In diesem Beitrag werden wir sehen, wie Flexport mithilfe von Mathematik und Datenwissenschaft Lieferprobleme löst und Waren pĂŒnktlich zu möglichst geringen Kosten liefert.Stellen Sie sich ein spekulatives Szenario vor: Der Spediteur hat zehn AbflĂŒge und einen Zielflug fĂŒr jede Sendung. Die einzige Entscheidung, die getroffen werden muss, ist, ob jede Sendung diesem einzelnen Flug zugeordnet werden soll. Wenn wir dem Flug keine bestimmte Last zuweisen, nehmen wir an, dass es möglich ist, ihn auf andere Weise zu bewegen.Jede Sendung hat Volumen und Kosten, und das Flugvolumen ist begrenzt. Sie können sich das als vereinfachtes Rucksackproblem vorstellen. Es gibt also 1024-1 = 1023 mögliche Lösungen (wir wĂŒrden das Flugzeug nicht vollstĂ€ndig leer senden).Wir könnten eine Tabelle erstellen, um die gesamte Lösung aufzulisten und die rentabelste auszuwĂ€hlen. Aber was ist, wenn Sie die gleichen zehn AbflĂŒge haben, aber zwei FlĂŒge? Dies sind 59.049 Lösungen in nur 10 Sendungen.Ein groĂer Spediteur hat mehr als zehn AbflĂŒge und natĂŒrlich mehr als zwei FlĂŒge zur Auswahl, was zu Billionen bis Billionen möglicher Lösungen fĂŒhrt. Unter diesen sind nur Millionen machbar, was bedeutet, dass die traditionelle Tabellenkalkulationsmethode mindestens eine praktikable Lösung finden kann. Wir brauchen aber nicht nur machbare Lösungen. Wir brauchen die besten und optimalen Lösungen. Wie findet man sie unter unzĂ€hligen Möglichkeiten? Eine Antwort ist die Verwendung der Ganzzahlprogrammierung.Die ganzzahlige Programmierung ist ein Unterabschnitt der diskreten Optimierung, ein Bereich der Untersuchung von Operationen im Zusammenhang mit der Minimierung einiger objektiver Funktionen, die EinschrĂ€nkungen unterliegen. Wir wollen die Gesamtkosten minimieren, vorausgesetzt, die Waren werden pĂŒnktlich an die richtigen Orte geliefert, gestapelt in ULD (Unit Load Device - ein Mittel zum Verpacken von Waren). Wir streben nach einer optimalen Lösung, aber in der Praxis können wir sie manchmal nicht erreichen. In diesem Fall sind wir mit einer guten oder engen Lösung zufrieden. Hier beschrĂ€nken wir uns auf ein einfaches Modell, in dem die optimale Lösung erreichbar ist.Der erste Schritt zur Lösung dieses Problems besteht darin, sich der Literatur zuzuwenden. Die wissenschaftliche Gemeinschaft befasst sich seit vielen Jahren mit der Spedition. Wir haben mehrere Werke gefunden, die sehr an unser Problem erinnern. Wir haben viele der folgenden Konzepte und Notationen aus diesen Werken ĂŒbernommen und danken den Autoren fĂŒr ihren Beitrag zu diesem Bereich.Wir beginnen mit der Definition der Zielfunktion. Um die Kosten zu minimieren, mĂŒssen wir das Konzept des Standardgewichts verstehen. Kurz gesagt, das Standardgewicht ist das Mindestgewicht, mit dem der Spediteur arbeiten möchte, unabhĂ€ngig davon, welches Gewicht tatsĂ€chlich angeboten wird. Wir haben Gesamtgewicht, Standardgewicht und Chancen fĂŒr Ăberlastungen und umgekehrt Untergewicht. Das Standardgewicht mal das Untergewicht ist eine UnterschĂ€tzung, daher können wir das Untergewicht ignorieren und uns auf den Ăberlastungsfaktor multipliziert mit der Ăberlast selbst konzentrieren.Die Zielfunktion besteht darin, die Gesamtkosten zu minimieren, definiert als das Gesamtgewicht aller von ULD zugewiesenen Waren, multipliziert mit dem Auslastungsfaktor. Wenn ULD1 beispielsweise 100 kg Ăberlastung aufweist und die Ăberlastungsrate fĂŒr ULD1 4 USD pro Kilogramm betrĂ€gt, betragen die Gesamtkosten fĂŒr ULD 1 400 USD. Wir brauchen also eine Notation, um ĂŒbergewichtig zu sein und um ihren Wert zu ermitteln.Lassen â- Gewicht ULD j ĂŒber Standard und â- Kostenfaktor fĂŒr dieselbe ULD. Wir mĂŒssen rechnen fĂŒr alle . Wenndann wird die Zielfunktion sein . Es bricht zusammen. Wir wollen den Wert minimieren, also unser Endziel:
Wert fĂŒr kein berechneter Wert. Dieser Parameter wird aus einer Tabelle oder Datenbank abgerufen. Aber Wir haben das GesamtĂŒberlastgewicht fĂŒr ULD definiert , die wir als Gesamtgewicht aller von ULD zugewiesenen Lieferungen berechnen können (bezeichnen Sie es ) abzĂŒglich des Standardgewichts dieser ULD. Das Standardgewicht ist spezifisch fĂŒr den ULD-Typ und auch ein Parameter. Lassen âist das Standardgewicht fĂŒr ULD in Kilogramm. Dann die Menge an zusĂ€tzlichem Gewicht fĂŒr ULD definiert als .Das Gesamtgewicht der ULD hĂ€ngt natĂŒrlich davon ab, welche Gewichte der ULD zugewiesen sind und wie schwer sie sind. Daher benötigen wir einen Ausdruck, um ihn zu berechnen, einschlieĂlich der oben genannten Details.Dies ist einfach die Summe der von ULD zugewiesenen Gewichte. Wie kann angegeben werden, dass eine Warencharge einer bestimmten ULD zugeordnet wurde? Dazu benötigen wir keinen Parameter, sondern eine Lösungsvariable. Eine Entscheidungsvariable kann der Löser steuern und gleichzeitig die Zielfunktion minimieren.Lassen Sie den Parameter reprĂ€sentiert das Bruttogewicht in Kilogramm.Zum Beispiel,bedeutet, dass eine Ladung von 4 500 Kilogramm wiegt.Lassen â- eine Entscheidungsvariable mit dem Wert 1 beim Versand von ULD zugewiesen , und sonst. Wenn wir also alle von ULD 3 zugewiesenen Sendungen zĂ€hlen möchten, können wir alle Variablen durchlaufenwo . Wenn wir 4 Sendungen hĂ€tten und die Sendungsnummern 1 und 3 ULD 3 zugewiesen wĂŒrden, wĂŒrde dies folgendermaĂen aussehen:
Aber wir brauchen das Gesamtgewicht, nicht die Menge. Um es zu erhalten, können Sie einfach jede Lösungsvariable mit einem Gewichtungsparameter multiplizieren. Da die Entscheidungsvariable den Wert 0 annimmt, wird dieses Gewicht zurĂŒckgesetzt und nicht in die Summe einbezogen, wenn ihr kein Gewicht zugewiesen ist. Angenommen, die Gewichte fĂŒr die Ladungen eins bis vier betragen 10, 50, 25 und 5. Dann betrĂ€gt das Gesamtgewicht in ULD 3:
Schreiben wir diese Berechnung des Gesamtgewichts im Allgemeinen. Bestimmen Sie das Gesamtgewicht der ULD wie . Dann, und . Wir können dies mithilfe der Summationsnotation reduzieren und . Da wir wollen, dass dies fĂŒr alle möglichen giltverwenden wir das Zeichen "fĂŒr alle": . Dies gibt uns die endgĂŒltige Form unserer Gesamtgewichtsgrenze:
Extra Gewicht
Nachdem wir das Gesamtgewicht haben, können wir unsere Formel fĂŒr die zusĂ€tzliche Last anwenden:
Zum Beispiel wenn und und dann zusĂ€tzliches Gewicht Kilogramm. Multiplizieren Sie dies mit dem Kostenfaktor, um das Ergebnis in Dollar zu erhalten. Auf den ersten Blick mag dies ausreichend erscheinen, aber wie sieht es aus, wenn das Gesamtgewicht der gesamten Ladung fĂŒr ULD das Standardgewicht nicht ĂŒberschreitet? In diesem Fall wĂ€re das Ăberlastgewicht eine negative Zahl, wenn wir die Ist-Formel verwenden wĂŒrden. Wenn beispielsweise das Standardgewicht 1650 Kilogramm und das zugewiesene Gesamtgewicht 1000 Kilogramm betrĂ€gt, ist Ăberlast = 1000â1650 = -650. Die Zielfunktion multipliziert diese Zahl mit einem Faktor fĂŒr Ăberlastungen und wir erhalten eine negative Zahl. Als ob der Spediteur uns fĂŒr den Versand weniger als die Kosten eines Standardgewichts bezahlt hĂ€tte.Folgendes wollen wir wirklich:.Dies entspricht dem Setzen von 0 fĂŒr eine Variable, was so einfach ist wie das Erstellen einer EinschrĂ€nkung., Also haben wir die Funktion max () in die mathematische Programmierung implementiert: a = max (b, c), dh a> = b && a> = c. Schauen wir uns unsere Definitionen an.Zielfunktion:: ULD-ĂberlastungsverhĂ€ltnis : ULD-Ăberlastung ;; UjP: Standardgewicht ULD jgi: Brutto-Versandgewicht ixi,j: Entscheidungsvariable; xi,j=1wenn Versand ivon ULD zugewiesen j, 0sonst.yj: Gesamtgewicht aller von ULD bezeichneten Sendungen j;; yj=âiâIgixi,jâjâJJede Ladung muss fliegen
Zu diesem Zeitpunkt könnten wir dies in Python schreiben und an den Solver senden. Wenn wir dies tun wĂŒrden, wĂŒrden wir feststellen, dass der Löser jedem Flug keine Lieferungen zugewiesen hat, und wir können schnell verstehen, warum: Der beste Weg, die Zielfunktion zu minimieren, besteht darin, keine Kosten zu akkumulieren. Dies fĂŒhrt zu folgender EinschrĂ€nkung: Jede Charge muss einer ULD zugeordnet werden. Wir werden dies auf jede Fracht ausweiten, die nur einer ULD zugeordnet werden soll, obwohl wir die Fracht in Wirklichkeit in mehrere ULD und sogar mehrere FlĂŒge aufteilen können.Es bedeutet dasxi,jkann nur 1 fĂŒr einen einzelnen Wert von $ j $ sein. Wenn wir zum Beispiel den Versand von 13 in Betracht ziehen, dannx13,1+x13,2+x13,3+âŠ+x13,J=1. Wir möchten diese EinschrĂ€nkung fĂŒr jede Sendung anwenden.i (was wir schreiben als âiâI), und wir können die Addition mit dem Summationsoperator reduzieren (â), also ist unsere letzte EinschrĂ€nkung:
âjâJxi,j=1âiâI
Angesichts dieser EinschrĂ€nkung beginnt der Löser tatsĂ€chlich, Sendungen FlĂŒgen zuzuweisen, verteilt die Sendungen jedoch einfach auf alle verfĂŒgbaren FlĂŒge, bis die Gewichte erreicht sind. Der Löser wĂŒrde dann jede verbleibende Sendung mit den geringsten zusĂ€tzlichen Kosten in eine ULD legen. Ohne das Volumen oder Gewicht dieser ULD. Die folgenden zusĂ€tzlichen EinschrĂ€nkungen betreffen also Volumen und Gewicht.Volumen- und GewichtsbeschrĂ€nkungen
Lass uns entscheiden UjMals maximale Nutzlast in Kilogramm ULD jund Ujals maximales Volumen in Kubikmetern ULD j. Lass uns entscheidenviund das Volumen in Kubikmetern Fracht i. Um das Modell auf die maximale TragfÀhigkeit und das maximale Volumen zu beschrÀnken, haben wir folgende Bedingungen:
yj<=UjMâjâJ
âiâIxi,jvi<=UjVâjâJ
Ein Branchenveteran wird sofort erkennen, dass dies nicht der Fall ist. Warum? Weil diese EinschrĂ€nkungen die Ladung so behandeln, als ob sie wie Wasser in ein beliebiges Volumen gegossen werden könnte. In der RealitĂ€t sind Lasten starr oder haben andere EinschrĂ€nkungen, wie z. B. Stapeln. 10 Kubikmeter Fracht können nicht in einem beliebigen Volumen von genau 10 Kubikmetern verpackt werden. Um diese FĂ€lle zu bewĂ€ltigen, mĂŒssen Sie das Problem der Verpackung in BehĂ€ltern lösen. Wir prĂŒfen, ob bestimmte Volumes in andere passen, dies geht jedoch ĂŒber den Rahmen dieses Artikels hinaus.Jetzt weist der Löser die Sendung ULD zu, wobei das maximale Gewicht und Volumen berĂŒcksichtigt und gleichzeitig die Gesamtkosten minimiert werden. Es gibt aber noch ein anderes Problem: Wir haben nichts ĂŒber die Ernennung der Artikel und die Einhaltung der Liefertermine gesagt. TatsĂ€chlich gibt es vier Zeitstempel, die Sie beim Zuweisen einer Sendung berĂŒcksichtigen mĂŒssen: DieZeit, zu der die Sendung tatsĂ€chlich bereit ist, sich mit anderen Sendungen in der ULD zu konsolidieren und den Flug zu laden. Lassen Sie uns verwendenQiâum die Zeit darzustellen, zu der die Sendung fertig ist i.Der Zeitpunkt, bis zu dem die Waren am Bestimmungsort entladen werden mĂŒssen, wird entkonsolidiert und steht in der Regel am Frachtterminal zur VerfĂŒgung. Verwenden wir $ Q_i ^ + $, um die Lieferfrist darzustelleni.Die Zeit, bis zu der die gesamte Fracht zum Laden auf den Flug zum Frachtterminal geliefert werden muss. Lassen Sie uns verwendenTjâum die Schnittzeit der Ladung ULD $ j $ darzustellen.Flugankunftszeit: Dies ist die Zeit, bis zu der die Fracht auf dem Flug im Ziellager verfĂŒgbar ist. Lassen Sie uns verwendenTj+ um die Ankunftszeit des ULD-Fluges darzustellen jQuelle und Ziel
Stellen Sie einen weiteren Satz vor Ji, die wir als eine Reihe von FlĂŒgen definieren, deren Quelle und Ziel mit dem Abflug und dem Empfang von Fracht zusammenfallen i. Mit anderen Worten, wenn Abflug 85 von Hongkong und Ziel in London ist, dann ist $ J_ {85} $ die Menge aller ULDs mit Abflug von Hongkong und Ziel in London.Jetzt können wir verwendenjâJi um ein ULD-Kit zu erhalten, das der Versandhandelsroute entspricht ioder wir können verwenden jâJium einen Satz von ULD zu erhalten, der nicht ĂŒbereinstimmt. Um die Bindung von Fracht an ULD zu verbieten, die nicht ihrer Quelle und ihrem Bestimmungsort entspricht, beschrĂ€nken wir einfachxi,j=0fĂŒr alle diese FlĂŒge. Die EinschrĂ€nkung wird vollstĂ€ndig wie folgt beschrieben:
âjâJixi,j=0âiâI
Lieferzeit
Wenn Sie mit Zeitstempeln in der Optimierung arbeiten, ist es praktisch, die erforderlichen Momente als Unix-Zeit darzustellen. Vorteile des Ansatzes:- Speichern von Daten als Zahlen.
- Keine Notwendigkeit, Zeitzonen zu behandeln.
- Der Solver verwendet direkte Vergleiche mit mehr oder weniger.
Der Flug muss vor der Lieferzeit ankommen:âjâJiTj+xi,j<=Qi+âiâIBitte beachten Sie, dass wir genau wie bei der oben genannten EinschrĂ€nkung fĂŒr Abflug und Ziel angegeben haben, dass diese EinschrĂ€nkung nur fĂŒr die ULD im Set gilt Jiwo Jiâist eine Reihe von ULDs, die dem Senden und Empfangen von Sendungen entsprechen i. Das ist alles! Schauen wir uns das ganze Modell an.Volles Modell
Unter solchen EinschrĂ€nkungen weist der Löser die ULD-Artikel auf die kostengĂŒnstigste Weise zu, wobei jede Ladung vom richtigen Abflugort zum richtigen Ziel geliefert wird. NatĂŒrlich wird die Ladung pĂŒnktlich und ohne Ăberladung der Artikel nach Volumen oder Gewicht geliefert.Parameter
I: Ein Satz aller Sendungen. Eine Sendung eingereichtiJ: Ein Satz aller ULD. Einzelne ULD ist Kleinbuchstabenj.Ji: Ein Satz aller ULDs, die mit Sender und EmpfĂ€nger ĂŒbereinstimmen i.gi: Versand Bruttogewicht iin Kilogramm.vi: Volumen in Kubikmetern Versand icjE: ULD-ĂberlastungsverhĂ€ltnis jin US-Dollar pro KilogrammUjM: Maximale GewichtskapazitĂ€t ULD jin KilogrammUjV: ULD Maximale Umgebungsleistung jin KubikmeternUjP: Standardgewicht ULD jin KilogrammTjâ: ZulĂ€ssige Lieferzeit zum ULD-Terminal j.Tj+: ULD Ankunftszeit j.Qiâ: Versandbereitschaftszeit i. Qi+: Liefertermin i.Entscheidungsvariablen und Zielfunktion:yj: ULD Gesamtgewicht jyjE: ULD-Ăberlastung jin Kilogramm.xi,j: 1 beim Senden ivon ULD zugewiesen j0 sonst.Zielfunktion
MinimizeâyjEcjE
EinschrÀnkungen
yjâ- Gesamtgewicht der Sendungen auf ULD $ j $: yj=âiâIgixi,jâjâJDas zusĂ€tzliche Gewicht jE betrĂ€gt max (0, yj-UjP):yjE>=yjâUjPâjâJyjE>=0âjâJJede Lieferung muss genau 1 ULD zugeordnet sein: âjâJxi,j=1âiâI.ULDj Maximales Gewicht darf nicht ĂŒberschritten werden: yj<=UjMâjâJULD jdarf die maximale KapazitĂ€t nicht ĂŒberschreiten: âiâIxi,jvi<=UjVâjâJWeitere Schritte
Dieser Artikel beschreibt die mathematische Programmierung, die dem Zweck der Flugbelastung zugrunde liegt. Aber nur Mathe zu schreiben ist nicht genug. Der nĂ€chste Schritt besteht darin, das Programm, wahrscheinlich in AML, wie Pyomo, zu implementieren oder eine eigene Solver-API zu verwenden, beispielsweise die Python Gurobi-API. Danach schreibt der Entwickler einen Code, um die Parameter aller verfĂŒgbaren AbflĂŒge und FlĂŒge zu ĂŒbertragen. Dann wird die Modellinstanz an den Solver gesendet. Der Solver legt die Werte der Entscheidungsvariablen optimal fest. Dann muss der Entwickler etwas mit den Werten der Entscheidungsvariablen tun.