Vorlesung 10: Mehrfache Zielsetzung

Grundlagen Operations Research

Mehrfache Zielsetzung

Zwei Ziele, ein Plan

Erinnerung: das LKW-Beispiel

Auftrag Stückerlös Paletten Tonnen
1 20 1 1
2 30 1 3
Kapazität 5 9

Für das Be- und Entladen fallen 5 EUR pro Tonne an.

Ziel 1: Umsatz

maxF=20X1+30X2X1+X25,X1+3X29,X1,X20 \begin{aligned} \max \; & F = 20 X_1 + 30 X_2 \\ & X_1 + X_2 \le 5, \quad X_1 + 3 X_2 \le 9, \quad X_1, X_2 \ge 0 \end{aligned}

X1*=3,X2*=2,F*=120 X_1^* = 3, \quad X_2^* = 2, \quad F^* = 120

Deckungsbeiträge

Zieht man die 5 EUR/Tonne ab, ergibt sich je Palette:

DB1=2015=15,DB2=3035=15 \text{DB}_1 = 20 - 1 \cdot 5 = 15, \qquad \text{DB}_2 = 30 - 3 \cdot 5 = 15

Das Controlling empfiehlt, nach Deckungsbeitrag statt Umsatz zu planen.

Ziel 2: Deckungsbeitrag

maxF=15X1+15X2X1+X25,X1+3X29,X1,X20 \begin{aligned} \max \; & F = 15 X_1 + 15 X_2 \\ & X_1 + X_2 \le 5, \quad X_1 + 3 X_2 \le 9, \quad X_1, X_2 \ge 0 \end{aligned}

X1*=5,X2*=0,F*=75 X_1^* = 5, \quad X_2^* = 0, \quad F^* = 75

Die Umsatzerlöse sinken dabei auf 520=1005 \cdot 20 = 100 EUR und die ungenutzte Ladekapazität steigt auf 4 Tonnen: ein Zielkonflikt.

Der Zielkonflikt

  • Umsatz-Optimum: (3,2)(3, 2) (rot).
  • Deckungsbeitrag-Optimum: (5,0)(5, 0) (gelb).

Die gelbe Kante ist komplett DB-optimal: mehrdeutig (V05!).

Frage: Wie lösen wir den Konflikt auf?

Arten von Zielkonflikten

  • Konkurrierende (konträre) Ziele: sie behindern sich.
  • Komplementäre Ziele: sie unterstützen sich.
  • Neutrale (orthogonale) Ziele: sie beeinflussen sich nicht.

Vier Ansätze zur Auflösung: lexikographische Ordnung, Haupt-/Nebenziele, Zielgewichtung, Goal Programming. Maßstab: der Zielerreichungsgrad.

Lexikographische Ordnung

Ziele nach Wichtigkeit

Eine strikte Rangfolge der Ziele ABCA \succ B \succ C \succ \dots

  1. Optimiere nur Ziel AA \Rightarrow Lösungsmenge XAX_A.
  2. Optimiere Ziel BB nur auf XAX_A XBXA\Rightarrow X_B \subseteq X_A.
  3. Optimiere Ziel CC nur auf XBX_B, und so weiter.

Anwendung auf das Beispiel

Ziel AA (Deckungsbeitrag): FA=75F_A = 75. Optimal ist die ganze Kante von (5,0)(5, 0) bis (3,2)(3, 2), also gibt es noch Spielraum.

Ziel BB (Umsatz), aber Deckungsbeitrag beibehalten:

maxFB=20X1+30X215X1+15X275(DB-Niveau halten)X1+X25,X1+3X29 \begin{aligned} \max \; & F_B = 20 X_1 + 30 X_2 \\ & 15 X_1 + 15 X_2 \ge 75 \quad (\text{DB-Niveau halten}) \\ & X_1 + X_2 \le 5, \quad X_1 + 3 X_2 \le 9 \end{aligned}

X1*=3,X2*=2,FB*=120\Rightarrow X_1^* = 3, X_2^* = 2, F_B^* = 120: beide Ziele erfüllt.

Haupt- und Nebenziele

Hauptziel plus Nebenziel

Ein Ziel wird optimiert, die übrigen als Mindestanforderung (satisfizierend) formuliert.

maxF=15X1+15X2(Hauptziel: DB)20X1+30X2110(Nebenziel: Umsatz)X1+X25,X1+3X29 \begin{aligned} \max \; & F = 15 X_1 + 15 X_2 && (\text{Hauptziel: DB}) \\ & 20 X_1 + 30 X_2 \ge 110 && (\text{Nebenziel: Umsatz}) \\ & X_1 + X_2 \le 5, \quad X_1 + 3 X_2 \le 9 \end{aligned}

X1*=3,X2*=2,F*=75 X_1^* = 3, \quad X_2^* = 2, \quad F^* = 75

Zielgewichtung

