简体   繁体   中英

Pulp Optimization with Pandas and NumPy (CLSP - Lot Sizing)

For my master thesis I will be implementing a heuristic for the lot sizing problem (CLSP). As a start (and a benchmark for the heuristic) I wanted to implement the optimal solution for a small example, in order to get to know Python and its functionalities.

Doing so, I found several optimisation problems, but must of them were way more basic than the CLSP. I feel like I mostly struggle with the multiple indices of variables and the combination of Pandas and PuLP.

Btw.: Please don't mind the #german comments. They are just for my documentation.

This is what I have so far:

import pandas as pd
import numpy as np
import pulp

# Liste für Perioden erstellen
PERIODS = list(range(1,7))

# Liste für Produkte erstellen
PRODUCTS = [1, 2]

# Liste für Ressourcen erstellen
RESSOURCES = [1]

# Minimierungsproblem definieren
clsp = pulp.LpProblem("Capacitated Lot-Sizing Problem", pulp.LpMinimize)

# Variablen deklarieren
# Nichtnegativitätsbedingungen werden durch LB=0 sichergestellt.
q       = pulp.LpVariable.dicts("Losgroesse fuer Produkt j in Periode t",
            ((k,t)  for k in PRODUCTS
                    for t in PERIODS),
                    0, None, 'Continuous')
y       = pulp.LpVariable.dicts("Lagerbestand für Produkt j am Ende der Periode t",
            ((k,t)  for k in PRODUCTS
                    for t in PERIODS),
                    0, None, 'Continuous')
gamma   = pulp.LpVariable.dicts("binaere Ruestvariable für Produkt j in Periode t",
            ((k,t)  for k in PRODUCTS
                    for t in PERIODS),
                    0, 1, 'Binary')

#Daten festlegen (Sollte in Zukunft in extra csv-Datei gespeichert werden)

#Rüstkostensatz pro Produkt
s = {1: 100,
     2: 50}

#Lagerhaltungskostensatz pro Produkt
h = {1: 4,
     2: 1}

#Produktionskosten pro Produkt & Periode
p = pd.DataFrame (np.array([(2, 2, 2, 2, 2, 2), (3, 3, 3, 3, 3, 3)]), index=PRODUCTS ,columns=PERIODS)
'''1  2  3  4  5  6
1  2  2  2  2  2  2
2  3  3  3  3  3  3'''

#Bedarfsmengen pro Produkt & Periode
d = pd.DataFrame (np.array([(110, 49, 0, 82, 40, 65), (48, 75, 15, 10, 15, 70)]), index=PRODUCTS ,columns=PERIODS)
'''  1   2   3   4   5   6
1  110  49   0  82  40  65
2   48  75  15  10  15  70'''

#Big-M für binäre Rüstvariable
M = 1000

#Stückbearbeitungszeit für Produkt k an Ressource j
tb = pd.DataFrame (np.ones((1,2), dtype=np.int16), index=RESSOURCES ,columns=PRODUCTS)

#Rüstzeit für Produkt k auf Resource j
tr = pd.DataFrame (np.ones((1,2), dtype=np.int16), index=RESSOURCES ,columns=PRODUCTS)

#Kapazität der Ressource j in Periode t
b = pd.DataFrame (np.array([(160, 160, 160, 160, 120, 120)]), index=RESSOURCES ,columns=PERIODS)

# Zielfunktion aufstellen - Summe der Ruest-, Lager- & Produktionskosten:
clsp += pulp.lpSum([s[k]  * gamma[k][t] + h[k] * y[k][t] + p.loc[k][t] * q[k][t] for k in PRODUCTS for t in PERIODS]), "Total Costs"

# Restriktionen
for k in PRODUCTS:
    for t in PERIODS:
        clsp += y[k][t-1]  + q[k][t] - y[k][t]  == d.loc[k][t]  , "Lagerbilanzgleichung"
        clsp += q[k][t] - M * gamma[k][t] <= 0                  , "Big-M für Ruestvariable"
        clsp += pulp.lpSum([tb.loc[j][k] * q[k][t] + tr.loc[j][k] * gamma[k][t] <= b.loc[j][t], "Kapazitaetstrestriktion"] for j in RESSOURCES)

# Lineares Programm (LP) in Textdatei schreiben
clsp.writeLP("CLSP.lp")

# LP lösen
clsp.solve()

# Status der Loesung ausgeben: “Not Solved”, “Infeasible”, “Unbounded”, “Undefined” or “Optimal”
print("Status:", pulp.LpStatus[clsp.status])

# Ergebnisse für einzelne Variablen ausgeben
for v in clsp.variables():
    print(v.name, "=", v.varValue, "%")

# Optimale Loesung der Zielfunktion ausgeben
print("Total Costs = ", value(clsp.objective))

I feel like this can't be too wrong.. Nevertheless, I am unsure about the following section. I am not sure, if I can put the indices (for k in PRODUCTS, etc.) before all of the constraints, if they have to be put behind each one respectively. At least this way I am not getting an error here...

for k in PRODUCTS:
    for t in PERIODS:
        clsp += y[k][t-1]  + q[k][t] - y[k][t]  == d.loc[k][t]  , "Lagerbilanzgleichung"
        clsp += q[k][t] - M * gamma[k][t] <= 0                  , "Big-M für Ruestvariable"
        clsp += pulp.lpSum([tb.loc[j][k] * q[k][t] + tr.loc[j][k] * gamma[k][t] <= b.loc[j][t], "Kapazitaetstrestriktion"] for j in RESSOURCES)

Further, when running that code, it gives me the following error:

Traceback (most recent call last):
  File "/Users/frederic/Dropbox/2_Universita\u0308t Duisburg-Essen/0_Master Thesis/Implementierung/CLSP/clsp_v2.py", line 69, in <module>
    clsp += pulp.lpSum([s[k]  * gamma[k][t] + h[k] * y[k][t] + p.loc[k][t] * q[k][t] for k in PRODUCTS for t in PERIODS]), "Total Costs"
  File "/Users/frederic/Dropbox/2_Universita\u0308t Duisburg-Essen/0_Master Thesis/Implementierung/CLSP/clsp_v2.py", line 69, in <listcomp>
    clsp += pulp.lpSum([s[k]  * gamma[k][t] + h[k] * y[k][t] + p.loc[k][t] * q[k][t] for k in PRODUCTS for t in PERIODS]), "Total Costs"
KeyError: 1

With being line 69 my objective function:

clsp += pulp.lpSum([s[k]  * gamma[k][t] + h[k] * y[k][t] + p.loc[k][t] * q[k][t] for k in PRODUCTS for t in PERIODS]), "Total Costs"

I studied all online documentations and have been googling for hours, but yet, I haven't found a feasible solution, so any tips would be helpful!

I am fairly new to Python, so I appreciate you bearing with me here.

Cheers, Frederic

Thanks for providing the code and good explanation. The issue is that the dictionaries q , y , and gamma that you are using to store your LpVariables are indexed on the (k, t) tuple, so you need to refer to them as gamma[(k, t)] instead of gamma[k][t] .

You'll have another issue when you get to this constraint

clsp += y[(k, t-1)]  + q[(k, t)] - y[(k, t)]  == d.loc[k][t]  , "Lagerbilanzgleichung"

because t-1 won't be in y when t equals 1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM