2017-08-05 32 views
0

對於我的碩士論文,我將實施批量問題(CLSP)的啓發式方法。作爲一個開始(也是啓發式的基準),我希望爲一個小例子實現最佳解決方案,以便了解Python及其功能。Pandas和NumPy紙漿優化(CLSP - 批量調整)

這樣做,我發現了幾個優化問題,但它們必須比CLSP更基礎。我覺得我主要是與多個變量指標以及熊貓和PuLP的組合鬥爭。

Btw .:請不要介意#german的評論。他們只是爲了我的文檔。

這是我到目前爲止有:

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)) 

我喜歡這種感覺不能太錯了..不過,我不確定下面的部分。我不確定,如果我可以在所有限制之前放置指數(對於產品中的k等),如果它們必須分別放在每個限制之後。至少這樣,我沒有得到這裏的錯誤...

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) 

此外,運行的代碼時,它給了我下面的錯誤:

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 

與正在線69我的目標函數:

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" 

我研究了所有的在線文檔和已經google搜索了幾個小時,不過不失,我還沒有找到一個可行的解決方案,所以任何提示將是有益的!

我對Python很新,所以我很感謝你在這裏和我在一起。

乾杯, 弗雷德裏克

回答

1

謝謝你提供的代碼,並很好的解釋。問題是您用來存儲Lp變量的字典q,ygamma(k, t)元組上索引,因此您需要將它們稱爲gamma[(k, t)]而不是gamma[k][t]

你有另外一個問題,當你到這個限制

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

因爲t-1不會在yt等於1

+0

謝謝@thomaskeefe!目標函數似乎現在起作用。你對另一個問題是正確的。我想我需要添加一個虛擬期間0。儘管如此,所有的約束(基本上都是目標函數之後的所有命令)似乎會導致各種錯誤。例如,即使我把'y [(k,t)]'而不是'y [(k,t-1)]'也會返回一個錯誤。 – Frederic

+0

您的約束還會遇到另一個問題:您正在for循環中創建約束,但for循環的每次迭代都嘗試使用重複名稱進行約束。 PuLP不允許這樣做,所以你要麼不必包含約束名稱,要麼確保約束名稱對於循環的每次迭代都是不同的。 – thomaskeefe

+0

有沒有for循環的另一種方法?然後,我會輕鬆地刪除約束名稱。這並不重要。感謝提示。 – Frederic