Gewichtete Summe

Alle Ziele gleichrichten (Minimierung ×(1)\times (-1)) und mit Gewichten 0λi10 \le \lambda_i \le 1 zusammenfassen:

Maximiere Z=i=1tλiFi \text{Maximiere } Z = \sum_{i=1}^{t} \lambda_i\, F_i

Die Gewichte drücken die relative Bedeutung der Ziele aus.

Beispiel

Umsatz und Deckungsbeitrag gleich gewichtet, λ1=λ2=0,5\lambda_1 = \lambda_2 = 0{,}5:

Z=0,5(20X1+30X2)+0,5(15X1+15X2)=17,5X1+22,5X2 Z = 0{,}5\,(20 X_1 + 30 X_2) + 0{,}5\,(15 X_1 + 15 X_2) = 17{,}5 X_1 + 22{,}5 X_2

X1*=3,X2*=2,Z*=97,5 X_1^* = 3, \quad X_2^* = 2, \quad Z^* = 97{,}5

Goal Programming

Abstand zum Ideal

Erweiterung der Zielgewichtung: Minimiere den Abstand zwischen dem Ideal Fi*F_i^* und dem erreichten Wert FiF_i.

  • Summe der gewichteten Abstände: Z1=iλi|Fi*Fi|Z_1 = \sum_i \lambda_i\,|F_i^* - F_i|.
  • Maximaler gewichteter Abstand: Z2=maxiλi|Fi*Fi|Z_2 = \max_i \lambda_i\,|F_i^* - F_i|.
  • Summe der quadrierten Abstände: Z3=iλi(Fi*Fi)2Z_3 = \sum_i \lambda_i (F_i^* - F_i)^2.

Ohne Betragsstriche

Frage: Warum dürfen die Beträge einfach wegfallen?

Im zulässigen Bereich gilt für Maximierungsziele stets FiFi*F_i \le F_i^*: der Abstand Fi*FiF_i^* - F_i ist nie negativ.

Für Z1Z_1 (mit λi=1\lambda_i = 1) heißt das konkret:

Z1=(7515X115X2)+(12020X130X2)min Z_1 = (75 - 15X_1 - 15X_2) + (120 - 20X_1 - 30X_2) \to \min

max35X1+45X2 \Longleftrightarrow \quad \max \; 35 X_1 + 45 X_2

Wieder ein gewöhnliches LP: Optimum (3,2)(3, 2) mit Z1=0Z_1 = 0.

Der Min-Max-Ansatz

Je Ziel eine Restriktion, λ1=λ2=1\lambda_1 = \lambda_2 = 1:

minZZ+20X1+30X2120(Abstand zum Umsatzmaximum)Z+15X1+15X275(Abstand zum DB-Maximum)X1+X25,X1+3X29 \begin{aligned} \min \; & Z \\ & Z + 20 X_1 + 30 X_2 \ge 120 && (\text{Abstand zum Umsatzmaximum}) \\ & Z + 15 X_1 + 15 X_2 \ge 75 && (\text{Abstand zum DB-Maximum}) \\ & X_1 + X_2 \le 5, \quad X_1 + 3 X_2 \le 9 \end{aligned}

X1*=3,X2*=2,Z*=0 X_1^* = 3, \quad X_2^* = 2, \quad Z^* = 0

WichtigEin robuster Kompromiss

Alle Ansätze empfehlen hier (3,2)(3, 2): ein stabiler Ausgleich beider Ziele.

Kontrolle mit Julia

Goal Programming mit JuMP

Zuerst die beiden Einzeloptima F1*,F2*F_1^*, F_2^*, dann der Ausgleich:

using JuMP, HiGHS

# Einzeloptima bestimmen
ideal(c1, c2) = begin
    modell = Model(HiGHS.Optimizer); set_silent(modell)
    @variable(modell, X[1:2] >= 0)
    @objective(modell, Max, c1*X[1] + c2*X[2])
    @constraint(modell, X[1] + X[2] <= 5); @constraint(modell, X[1] + 3X[2] <= 9)
    optimize!(modell); objective_value(modell)
end
F1, F2 = ideal(20, 30), ideal(15, 15)     # Umsatz-, DB-Maximum

modell = Model(HiGHS.Optimizer); set_silent(modell)  # minimiere max. Abweichung
@variable(modell, X[1:2] >= 0); @variable(modell, Z >= 0)
@constraint(modell, Z + 20X[1] + 30X[2] >= F1)
@constraint(modell, Z + 15X[1] + 15X[2] >= F2)
@constraint(modell, X[1] + X[2] <= 5); @constraint(modell, X[1] + 3X[2] <= 9)
@objective(modell, Min, Z)
optimize!(modell)
println("X = ", value.(X), ", Z* = ", objective_value(modell))
X = [2.999999999999999, 2.000000000000001], Z* = 0.0

Anwendung: Standortplanung

