Wir lernen die mathematische Optimierung mit von Google entwickelten OR-Tools. Der größte Teil des Inhalts basiert auf diesem Buch. Practical Python AI Projects: Mathematical Models of Optimization Problems with Google OR-Tools (English Edition)
Klicken Sie hier, um eine Liste der Codes nach Autor anzuzeigen Der in diesem Blog beschriebene Code entspricht fast dem Originalcode des Autors und ist nur teilweise auf Japanisch korrigiert. Mathematische Genauigkeit und theoretischer Kommentar haben eine niedrige Priorität. Bitte verzeih mir.
Integrieren Sie "wann" in Ihre Entscheidungen. Am Beispiel eines Lagers ändert sich die Bestellmenge für den nächsten Monat in Abhängigkeit davon, wie viele Lagerbestände Sie am Ende dieses Monats haben. Ebenso ändert sich die Bestellmenge für den nächsten Monat in Abhängigkeit von der Bestellmenge für den nächsten Monat. Berücksichtigen Sie auf diese Weise die optimale Entscheidung in einer Situation, in der die Entscheidung in einer Phase die Entscheidung in den nachfolgenden Phasen beeinflusst.
Takashi betreibt eine Seifenfabrik. Da sich die Leistung der Fabrik auf Takashis Taschengeld auswirkt, habe ich mich für eine effiziente Betriebsmethode entschieden.
Seife wird durch Scheuern und Mischen verschiedener Öle hergestellt. Öle haben verschiedene Düfte wie Aprikose und Avocado, und jedes Öl enthält verschiedene Fettsäuren (Laurin, Linol, Ölsäure usw.). Unten finden Sie eine Tabelle der in Öl $ i $ enthaltenen Fettsäuren $ A_j $. Berücksichtigen Sie auch die Eigenschaften der Seife (Waschmittel, Schaumbildung, Trockenheit der Haut usw.) richtig, damit der endgültige Fettsäuregehalt in einem bestimmten Bereich liegt. Hier wird angenommen, dass es in den Bereich der folgenden Tabelle fällt. Hier betrachten wir eine Entscheidung, die mehrere Monate umfasst. Jedes Öl kann zur sofortigen Verwendung oder für den nächsten Monat gekauft werden. Die folgende Tabelle zeigt den Preis (Dollar / t) jedes Öls für jeden Monat. Sie können bis zu 1.000 Tonnen Öl für die spätere Verwendung aufbewahren. Es gibt jedoch monatliche Lagerkosten von 5 USD pro Tonne. Darüber hinaus muss Takashis Fabrik den monatlichen Bedarf an 5.000 Tonnen Seife decken. Zu diesem Zeitpunkt hat Takashis Fabrik die in der folgenden Tabelle aufgeführten Öle.
Es ist endlich das Hauptthema. ** Wie viel Öl sollte in welchem Monat geschmolzen und gemischt werden, um die Kosten zu minimieren? </ font> ** Ah, es war lang.
Es scheint eine Determinante dafür zu sein, wie viel jedes Öl jeden Monat gemischt wird, aber das reicht nicht aus. Wenn Sie Öl verwenden, können Sie verwenden, was Sie gekauft haben oder was Sie auf Lager hatten, also unterscheiden wir zwischen ihnen. Sie müssen auch wissen, wie viel Sie bei einer Gesamtgrenze von 1.000 Tonnen für Aktien kaufen können.
Daher benötigen wir mindestens drei Determinanten für den Ölsatz $ O $ und den Monatssatz $ M $.
x_{i,j} \geq 0 \quad \forall i \in O, \forall j \in M \Quad Kauf\\
y_{i,j} \geq 0 \quad \forall i \in O, \forall j \in M \Quad gemischt\\
z_{i,j} \geq 0 \quad \forall i \in O, \forall j \in M \Quad Stock\\
$ x_ {i, j} $ ist die Menge an Öl $ i $, die im Monat $ j $ gekauft wurde, $ y_ {i, j} $ ist das Öl $ i $, das im Monat $ j $ gemischt wurde, um Seife herzustellen Was ist $ z_ {i, j} $ ist die Menge an Öl $ i $, die Sie zu Beginn von $ j $ pro Monat haben. Repräsentiert. Obwohl dies nicht unbedingt erforderlich ist, geben wir auch eine Variable für die Anzahl der Tonnen Seife an, die pro Monat hergestellt wurden. Dies erleichtert die Beschreibung von Einschränkungen. Monatliche $ j $ Seifenproduktion
t_j \quad \forall j \in M
Wird besorgt.
Sie müssen angeben, wie der Bestand jedes Öls jeden Monat schwankt. Deshalb
z_{i,j} + x_{i,j} - y_{i,j}= z_{i,j+1} \quad \forall i \in O, \forall j \in M \ {letzten Monat}
Bereiten Sie die Formel vor. Dies bedeutet, dass der Bestand am Monatsanfang zuzüglich des Kaufs für den aktuellen Monat abzüglich der Nutzung für den aktuellen Monat der Bestand für den nächsten Monat ist.
Da es monatlich Unter- und Obergrenzen für die Kapazität des Lagers gibt,
C_{min} \leq \sum_{i} z_{i,j} \leq C_{max} \quad \forall j \in M
Als nächstes kommt die Mischungsbeschränkung. Es gab eine Regelung über den Bereich der Fettsäuren im Endprodukt. Wir werden die monatliche Produktion $ t_j = \ sum_ {i} y_ {i, j} \ quad \ forall j \ in M $ verwenden. Es gibt eine Reihe von Fettsäuren $ A $ und für jede Fettsäure $ k \ in A $ den angegebenen Bereich $ [l_k, u_k] $ und das Verhältnis der in Öl $ i $ p_ {i, k} $ enthaltenen Fettsäuren $ k $ Nachdenken über. Dann gibt es zwei Formeln für den Bereich des Fettsäuregehalts, die Untergrenze und die Obergrenze.
\sum_i y_{i,j} p_{i,k} \geq l_k t_j \quad \forall k \in A, \forall j \in M \\
\sum_i y_{i,j} p_{i,k} \leq u_k t_j \quad \forall k \in A, \forall j \in M
Schließlich müssen wir den monatlichen Bedarf decken (obwohl er diesmal konstant bei 5.000 t liegt). Angesichts der monatlichen Nachfrage von $ j $ $ D_j $,
t_j \geq D_j \quad \forall j \in M
Der Zweck dieser Zeit war es, die Kosten zu minimieren. Das heißt, um die Summe der Anschaffungs- und Lagerkosten für Öl zu minimieren. Der Kaufpreis variiert je nach Öl und Monat, die Lagerkosten pro Tonne sind jedoch fest. Daher ist die Zielfunktion
\sum_i \sum_j x_{i,j} P_{i,j} + \sum_i \sum_j z_{i,j}p
$ P_ {i, j} $ ist der monatliche Stückpreis von Öl $ i $ und $ p $ sind die Lagerkosten pro Tonne (diesmal $ 5).
Hier ist der Code zur Lösung dieses Beispiels. my_or_tools.py
und tableutils.py
Den Inhalt finden Sie unter Autor GitHub.
blend_multi.py
from my_or_tools import SolVal, ObjVal, newSolver
def solve_model(Part,Target,Cost,Inventory,D,SC,SL):
#Part:Tabelle der Öle und Fettsäuren,Target:Regulierung des Fettsäuregehalts,Cost:Ölkaufkosten,Inventory:Anfangsbestand,
#D:Nachfrage nach Seife,SC:Öllagerungskosten,SL:Auswahl an Ölen, die Sie auf Lager haben können
s = newSolver('Multi-period soap blending problem') #Löser deklarieren
Oils= range(len(Part)) #Anzahl der Ölsorten
Periods, Acids = range(len(Cost[0])), range(len(Part[0])) #Anzahl der Perioden,Arten von Fettsäuren
Buy = [[s.NumVar(0,D,'') for _ in Periods] for _ in Oils] #Determinantenvariable x. Wie viel Öl muss ich im Monat kaufen? J.
Blnd = [[s.NumVar(0,D,'') for _ in Periods] for _ in Oils] #Determinantenvariable y. Wie viele Öle soll ich für den Monat verwenden? J.
Hold = [[s.NumVar(0,D,'') for _ in Periods] for _ in Oils] #Determinantenvariable z. Wie viele Öle habe ich pro Monat auf Lager? J.
Prod = [s.NumVar(0,D,'') for _ in Periods] #Hilfsvariablen. Seife produziert am Monat j
CostP= [s.NumVar(0,D*1000,'') for _ in Periods] #Hilfsvariablen. Monat j Anschaffungskosten
CostS= [s.NumVar(0,D*1000,'') for _ in Periods] #Hilfsvariablen. Lagerkosten für Monat j
Acid = [[s.NumVar(0,D*D,'') for _ in Periods] for _ in Acids] #Hilfsvariablen. Menge der im Monat j produzierten Fettsäure k
for i in Oils:
s.Add(Hold[i][0] == Inventory[i][0]) #Einschränkungen. Der Lagerbestand zum Zeitpunkt der Entscheidung ist angegeben
for j in Periods:
s.Add(Prod[j] == sum(Blnd[i][j] for i in Oils)) #Einschränkungen. Die monatliche Produktion ist die Summe der verwendeten Ölmenge
s.Add(Prod[j] >= D) #Einschränkungen. Die Produktion im Monat j muss die Nachfrage dieses Monats übersteigen
if j < Periods[-1]: #Ohne den letzten Monat
for i in Oils:
s.Add(Hold[i][j]+Buy[i][j]-Blnd[i][j] == Hold[i][j+1]) #Einschränkungen.(Lager am Monatsanfang)+(Kaufbetrag)-(Menge zu verwenden)=(Lager Anfang nächsten Monats)
s.Add(sum(Hold[i][j] for i in Oils) >= SL[0]) #Einschränkungen. Untergrenze des Öls, das gelagert werden kann
s.Add(sum(Hold[i][j] for i in Oils) <= SL[1]) #Einschränkungen. Obergrenze des Öls, das gelagert werden kann
for k in Acids:
s.Add(Acid[k][j]==sum(Blnd[i][j]*Part[i][k] for i in Oils)) #Einschränkungen. Die Menge an Fettsäure k, die im Monat j produziert wird, ist die Summe der Produkte aus der Menge an verwendetem Öl und dem Gehalt an Fettsäure k in diesem Öl.
s.Add(Acid[k][j] >= Target[0][k] * Prod[j]) #Einschränkungen. Untergrenze der Fettsäure-k-Produktion
s.Add(Acid[k][j] <= Target[1][k] * Prod[j]) #Einschränkungen. Obergrenze der Fettsäure-k-Produktion
s.Add(CostP[j] == sum(Buy[i][j] * Cost[i][j] for i in Oils)) #Einschränkungen. Die Anschaffungskosten für Monat j sind die Summe aus dem Produkt aus Kaufbetrag und Preis.
s.Add(CostS[j] == sum(Hold[i][j] * SC for i in Oils)) #Einschränkungen. Die Lagerkosten für den Monat j sind die Summe aus dem Produkt aus Inventar und Lagerkosten.
Cost_product = s.Sum(CostP[j] for j in Periods) #Zielfunktion. Gesamtkaufkosten
Cost_storage = s.Sum(CostS[j] for j in Periods) #Zielfunktion. Gesamtspeicherkosten
s.Minimize(Cost_product+Cost_storage) #Minimieren Sie die Summe der gesamten Anschaffungskosten und der gesamten Lagerkosten
rc = s.Solve()
B,L,H,A = SolVal(Buy),SolVal(Blnd),SolVal(Hold),SolVal(Acid)
CP,CS,P = SolVal(CostP),SolVal(CostS),SolVal(Prod)
return rc,ObjVal(s),B,L,H,P,A,CP,CS
my_blend_multi.py
from blend_multi import solve_model
Content = [#Öl und Fettsäuren enthalten
[36,20,33,6,4,0,1],
[0,68,13,0,0,8,11],
[0,6,0,66,16,5,7],
[0,32,0,0,0,14,54],
[0,0,49,3,39,7,2],
[45,0,40,0,15,0,0,0],
[0,0,0,0,0,28,72],
[36,55,0,0,0,0,9],
[12,48,34,0,4,2,0]
]
Target = [#Regulierung des Fettsäuregehalts
[13.3,23.2,17.8,3.7,4.6,8.8,23.6],
[14.6,25.7,19.7,4.1,5.0,9.7,26.1]
]
Price = [#Monatlicher Ölpreis
[118,128,182,182,192],
[161,152,149,156,174],
[129,191,118,198,147],
[103,110,167,191,108],
[102,133,179,119,140],
[127,100,110,135,163],
[171,166,191,159,164],
[171,131,200,113,191],
[147,123,135,156,116]
]
Inventory = [#Anfangsbestand
[15],[52],[193],[152],[70],[141],[43],[25],[89]
]
def main():
import sys
import tableutils
m=len(Content)
n=len(Content[0])
k=len(Price[0])
if len(sys.argv)<=1:
print('Usage is main [content|target|cost|inventory|run] [seed]')
return
""" elif len(sys.argv)>2:
random.seed(int(sys.argv[2])) """
C = Content
T = Target
K = Price
I = Inventory
if sys.argv[1]=='content': #Ausgabetabelle von Ölen und enthaltenen Fettsäuren
for j in range(m):
C[j].insert(0,'O'+str(j))
C.insert(0,['']+['A'+str(i) for i in range(n)])
tableutils.printmat(C,False,1)
elif sys.argv[1]=='target': #Ausgabe der Regulierung des Fettsäuregehalts
T.insert(0,['']+['A'+str(i) for i in range(n)])
T[1].insert(0,'Min')
T[2].insert(0,'Max')
tableutils.printmat(T,True,1)
elif sys.argv[1]=='cost': #Monatlichen Ölpreis ausgeben
for j in range(m):
K[j].insert(0,'O'+str(j))
K.insert(0,['']+['Month '+str(i) for i in range(k)])
tableutils.printmat(K)
elif sys.argv[1]=='inventory': #Geben Sie das zum Zeitpunkt der Entscheidung gehaltene Inventar aus
for j in range(m):
I[j].insert(0,'O'+str(j))
I.insert(0,['Oil','Held'])
tableutils.printmat(I)
elif sys.argv[1]=='run': #Führen Sie den Solver aus
Demand=5000 #Monatliche Nachfrage nach Seife
Limits=[0,1000] #Unter- und Obergrenze, die Sie auf Lager haben können
Cost=5
rc,Value,B,L,H,P,A,CP,CS=solve_model(C,T,K,I,Demand,Cost,Limits)
if len(B):
A.append([0 for l in range(len(A[0]))])
for j in range(len(A)-1):
for l in range(len(A[0])):
A[j][l] = A[j][l]/P[l]
A[-1][l] += A[j][l]
for j in range(m):
B[j].insert(0,'O'+str(j))
L[j].insert(0,'O'+str(j))
H[j].insert(0,'O'+str(j))
for l in range(n):
A[l].insert(0,'A'+str(l))
A[-1].insert(0,'Total')
B.insert(0,['Buy qty']+['Month '+str(i) for i in range(k)])
L.insert(0,['Blend qty']+['Month '+str(i) for i in range(k)])
H.insert(0,['Hold qty']+['Month '+str(i) for i in range(k)])
A.insert(0,['Acid %']+['Month '+str(i) for i in range(k)])
P=[P]
P[0].insert(0,'Prod qty')
CP=[CP]
CP[0].insert(0,'P. Cost')
CS=[CS]
CS[0].insert(0,'S. Cost')
tableutils.printmat(B,True,1)
tableutils.printmat(L,True,1)
tableutils.printmat(H,True,1)
tableutils.printmat(P,True,1)
tableutils.printmat(CP,True,2)
tableutils.printmat(CS,True,2)
tableutils.printmat(A,True,1)
main()
Das Ausführen des obigen Codes führt zu folgenden Ergebnissen:
Takashi konnte die Seifenfabrik gut betreiben.
Hier sind einige der möglichen Entwicklungen dieses Beispiels. ・ Die monatliche Nachfrage schwankt
Diesmal bin ich wirklich müde
Recommended Posts