using JuMP, HiGHS
modell = Model(HiGHS.Optimizer)
set_silent(modell) # Solver-Ausgabe abschalten
# ... Variablen, Zielfunktion, Nebenbedingungen ...
optimize!(modell) # lösenCheatsheet JuMP
Grundlagen Operations Research
Kompakte Referenz aller JuMP-Bausteine, die in diesem Kurs vorkommen. Schritt-für-Schritt-Einführung: Pakete & JuMP.
Grundgerüst
Variablen
Deklaration
@variable(modell, X) # frei (unbeschränkt)
@variable(modell, X >= 0) # nichtnegativ
@variable(modell, 0 <= X <= 10) # mit beiden Schranken
@variable(modell, X >= 0, Int) # ganzzahlig
@variable(modell, X, Bin) # binär (0 oder 1)Container
@variable(modell, X[1:5] >= 0) # Vektor von Variablen
@variable(modell, X[1:3, 1:4] >= 0) # Matrix (z. B. Transport)
@variable(modell, X[t in T], Bin) # über Indexmenge T
X[2] # einzelne Variable
X[1, 3] # Element einer Variablenmatrix
modell[:X] # Container über seinen Namen im Modell abrufenZielfunktion
@objective(modell, Max, 20X1 + 30X2) # maximieren
@objective(modell, Min, 4X1 + X2) # minimieren
@objective(modell, Min, sum(c[i] * X[i] for i in 1:5))Nebenbedingungen
# Benannt (empfohlen, der Name erlaubt später shadow_price etc.):
@constraint(modell, Paletten, X1 + X2 <= 5)
@constraint(modell, Bedarf, X1 + 3X2 >= 9)
@constraint(modell, Bilanz, X1 - X2 == 0)
# Eine Bedingung je Index (Container):
@constraint(modell, Kapazitaet[i in 1:3],
sum(X[i, j] for j in 1:4) <= a[i]
)
# Summen mit Bedingung:
@constraint(modell, Fluss,
sum(X[k] for k in 1:9 if von[k] == 1) == 1
)Lösen und Ergebnisse
optimize!(modell)
@show termination_status(modell) # IMMER zuerst prüfen!
@show objective_value(modell) # optimaler Zielfunktionswert F*
@show value(X1) # Wert einer Variablen
@show value.(X) # Werte eines Containers (Punkt!)Statuswerte (vgl. Vorlesung 5)
termination_status(modell) == OPTIMAL # optimale Lösung
termination_status(modell) == INFEASIBLE # unzulässig
termination_status(modell) == DUAL_INFEASIBLE # unbeschränktSensitivität (vgl. Vorlesungen 3 und 4)
shadow_price(Paletten) # Änderung von F* bei Relaxation
# der Nebenbedingung um eine Einheit
reduced_cost(X1) # reduzierte Kosten der Variablen
dual(Paletten) # Dualwert der NebenbedingungVorzeichen-Konvention: shadow_price misst die Änderung von bei Relaxation der Nebenbedingung. Bei Maximierungsmodellen ist das identisch mit dem Simplex-Multiplikator (der Dualvariablen) aus der Vorlesung. Bei Minimierungsmodellen ist das Vorzeichen gegenüber der klassischen Dualvariablen bei ≥-Nebenbedingungen stets und bei Gleichungen teilweise gedreht. Vergleichen Sie dort im Zweifel mit der Handrechnung.
Bei dual hängt das Vorzeichen nur von der Richtung der Nebenbedingung ab, nicht von Max oder Min: Bei ≤-Nebenbedingungen ist der Wert nie positiv, bei ≥-Nebenbedingungen nie negativ. Im Minimierungsmodell mit ≥-Nebenbedingungen aus Vorlesung 4 liefert dual deshalb direkt die Dualvariablen . Im Frachtführer-Problem (Maximierung, ≤-Nebenbedingungen) ist dual(Paletten) dagegen , während shadow_price(Paletten) den Simplex-Multiplikator liefert.
Modell nachträglich ändern
fix(X1, 9; force = true) # Variable auf Wert festsetzen
unfix(X1) # Festsetzung aufheben
set_lower_bound(X1, 2) # untere Schranke setzen/ändern
set_upper_bound(X1, 8) # obere Schranke setzen/ändern
delete_upper_bound(X1) # obere Schranke entfernen
set_integer(X1) # Ganzzahligkeit ergänzen
unset_integer(X1) # ... wieder entfernen
# danach einfach erneut lösen:
optimize!(modell)Modell prüfen
print(modell) # Modell wie auf dem Papier anzeigen
num_variables(modell) # Anzahl Variablen
solution_summary(modell) # Zusammenfassung nach dem LösenWiederkehrende Ausgabezeile des Kurses
println("F* = ", objective_value(modell),
" mit X = ", value.(X))Julia-Grundlagen (Vektoren, Schleifen, Broadcasting) stehen im Cheatsheet Julia.