Ein Gebietsplanungsproblem

16 Gebiete (4×4-Raster) mit Umsatzpotenzialen; 4 mögliche Standorte (Gebiete 2, 8, 9, 15, mit ° markiert). Wähle genau zwei und ordne jedes Gebiet einem Standort zu.

68 96° 101 114
42 73 78 34°
68° 51 73 52
51 105 123° 77

Variablen und Restriktionen

Frage: Welche Variablen und Restriktionen brauchen wir?

  • Yj{0,1}Y_j \in \{0,1\}: Standort jj errichten; Xij{0,1}X_{ij} \in \{0,1\}: Gebiet ii \to Standort jj.
  • Genau zwei Standorte: jYj=2\sum_j Y_j = 2.
  • Zuordnung nur zu errichteten: XijYjX_{ij} \le Y_j; ein Standort versorgt sein eigenes Gebiet: Xjj=YjX_{jj} = Y_j.
  • Jedes Gebiet genau einmal: jXij=1\sum_j X_{ij} = 1.

Im Original zusätzlich: Gebiete müssen zusammenhängend sein. Das lassen wir hier weg.

Zwei konkurrierende Ziele

HinweisFairness gegen Kosten
  • F1F_1 = kleinstes zugeordnetes Umsatzpotenzial \to maximieren (ausgewogene Gebiete).
  • F2F_2 = gesamte Reisekosten ijdijXij\sum_{ij} d_{ij} X_{ij} \to minimieren.

Ein Zielkonflikt, aufzulösen mit Goal Programming (gleichgewichtete relative Abweichungen).

Die Einzeloptima

Erst die beiden Ideale, jeweils mit demselben Grundmodell:

using JuMP, HiGHS
u = [68,96,101,114, 42,73,78,34, 68,51,73,52, 51,105,123,77]
J = [2,8,9,15]; I = 1:16
pos(i) = (cld(i,4), mod1(i,4))                      # Zeile, Spalte
d(i,j) = abs(pos(i)[1]-pos(j)[1]) + abs(pos(i)[2]-pos(j)[2])

function standortmodell()
    modell = Model(HiGHS.Optimizer); set_silent(modell)
    @variable(modell, Y[J], Bin); @variable(modell, X[I,J], Bin)
    @variable(modell, F1 >= 0)
    @constraint(modell, sum(Y[j] for j in J) == 2)
    @constraint(modell, [i in I, j in J], X[i,j] <= Y[j])
    @constraint(modell, [j in J], X[j,j] == Y[j])
    @constraint(modell, [i in I], sum(X[i,j] for j in J) == 1)
    @constraint(modell, [j in J],
        F1 <= sum(u[i]*X[i,j] for i in I) + sum(u)*(1 - Y[j]))
    modell, X, Y, F1, sum(d(i,j)*X[i,j] for i in I, j in J)
end

m1, _, _, F1v, _ = standortmodell()
@objective(m1, Max, F1v); optimize!(m1); F1stern = objective_value(m1)
m2, _, _, _, F2v = standortmodell()
@objective(m2, Min, F2v); optimize!(m2); F2stern = objective_value(m2)
println("F1* = ", round(Int, F1stern), ", F2* = ", round(Int, F2stern))
F1* = 603, F2* = 24

Der Ausgleich

Jetzt das angekündigte Goal Programming, minimiere die Summe der relativen Abweichungen von beiden Idealen:

modell, X, Y, F1v, F2v = standortmodell()
@objective(modell, Min,
    (F1stern - F1v)/F1stern + (F2v - F2stern)/F2stern)
optimize!(modell)

println("Standorte: ", [j for j in J if value(Y[j]) > 0.5])
println("F1 = ", round(Int, value(F1v)), " (Ideal ", round(Int, F1stern),
        "), F2 = ", round(Int, value(F2v)), " (Ideal ", round(Int, F2stern), ")")
Standorte: [8, 9]
F1 = 602 (Ideal 603), F2 = 24 (Ideal 24)

Beide Ziele bleiben nahe an ihrem Ideal. Der Preis des Kompromisses ist direkt ablesbar.

Zusammenfassung

Das Wichtigste auf einen Blick

  • Mehrere Ziele erzeugen oft Zielkonflikte.
  • Lexikographische Ordnung: Ziele strikt nacheinander optimieren.
  • Haupt-/Nebenziele: eines optimieren, andere als Mindestanforderung.
  • Zielgewichtung und Goal Programming fassen die Ziele über Gewichte bzw. Abstände zusammen.
  • Anwendung: Standortplanung wägt faire Umsätze gegen Reisekosten ab.

Literatur

Literaturverzeichnis

Domschke, Wolfgang, Andreas Drexl, Robert Klein, und Armin Scholl. 2015. Einführung in Operations Research. 9. Aufl. Springer Gabler. https://doi.org/10.1007/978-3-662-48216-2.