Binäre Variable in Python mit Pulp

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Allstar1000
User
Beiträge: 4
Registriert: Donnerstag 2. Oktober 2014, 07:57

Hallo Zusammen,

ich bin relativ neu was Phyton angeht und habe ein Frage zu einem linearen Optimierungsproblem, ich benutze dazu SolverStudio ein Excel Addin bei dem man mit Phyton/Pulp linear optimieren kann.

Das Problem selbst sieht folgendermaßen aus:
Es geht darum einen bestimmten Lastgang in einem imaginären Fernwärmenetz von verschiedenen Erzeugungsanlagen die unterschiedlich teuer sind zu bedienen. Der Solver soll die Anlagenzusammensetzung mit dem niedrigsten Gesamtpreis finden.

Das hab ich grundsätzlich auch schon so umgesetzt ich hab nur ein Problem es gibt auch eine Anlage (Kessel1) welche wenn man sie betreiben will mindestens 5 MW Wärme liefern muss
Das habe ich so in die Variablendefinition geschrieben:
var_Kessel1_th = LpVariable.dicts ("thermische Leistung des Kessel1",Zeit,5,90,LpContinuous)

Es soll aber auch möglich sein diesen Kessel1 über eine binäre Variable komplett abzuschalten
Dazu habe ich noch diese binäre Variable definiert:
var_Kessel1_anaus = LpVariable.dicts ("Kessel1 an /aus",Zeit,0,1,LpBinary)

Leider ist mir nicht klar wie ich diese Variable so in meinen Code einbinde das der Kessel1 auch komplett abgeschaltet werden kann.

Hier mein bisheriger Code:

Code: Alles auswählen

from pulp import *

prob = LpProblem ("Fernwärmekosten",LpMinimize)

var_Kessel2_th = LpVariable.dicts ("thermische Leistung des Kessel2",Zeit,0,32,LpContinuous)
var_Kessel1_th = LpVariable.dicts ("thermische Leistung des Kessel1",Zeit,5,90,LpContinuous)
var_Kessel1_anaus = LpVariable.dicts ("Kessel1 an /aus",Zeit,0,1,LpBinary)

prob += lpSum( [var_Kessel2_th[i]*Kosten_Kessel2 +  var_Kessel1_th[i]*Kosten_Kessel1  for i in Zeit]),"Komplette Kosten FW Versorgung"
      
for i in Zeit:
    prob += var_Kessel2_th[i]+var_HWD_th[i] == Last_FW[i]

prob.writeLP("Fernwaermekosten.lp")

prob.solve()
Die Erstellung und Definition der Konstanten und vorgegebenen Listen bzw. Dicts. habe ich der Übersichtlichkeit wegen weggelassen.

Ich hoffe jemand hat eine Idee für mich. Danke im Voraus für eure Mühe

Sollte ich das Thema im falschen Bereich erstellt haben darf es gerne verschoben werden.
Zuletzt geändert von Anonymous am Montag 13. Oktober 2014, 09:19, insgesamt 2-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@Allstar1000: Könnte man nicht die Kosten/Gewinne die der Kessel verursacht mit dieser ”Schalter”-Variable multiplizieren? Wenn die mit 0 belegt ist, dann kostet und bringt der Kessel nichts, wenn sie mit 1 belegt ist werden Kosten/Gewinne mit 1 multipliziert, gehen also unverändert in die Rechnung ein.

Die Programmiersprache heisst übrigens Python und nicht Phython. ;-)
Allstar1000
User
Beiträge: 4
Registriert: Donnerstag 2. Oktober 2014, 07:57

Das ist theoretisch möglich leider wird dann die Randbedingung unwirksam das die Last der Analgen zusammen nie größer als die Last im Fernwärmenetz sein darf

Code: Alles auswählen

for i in Zeit:
    prob += var_Kessel1_th[i]+var_Kessel2_th[i] == Last_FW[i]

Die Programmiersprache heisst übrigens Python und nicht Phython. ;-)
Danke da waren die Finger wohl schneller als der Kopf ;)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du müsstest natürlich auch die Randbedingungen entsprechend anpassen und mit dem Wert des Triggers multiplizieren. Das ganze ist, schon ohne die Änderung der Constraints, dann aber schon kein lineares Problem mehr. Auf die schnelle habe ich auch keine Idee, wie (und ob) das Problem als LP darstellbar ist. Wenn du es einfach nur lösen willst, dann würde ich zwei Probleme draus machen.

Woher kommt denn das Problem/die Aufgabe?
Das Leben ist wie ein Tennisball.
Allstar1000
User
Beiträge: 4
Registriert: Donnerstag 2. Oktober 2014, 07:57

Ich habe diese Art der Optimierung bereits mit einem anderen Excel AddIn (OpenSolver) gemacht, allerdings dauert das übersetzen zwischen Excel und OpenSolver sehr lange diese Rechenzeit wollte ich mir sparen in dem ich das Problem gleich in Pulp schreibe.

Beim OpenSolver kann man eine binäre Variable mit einer normalen Variablen multiplizieren und das Problem bleibt immer noch linear da es dann nach dem Branch-and-Bound Verfahren gelöst wird. Ich dachte eigentlich das mit SolverStudio ein ähnliches Vorgehen möglich ist.

Ich hoffe jemand hat noch eine Idee.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wie ich schon schrieb:
EyDu hat geschrieben:Du müsstest natürlich auch die Randbedingungen entsprechend anpassen und mit dem Wert des Triggers multiplizieren.
Du kommst um das Umschreiben der Constraints nicht herum. In diesem Fall sollte das aber wirklich kein Hexenwerk sein.
Das Leben ist wie ein Tennisball.
Allstar1000
User
Beiträge: 4
Registriert: Donnerstag 2. Oktober 2014, 07:57

Danke hatte vergessen das ich bei der Definition der Variable als Grenze None eintragen muss, wenn ich die Grenzen über die Constraints setze.

Code: Alles auswählen

var_Kessel1_th = LpVariable.dicts ("thermische Leistung des Kessel1",Zeit,None,None,LpContinuous)

Code: Alles auswählen

 prob += var_HWD_th[i] >= 5*var_HWD_anaus[i] 
 prob += var_HWD_th[i] <= 90*var_HWD_anaus[i]
Das funktioniert einwandfrei.

Vielen Dank für den Tipp
Antworten