In meinem Unternehmen entwickle ich Software mithilfe der Technologie zur Kombinationsoptimierung (z. B. Minimierung der Transportkosten in der Logistik). Früher habe ich Optimierungsmodelle mit C ++ und C # erstellt, heute verwende ich häufig Python. Hier werden wir Python in die Optimierung einführen.
Die Gründe für die Verwendung von Python sind folgende.
--Einfach zu verstehen. Da das Modell nach mathematischer Formel und das Modell nach Python nahe beieinander liegen, können Sie sich auf wesentlichere Beschreibungen konzentrieren und ein Modell erstellen, das einfach zu warten ist.
--Kurzbeschreibungsbetrag ist erforderlich. Die Größe des Programms ist ein Bruchteil der von C ++.
Python soll langsamer laufen als Compilersprachen wie C ++. Bei der Optimierung wird Python jedoch hauptsächlich für die Modellerstellung (Modellierung) und für die Ausführung von Optimierungsalgorithmen in C ++ usw. geschriebene dedizierte Software (Solver) verwendet. Selbst wenn Sie Python zur Optimierung verwenden, spielt die Ausführungszeit daher keine große Rolle.
Bei der Optimierungsmodellierung werden hauptsächlich die Pakete PuLP und Pandas verwendet.
--PuLP ist ein mathematisches Modellierungspaket und pandas ist ein Datenanalysepaket. --Pandas eignet sich für den Umgang mit Daten, die in einer Tabelle unter den im Modell enthaltenen Daten ausgedrückt werden können, und kann die komplizierte Verarbeitung auf leicht verständliche Weise beschreiben. Pandas verwendet Numpy auch intern. --Numpy verwendet eine hochoptimierte lineare Algebra-Bibliothek, die in C oder Fortran geschrieben ist, und kann Matrixberechnungen effizient berechnen.
Führen Sie die folgenden Schritte aus, um das mathematische Optimierungsproblem zu lösen:
--Erstellen Sie mit dem Modellierer ein mathematisches Modell
Solver ist eine Software, die ein mathematisches Modell als Eingabe verwendet, das mathematische Modell löst und den Wert (die Lösung) einer Variablen ausgibt.
PuLP ist eine vom COIN-Projekt erstellte Software und wird ein Modellierer sein. Mit PuLP können Sie verschiedene Löser wie CBC, Gurobi und GLPK verwenden. Standardmäßig wird CBC verwendet. Wenn Sie PuLP installieren, wird CBC gleichzeitig installiert.
--CBC: COIN Project Free Solver (kurz für COIN-OR Branch and Cut) https://projects.coin-or.org/Cbc
Das Problem, das PuLP bewältigen kann, ist das Optimierungsproblem für gemischte Ganzzahlen. Das gemischte ganzzahlige Optimierungsproblem ist eine Art mathematisches Optimierungsproblem und weist die folgenden Eigenschaften auf.
Weitere Informationen finden Sie auf der Referenzseite.
Betrachten Sie das folgende Problem.
Problem
Ich möchte viele chemische Produkte X und Y herstellen, die aus den Materialien A und B synthetisiert werden können.
Um 1 kg X herzustellen, benötigen Sie 1 kg A und 3 kg B.
Um 1 kg Y herzustellen, benötigen Sie 2 kg A und 1 kg B.
Der Preis für X und Y beträgt 100 Yen pro kg.
Um die Summe der Preise von X und Y zu maximieren, wenn Material A nur 16 kg und B nur 18 kg wiegt
Finden Sie heraus, wie viele X und Y erstellt werden sollen.
Das mathematische Modell des Problems ist wie folgt. Die Darstellung eines mathematischen Modells mit einem Ausdruck wird als Formalisierung bezeichnet.
Lassen Sie uns dies mit PuLP modellieren und lösen.
python3
from pulp import *
m = LpProblem(sense=LpMaximize) #Mathematisches Modell
x = LpVariable('x', lowBound=0) #Variable
y = LpVariable('y', lowBound=0) #Variable
m += 100 * x + 100 * y #Zielfunktion
m += x + 2 * y <= 16 #Obergrenze des Materials A.
m += 3 * x + y <= 18 #Obergrenze des Materials B.
m.solve() #Führen Sie den Solver aus
print(value(x), value(y)) # 4, 6
Das Folgende ist eine kurze Erklärung in der Reihenfolge.
from pulp import *
Bei Minimierungsproblemen: m = LpPrblem () Bei Maximierungsproblemen: m = LpProblem (sense = LpMaximize)
Kontinuierliche Variable: x = LpVariable (Variablenname, lowBound = 0) 0-1 Variable: x = LpVariable (Variablenname, cat = LpBinary) Liste der stetigen Variablen: x = [LpVariable (i-ter Variablenname, lowBound = 0) für i im Bereich (n)] Variablennamen müssen unterschiedlich sein
m + = Ausdruck
m + = Ausdruck == Ausdruck m + = Ausdruck <= Ausdruck m + = Ausdruck> = Ausdruck
2 * x + 3 * y - 5
Summe: lpSum (Liste der Variablen) Inneres Produkt: lpDot (Liste der Koeffizienten, Liste der Variablen)
m.solve()
Wert (Variable), Wert (Ausdruck), Wert (Ziel)
Das Kombinieren von PuLP und Pandas und das Verwalten von Variablen (LpVariable) in einer Pandas-Tabelle (DataFrame) erleichtert das Verständnis der Formulierung.
Nehmen Sie als Beispiel das Problem der Transportoptimierung.
Ich möchte Teile von einer Gruppe von Lagern zu einer Gruppe von Fabriken transportieren. Ich möchte einen Plan finden, der die Transportkosten minimiert.
Transportkosten td> | Montagewerk td> tr> | |||||
F1 td> | F2 td> | F3 td> | F4 td> | Versorgung td> tr> | ||
Lager td> | W1 td> | 10 td> | 10 td> | 11 td> | 17 td> | 35 td> tr> |
W2 | 16 | 19 | 12 | 14 | 41 | |
W3 | 15 | 12 | 14 | 12 | 42 | |
td> | Nachfrage td> | 28 td> | 29 td> | 31 td> | 25 td> tr> |
Stellen Sie die erforderlichen Parameter ein. (Die Zahlen sind die gleichen wie in der vorherigen Tabelle)
python3
import numpy as np, pandas as pd
from itertools import product
from pulp import *
np.random.seed(1)
nw, nf = 3, 4
pr = list(product(range(nw),range(nf)))
Liefern= np.random.randint(30, 50, nw)
Nachfrage= np.random.randint(20, 40, nf)
Versandkosten= np.random.randint(10, 20, (nw,nf))
Auf Variablen wird über Indizes zugegriffen.
python3
m1 = LpProblem()
v1 = {(i,j):LpVariable('v%d_%d'%(i,j), lowBound=0) for i,j in pr}
m1 += lpSum(Versandkosten[i][j] * v1[i,j] for i,j in pr)
for i in range(nw):
m1 += lpSum(v1[i,j] for j in range(nf)) <=Liefern[i]
for j in range(nf):
m1 += lpSum(v1[i,j] for i in range(nw)) >=Nachfrage[j]
m1.solve()
{k:value(x) for k,x in v1.items() if value(x) > 0}
>>>
{(0, 0): 28.0,
(0, 1): 7.0,
(1, 2): 31.0,
(1, 3): 5.0,
(2, 1): 22.0,
(2, 3): 20.0}
Auf Variablen kann über Tabellenattribute zugegriffen werden. Zuerst erstellen wir eine Tabelle.
python3
a = pd.DataFrame([(i,j) for i, j in pr], columns=['Warenhaus', 'Fabrik'])
a['Versandkosten'] = Versandkosten.flatten()
a[:3]
th> | Lager th> | Fabrik th> | Transportkosten th> tr> |
---|---|---|---|
0 | 0 | 0 | 10 |
1 | 0 | 1 | 10 |
2 | 0 | 2 | 11 |
Lassen Sie uns auf die gleiche Weise ein mathematisches Modell erstellen.
python3
m2 = LpProblem()
a['Var'] = [LpVariable('v%d'%i, lowBound=0) for i in a.index]
m2 += lpDot(a.Versandkosten, a.Var)
for k, v in a.groupby('Warenhaus'):
m2 += lpSum(v.Var) <=Liefern[k]
for k, v in a.groupby('Fabrik'):
m2 += lpSum(v.Var) >=Nachfrage[k]
m2.solve()
a['Val'] = a.Var.apply(value)
a[a.Val > 0]
Lager th> | Fabrik th> | Transportkosten th> | Var | Val | |
---|---|---|---|---|---|
0 | 0 | 0 | 10 | v0 | 28.0 |
1 | 0 | 1 | 10 | v1 | 7.0 |
6 | 1 | 2 | 12 | v6 | 31.0 |
7 | 1 | 3 | 14 | v7 | 5.0 |
9 | 2 | 1 | 12 | v9 | 22.0 |
11 | 2 | 3 | 12 | v11 | 20.0 |
Ausdrücke mit Indizes mussten sich daran erinnern, was die Indizes bedeuteten. Die Kombination von PuLP und Pandas erleichtert jedoch das Verständnis des mathematischen Modells, wie unten gezeigt.
das ist alles
Recommended Posts