In Lektion wurden zwar schon mehrere Standorte mit eigener Produktion betrachtet, aber Verkauf und Lager wurden kollektiv behandelt. In dieser Lektion soll nun das Modell aus Lektion 5 so erweitert werden, dass jeder Standort seine Produktion und sein Lager selbst verwaltet. Zudem soll es möglich sein, die Produkte zwischen den Standorten bedarfsgerecht zu transportieren, wobei allerdings angenommen wird, dass die Transportzeiten klein im Vergleich zur Länge der Monatszeitscheiben sind und somit zu Null gesetzt werden.En la sesión 5, usted encontró un modelo para una compañía de producción.
Um dieses Ziel zu erreichen, werden zwei weitere sogenannte Alias-Indizes, toplant und fromplant eingeführt werden, die bei einem Transportvorgang den Ursprungs- und Zielstandort angeben. Da jeder Standort nun seine eigene Produktion und Lager verwaltet, müssen ausserdem die Lager- und Verkaufs-Variablen entsprechend angepasst werden, sodass sie vom plant-Index abhängen.
Los Modelos que permiten embarques entre localizaciones son algunas veces llamados Modelos de Distribución o de Transporte. Normalmente, en modelos de transporte, usted tiene orígenes con cierta disponibilidad, destinos con ciertos requerimientos, y usted necesita embarcar los productos desde esos orígenes a esos destinos. En algunos casos, usted tiene modelos de transporte con multiples niveles. Por ejemplo, pueden haber embarques desde las plantas hacia los depósitos, y desde esos depósitos a las tiendas de ventas al por menor.
Modelle, die Transport zwischen verschiedenen Standorten erlauben, werden manchmal auch Transport- oder Distributions-Modelle genannt. In solchen Modellen werden typischerweise Quellen mit bestimmten Materialverfügbarkeiten und Bestimmungsorte mit bestimmten Nachfragen abgebildet, zwischen denen Produkte transport werden sollen. Hierbei können Transporte mehrstufig verknüpft sein. Beispielsweise soll ein Transport zunächst von einem Produktionsstandort zu einem Depot erfolgen und dann von einem solchen Depot zu einem Verteillager.
Sind in einem Transportmodell keine spezifischen Quellen und Senken spezifiziert, d.h. jeder Standort kann sowohl Ware versenden als auch empfangen, so spricht man auch von ungerichteten Transportmodellen. Hierbei kann es im Extremfall vorkommen, dass von jedem beliebigen Standort ein Transport zu jedem anderen Standort erfolgen kann.
Alias-Indizes finden Verwendung, wenn ein Vektor mehrfach vomselben Index abhängt. Sollen Produkte zwischen Standorten transport werden, so wird ein Variablenvektor benötigt, der diese Transportmengen als Entscheidungsvariablen repräsentiert. Da die Ausgangs- und Bestimmungsorte der Transportvorgänge Elemente derselben Menge, nämlich der Menge aller Standorte sind, werden hier zwei Alias-Indizes benötigt: einer für die Ursprungsorte und einer für die Bestimmungsorte.
Bei der Verwendung mehrdimensionaler Vektorvariablen tritt häufig der Fall auf, dass nicht alle Elemente des Vektors erlaubt oder eine sinnvolle Bedeutung haben. In einem ungerichteten Transportmodell ist es z.B. nicht sinnvoll, einen Transport von einem Standort zu sich selbst zuzulassen. In MPL können solche logische Bedingungen mit der Schlüsselwort WHERE modelliert werden. Damit kann die Erzeugung nicht sinnvoller Elemente und damit ein unötiges Anwachsen der Modellgröße vermieden werden.
Das folgende Beispiel zeigt, wie der Transport eines Standort zu sich selbst vermieden werden kann:
VARIABLES Ship[fromplant,toplant] WHERE (fromplant <> toplant);
In diesem Beispiel eliminiert die Bedingung (fromplant <> toplant) alle Vektorelemente, bei denen Ausgangs- und Bestimmungsort identisch sind.
Logische Bedingung treten aber nicht nur in Verbindung mit Vektorvariablen auf und sind auch nicht unbedingt vom Index abhängig. Im Zusammenhang mit Datenvektoren kann z.B. der Transportkostenvektor für nicht erlaubte Transportwege auf den Wert Null gesetzt werden. Damit ist es dann möglich, bei der Definition der Transportvariablen unerlaubte Transportwege dadurch auszuschliessen, indem wie im folgenden Beispiel getestet wird, ob die Transportkosten Null sind:
VARIABLES Ship[fromplant,toplant] WHERE (ShipCost[fromplant,toplant] > 0);
Bei Transportmodellen, insbesondere den ungerichteten, ist für jeden Standort sicherzustellen, dass die Summe aus eingehenden Transportmengen, produzierter und aus dem Lager entnommener Menge gerade der Summe aus abgehender Transportmenge, verkaufter Menge und der Menge, die im Lager verbleibt, entspricht. In Kurzform bedeutet dies, dass die Menge der Eingangs- und Ausgangsströme gleich sind. Solche Bilanzgleichungen werden auch Massenerhaltungs- oder Transportbilanzgleichungen genannt. Nachfolgend dafür ein Beispiel:
PlantBal[plant, product, month]: Produce + Inventory[month-1] + SUM(fromplant: Ship[fromplant, toplant:=plant]) = Sales + Inventory + SUM(toplant: Ship[fromplant:=plant, toplant]);
Diese Bilanzgleichung hat natürlich ein ähnliche Form wie die Lagerbilanzgleichung in Lektion 5; sie enthält lediglich die zusätzlichen Terme für die Summen der ein- und ausgehenden Transportmengen.
Die Zuweisung 'toplant:=plant' im ersten Summanden definiert lokal und nur für die Bedingung PlantBal, die Indexmenge toplant als identisch mit der Indexmenge plant. Die Summe ergibt dann die Lieferung aller eingehenden Transportmengen in die betrachtete Anlage. Entsprechend ordnet die Zuweisung 'fromplant:=plant' in der Summe der Indexmenge fromplant die Elemente der Indexmenge plant zu.
In dieser Lektion wird, aufbauend auf der Formulierung in Lektion 5, ein neues Modell erzeugt, in dem jeder Standort jetzt als separate Nachfragelokation mit eigenem Lager betrachtet wird.
Da nun jeder Standort nicht nur Produkte produzieren, sondern auch verkaufen kann, wird die Nachfrage, wie in der nachfolgenden Tabelle spezifiziert, als abhängig von Standort, Produkt und Monat aufgefasst:
Plant | Product | Jan | Feb | Mar | Apr |
---|---|---|---|---|---|
p1 | A1 | 4300 | 4200 | 6400 | 5300 |
A2 | 4500 | 5400 | 6500 | 7200 | |
A3 | 5400 | 6700 | 7800 | 8200 | |
p2 | A1 | 5100 | 6200 | 5400 | 7600 |
A2 | 6300 | 7100 | 5200 | 6300 | |
A3 | 4800 | 6500 | 5000 | 7200 | |
p3 | A1 | 4100 | 6100 | 4700 | 5800 |
A2 | 5300 | 5200 | 5700 | 4100 | |
A3 | 4200 | 4100 | 5200 | 6300 | |
p4 | A1 | 4300 | 4100 | 5300 | 4500 |
A2 | 5300 | 6400 | 4200 | 6200 | |
A3 | 5600 | 5200 | 3800 | 4100 |
Diese Daten hängen von den drei Dimensionen Standort, Produkt und Zeit (Monat) ab. Lineare Optimierungsmodelle enthalten häufig Daten und Strukturen, die von bis zu 8 Dimensionen abhängen dürfen. In der nächsten Lektion werden die Nachfragedaten nochmals um eine weitere Dimension, dem Anlagenindex, erweitert und somit zu einem vierdimensionalen Datenvektor.
Die Lagerkapazität ist nun auch für jeden Standort separat zu spezifizieren. Die Daten lauten hier: 800, 400, 500 und 400.
Weiterhin werden nun, da jeder Standort ein eigenes Lager unterhält, auch die Lagerkosten sowohl von Produkt als auch Standort abhängen. Die nachfolgende Tabelle spezifiziert diese:
Inventory Cost | A1 | A2 | A3 |
---|---|---|---|
p1 | $8.50 | $7.00 | $6.50 |
p2 | $9.80 | $9.80 | $9.80 |
p3 | $7.50 | $7.50 | $7.50 |
p4 | $9.30 | $8.00 | $6.50 |
Schließlich werden noch die mit dem Transport verbundenen Kosten benötigt:
Shipping Cost | p1 | p2 | p3 | p4 |
---|---|---|---|---|
p1 | - | $15.00 | $21.00 | $13.00 |
p2 | $16.00 | - | $12.00 | $12.00 |
p3 | $14.00 | $17.00 | - | $15.00 |
p4 | $21.00 | $13.00 | $10.00 | - |
Wie erwartet, enthält die Tabelle keine Transportkosten, in denen Ausgangs- und Bestimmungsort identisch sind. Dieser Fall könnte lediglich sinnvoll sein, wenn von Null verschiedene Transportzeiten betrachtet würden, da sich dann für eine kurze Zeit zusätzliche Lagerkapazität ergeben würde.
Nachstehend ist das vollständige Modell für das Problem Planning6 aufgelisted. Gegenüber der Formulierung in Lektion 5 sind einige Erweiterungen erkennbar; sie sind im Fettdruck hervorgehoben und leicht zu verfolgen.
TITLE Production_Planning6; INDEX product := (A1, A2, A3); month := (Jan, Feb, Mar, Apr); plant := (p1, p2, p3, p4); fromplant := plant; toplant := plant; DATA Price[product] := (120.00, 100.00, 115.00); Demand[plant, product, month] := DATAFILE("Demand6.dat"); ProdCost[plant, product] := DATAFILE("ProdCost.dat"); ProdRate[plant, product] := DATAFILE("ProdRate.dat"); ProdDaysAvail[month] := (23, 20, 23, 22); InvtCost[plant, product] := DATAFILE("InvtCost.dat"); InvtCapacity[plant] := (800, 400, 500, 400); ShipCost[fromplant, toplant] := DATAFILE ("ShipCost.dat"); VARIABLES Produce[plant, product,month] -> Prod; Inventory[plant, product, month] -> Invt; Sales[plant,product, month] -> Sale; Ship[product, month, fromplant, toplant] WHERE (fromplant <> toplant); MACROS TotalRevenue := SUM(plant, product,month: Price * Sales); TotalProdCost := SUM(plant, product, month: ProdCost* Produce); TotalInvtCost := SUM(plant, product, month: InvtCost * Inventory); TotalShipCost := SUM(product, month, fromplant,toplant: ShipCost * Ship); TotalCost := TotalProdCost + TotalInvtCost + TotalShipCost; MODEL MAX Profit= TotalRevenue - TotalCost; SUBJECT TO ProdCapacity[plant, month] -> PCap: SUM(product: Produce / ProdRate) <= ProdDaysAvail; PlantBal[plant, product, month] -> PBal: Produce + Inventory[month-1] + SUM(fromplant:Ship[fromplant, toplant:=plant]) = Sales + Inventory + SUM(toplant: Ship[fromplant:=plant,toplant]); MaxInventory[plant, month] -> MaxI: SUM(product: Inventory) <= InvtCapacity; BOUNDS Sales < Demand ; END
Start der MPL Applikation.
Wähle File | Open und öffne die Modelldatei Planning5.mpl aus der vorherigen Lektion.
Wähle File | Save As zum Speichern der neuen Modelldatei Planning6.mpl.
Der Titel des Modells soll geändert werden um klarzustellen, dass nun mit der Modelldatei Planning6 gearbeitet wird.:
TITLE Production_Planning6;
In dieser Lektion wird das Modell nun um den Transport zwischen den Standorten erweitert. Vektoren, in denen die Elemente einer Indexmenge mehrfach als Indizes auftreten, lassen sich nutzbringend mit sogenannten Alias-Indizes bzw. aktuellen Indizes konstruieren. Derartige Indexmengen sind exakte Kopien von bereits definierten Indenxmengen. In bestimmten Situation greifen sie aber nur das jeweilige, aktuelle Element einer Indexmenge heraus.
Zunächst soll nun eine Vektorvariable erzeugt werden, die beschreibt, wieviel zwischen zwei jeweiligen Standorten transportiert wird. Dazu sind zwei Alias-Indizes zu erzeugen, eine zur Beschreibung der Ausgangsstandorte und eine zur Darstellung der Bestimmungsorte. Am Ende des INDEX-Abschnittes sollen nun die beiden Alias-Indizes fromplant und toplant hinzugefügt werden:
INDEX product := (A1, A2, A3); month := (Jan, Feb, Mar, Apr); plant := (p1, p2,p3, p4); fromplant := plant; toplant := plant;
Da die Nachfrage jetzt auch vom Standort abhängt, muss der plant Index in den Demand-Datenvektor aufgenommen werden. Im Modelleditor wird der plant-Index nun zum Demand-Datenvektor hinzugefügt und der Dateiname zu Demand6.dat geändert.
DATA Price[product] := (120.00, 100.00, 115.00); Demand[plant, product, month] := DATAFILE("Demand6.dat");
Da der Demand-Vektor nun von drei Indizes abhängt, muss auch die Datei Demand.dat, die die Nachfragen enthält, aktualisiert werden. Dazu sind die folgenden Daten einzugeben:
! ! Demand6.dat - Demand for each product and each plant ! ! Demand[plant,product,month]: ! ! Jan Feb Mar Apr ! --------------------------- !plant 1: 4300, 4200, 6400, 5300, 4500, 5400, 6500, 7200, 5400, 6700, 7800, 8200, !plant 2: 5100, 6200, 5400, 7600, 6300, 7100, 5200, 6300, 4800, 6500, 5000, 7200, !plant 3: 4100, 6100, 4700, 5800, 5300, 5200, 5700, 4100, 4200, 4100, 5200, 6300, !plant 4: 4300, 4100, 5300, 4500, 5300, 6400, 4200, 6200, 5600, 5200, 3800, 4100
Bei dreidimensionalen Daten ist sorgfältig auf die Reihenfolge der Eingabe zu achten. Die Daten müssen in derselben Ordnung eingegeben werden, in der die Indizes definiert sind. Der Index, der am weitesten rechts (im Beispiel: month) in der Definiton steht, variiert am schnellsten; entsprechend der am weitesten links stehende (im Beispiel: plant) am langsamsten. Daraus resultiert in obiger Tabelle, dass in jeder Zeile alle Informationen für ein bestimmtes Produkt an einem bestimmten Standort stehen.
Wegen der Standortabhängigkeit der Läger wird nun der plant-Index zur Deklaration des InvtCost-Datenvektors und der InvtCapacity-Datenkonstante hinzugefügt. Die Daten, die für den InvtCost-Datenvektor definiert wurden, werden entfernt und durch das Schlüsselwort DATAFILE und den Dateinamen 'InvtCost.dat.' ersetzt. Der Wert 800, der der Datenkonstante zugeordnet wurde, wird durch eine Liste von vier Werten, ein jeder für einen der vier Standorte, ersetzt.
InvtCost[<b>plant</b>, product] := <b>DATAFILE("InvtCost.dat")</b>; InvtCapacity<b>[plant]</b> := <b>(800, 400, 500, 400)</b>;
Danach ist die neue Datei 'InvtCost.dat' zu erzeugen; sie enthält die Lagerkosten, wie sie in der Problembeschreibung spezifiziert wurden:
! ! InvtCost.dat - Inventory cost per item a month ! ! InvtCost[plant,product]: ! ! A1 A2 A3 ! ----------------------- 8.50, 7.00, 6.50 9.80, 9.80, 9.80 7.50, 7.50, 7.50 9.30, 8.00, 6.50
Zur Definition der Transportkosten wird im Modelleditor der neue Datenvektor ShipCost über die beiden Alias-Indizes fromplant und toplant definiert und über das Schlüsselwort DATAFILE mit der Datei ShipCost.dat verknüpft.
ShipCost[fromplant, toplant] := DATAFILE("ShipCost.dat");
Dazu ist nun natürlich noch die Datei ShipCost.dat mit den entsprechenden Daten zu erzeugen:
! ! ShipCost.dat - Costos de embarque de planta a planta ! ! ShipCost[fromplant, toplant] ! 0, 15.00, 21.00, 13.00, 16.00, 0, 12.00, 12.00, 14.00, 17.00, 0, 15.00, 21.00, 13.00, 10.00, 0,
Die Transportmengen sollen durch den Variablenvektor Ship repräsentiert werden. Dieser Variablenvektor hängt von den Alias-Indizes fromplant und toplant sowie von Indizes product und month ab. Seine Definition erfolgt wie folgt im Abschnitt VARIABLES:
Ship[product, month, fromplant, toplant] WHERE (fromplant <> toplant);
Da der Transport eines Produktes von einem Ausgangsort zu sich selbst ausgeschlossen werden soll, werden in der Definition mit Hilfe des WHERE-Schlüsselwortes die entsprechenden Vektorelemente ausgeschlossen.
Im MACROS-Abschnitt wird der zusätzliche Makro TotalShipCost definiert und der existierende Makro TotalCost enstprechend aktualisiert:
TotalShipCost := SUM(product, month, fromplant, toplant: ShipCost * Ship); TotalCost := TotalProdCost + TotalInvtCost + TotalShipCost;
Die Zielfunktion selbst braucht nicht geändert zu werden, da der Makro TotalCost bereits alle Änderungen enthält.
Die existierenden Lagerbilanzgleichungen sind nun um die ein- und ausgehenden Transportmengen zu erweitern und werden damit zu Standortbilanzgleichungen. Deshalb wird zunächst der Name InvtBal in PlantBal umgeändert und der Index plant zur Deklaration hinzugefügt. Da nun die Nebenbedingung selbst vom plant-Index abhängt, braucht in der Summe der Produce-Variablen nicht mehr über den plant-Index summiert zu werden.
PlantBal[plant, product, month] -> PBal: Produce + Inventory[month-1] + SUM (fromplant:Ship[fromplant, toplant:=plant]) = Sales + Inventory + SUM(toplant: Ship[fromplant:=plant, toplant]);
Auf der linken Seite dieser Bilanzgleichung sind die Massenströme berücksichtigt, die in den Standort einfliessen, also die eingehenden Transportmengen sowie das, was neu produziert wird. Zu beachten ist, dass das die Summe alle möglichen Ausgangsorte berücksichtigt, die den aktuellen Standort beliefern können. Als Bestimmungsort wird im Argument der Ship-Variable mit Hilfe des Alias-Indexes toplant der aktuelle Standort, d.h. das aktuelle Element der Indexmenge plant gewählt.
Auf der rechten Seite der Bilanzgleichung sind die abfliessenden Materialströme zusammengefasst. Diesmal spielt im Argument der Ship-Variablen der aktuelle Standort die Rolle des aktuellen Indexes.
Der nächste Schritt besteht darin, das durch 'Planning6.mpl' kodierte Problem zu lösen. Hierzu wird im Run-Menu die Option Solve CPLEX gewählt. Sofern alle Daten richtig eingegeben und alle Modifikationen korrekt durchgeführt wurden, meldet sich MPL mit der Meldung Optimal Solution Found zurück. Bei Identifizierung eines Syntaxfehlers ist die Eingabe des Modells nocheinmal zu überprüfen.
Wie schon in Lektion 5, sollen mit Hilfe des Modelldefinitionsfensters lediglich die hier interessierenden Aspekte der Lösung angezeigt werden. Dazu wird für das Planning6-Modell Model Definitions aus dem View-Menu gewählt.
Das Modell-Definitions-Fenster für das Planning6-Modell
Um die Werte der Produktions-Variablen zu inspizieren, wird das Produce-Objekt im Baum gewählt und mit der View-Taste bestätigt. Dies erzeugt ein Fenster, dass die von Null verschiedenen Produktions-Variablen anzeigt.
VARIABLE Produce[plant,product,month] : plant product month Activity Reduced Cost ----------------------------------------------------------- p1 A1 Jan 4300.0 0.0 p1 A1 Feb 4200.0 0.0 p1 A1 Mar 6400.0 0.0 p1 A1 Apr 5300.0 0.0 p1 A2 Jan 1080.0 0.0 p1 A3 Jan 5400.0 0.0 p1 A3 Feb 5220.0 0.0 p1 A3 Mar 4590.0 0.0 p1 A3 Apr 5130.0 0.0 p2 A1 Jan 5100.0 0.0 p2 A1 Feb 6200.0 0.0 p2 A1 Mar 5400.0 0.0 p2 A1 Apr 7600.0 0.0 p2 A2 Jan 6177.3 0.0 p2 A2 Feb 3927.3 0.0 p2 A2 Mar 5931.8 0.0 p2 A2 Apr 3681.8 0.0 p3 A1 Jan 4100.0 0.0 p3 A1 Feb 6100.0 0.0 p3 A1 Mar 4700.0 0.0 p3 A1 Apr 5800.0 0.0 p3 A3 Jan 4166.7 0.0 p3 A3 Feb 1933.3 0.0 p3 A3 Mar 3766.7 0.0 p3 A3 Apr 2733.3 0.0 p4 A1 Jan 3850.0 0.0 p4 A1 Feb 2828.6 0.0 p4 A1 Mar 5300.0 0.0 p4 A1 Apr 4500.0 0.0 p4 A3 Jan 5600.0 0.0 p4 A3 Feb 5200.0 0.0 p4 A3 Mar 4677.3 0.0 p4 A3 Apr 4836.4 0.0 -----------------------------------------------------------
Man bemerkt nun, dass die Produktion zwischen den einzelnen Standorten effizienter verteilt ist. Einige Produkte werden unter Berücksichtigung der Produktions- und Transportkosten sinnvollerweise an bestimmten Standorten produziert. So wird z.B. das Produkt A2 an den Standorten p1 und p2 produziert, nicht aber in p3 und p4, während das Produkt A3 an den Standorten p1, p3 und p4 produziert wird. Produkt A1 wird an allen Standorten produziert.
Verwendet man das Modell-Definitions-Fenster nun, um die Ship-Variablen genauer anzuschauen, so erhält man die folgenden Werte:
VARIABLE Ship[product,month,fromplant,toplant] : product month fromplant toplant Activity Reduced Cost ------------------------------------------------------------------------ A2 Mar p2 p4 331.8 0.0 A3 Mar p4 p3 877.3 0.0 A3 Apr p4 p3 736.4 0.0 ------------------------------------------------------------------------
Hier sehen wir den Vorschlag, Produkt A2 vom Standort p2 zum Standort p4 sowie Produkt A3 von p4 nach p3 zu transportieren. Offensichtlich bieten die Standorte p2 und p4 zusätzliche Kapazitäten zu niedrigeren Kosten; diese Kapazitäten werden genutzt, um die Nachfragen der Standorte p4 und p3 zu bedienen.