Phase 6.1: Chance Constraints - die Zusage "mit 95 % Sicherheit"
Neuer Abschnitt im Kapitel Unsicherheit plus Chance_Constraints.py (74. Programm). Das Kapitel hatte Monte-Carlo, Zweistufigkeit und Worst-Case-Robustheit; die Wahrscheinlichkeitszusage war die fehlende vierte Antwort - und die, nach der das Management tatsaechlich fragt. Setzt Paket 4 aus Verbesserungen_02.md um. Beide Wege an DERSELBEN Instanz (Kraftwerkspark, 500 MW gesicherte Zusage): analytisch als Second-Order-Cone-Bedingung (CLARABEL) und szenariobasiert als Big-M-MILP (SciPy/HiGHS) - beides in einem Prozess, ohne ortools- oder highspy-Import. Drei gemessene Befunde: * Der Mittelwertplan haelt 50,08 %. Kein Fehler, sondern die Definition des Erwartungswerts. * Sicherheit ist konvex bepreist: 56.289 EUR je Prozentpunkt auf dem Weg zu 80 %, 253.848 EUR zwischen 95 und 99 % - das 4,5-fache. Das Programm rechnet die Tabelle selbst aus, statt sie zu behaupten. * Die Zusage gilt nur fuer die unterstellte Verteilung: Der 95-%-Plan haelt gemessen 87,44 %, sobald die Testverteilung eine Kaeltewelle mit Dunkelflaute enthaelt, in der alles zugleich einbricht - auch das Gaskraftwerk. In einer reinen Normalwelt liefert derselbe Plan 94,97 %. Zwei eigene Fehlgriffe, beide durch Messen aufgefallen und korrigiert: Die erste Kostentarierung ergab eine entartete Loesung (alles ins Gaskraftwerk), womit die Kovarianzmatrix wirkungslos war - und gerade sie begruendet die Kegelform. Und der erste Kaelteeinbruch traf nur Wind und Sonne; der SOC-Plan hatte die ohnehin herausgehalten und war zufaellig robust, das Argument trug nicht. Ehrlich berichtet statt geglaettet: Die Szenariomethode ueberanpasst. Ueber zwoelf Laeufe (S = 200, 400, 800) lag die tatsaechliche Quote zwischen 93,14 % und 96,71 %, und die Spanne wurde von S = 400 auf 800 wieder breiter. Beide Solver bestaetigen optimal bei identischen Kosten - echte Ueberanpassung, kein Solverartefakt. Steht als Warnkasten im Abschnitt. Die Laufzeitmessung ist aus der Ausgabe entfernt: Eine Wanduhrzeit ist nie byteidentisch reproduzierbar (2,2 s / 2,3 s zwischen zwei Laeufen) und haette Regel 4 dauerhaft gebrochen. Danach drei Laeufe zeichengleich, und die abgedruckte Ausgabe stimmt mit dem Lauf des extrahierten Programms ueberein. Mitgezogen: Kapitelkopf, Lernziele, Uebersichtstabelle (drei -> vier Ansaetze), Selbsttest, Zusammenfassung, Vorwort-Programmverzeichnis, eine neue Uebungsaufgabe und ihre Loesung in Anhang A. pyproject.toml korrigiert: cvxpy lag in [finance], wird aber von 13 Programmen gebraucht, darunter dreien in diesem Kapitel - jetzt in der Grundausstattung. Es zieht kein highspy nach, der Solverkonflikt bleibt auf [large-scale] beschraenkt. Stand: 293 Abschnitte, 712 Querverweise, 327 Indexmarken, 74 Programme (0 Fehler), 33 pytest-Tests, PDF 725 Seiten. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
62952ba066
commit
6c67e126dd
23 changed files with 9089 additions and 6419 deletions
|
|
@ -449,6 +449,7 @@ Pfad E oder um gezielt nach einem Thema zu suchen:
|
|||
| `Monte_Carlo.py` | Monte-Carlo-Bewertung | {ref:kap:unsicherheit} |
|
||||
| `Stochastische_Optimierung.py` | Two-Stage mit Recourse | {ref:kap:unsicherheit} |
|
||||
| `Robuste_Optimierung.py` | Worst-Case-Absicherung | {ref:kap:unsicherheit} |
|
||||
| `Chance_Constraints.py` | Zusage „mit 95 % Sicherheit“, SOC und Big-M | {ref:kap:unsicherheit} |
|
||||
| `Bellman_Minimalbeispiel.py` | Rückwärtsinduktion | {ref:kap:dynamische-programmierung} |
|
||||
| `Mehrziel_Pareto.py` | Pareto-Front, ε-Constraint, Gewichtslücke | {ref:kap:mehrziel} |
|
||||
| `Predict_then_Optimize.py` | MSE gegen Entscheidungskosten | {ref:kap:prognose} |
|
||||
|
|
|
|||
|
|
@ -3,22 +3,25 @@
|
|||
> **📌 Kapitel auf einen Blick**
|
||||
>
|
||||
> **Worum geht es?** Bisher waren alle Parameter bekannt. In der Realität sind Nachfrage,
|
||||
> Rendite und Fahrzeit **Zufallsgrößen**. Dieses Kapitel zeigt drei Wege, damit umzugehen —
|
||||
> Rendite und Fahrzeit **Zufallsgrößen**. Dieses Kapitel zeigt vier Wege, damit umzugehen —
|
||||
> und warum „einfach den Mittelwert einsetzen“ der schlechteste davon ist.
|
||||
>
|
||||
> **Voraussetzungen:** {ref:kap:lp}, {ref:kap:qp-nlp}. Grundbegriffe der Statistik (Erwartungswert, Quantil).
|
||||
>
|
||||
> **Danach können Sie:** Ein zweistufiges stochastisches Modell aufstellen, Monte-Carlo zur
|
||||
> Risikomessung einsetzen, ein robustes Modell für den Worst Case formulieren — und
|
||||
> erkennen, wann Rechnen mit Mittelwerten zulässig ist und wann es systematisch danebengeht.
|
||||
> Risikomessung einsetzen, ein robustes Modell für den Worst Case formulieren, eine
|
||||
> Wahrscheinlichkeitszusage („mit 95 % Sicherheit“) als lösbare Nebenbedingung schreiben —
|
||||
> und erkennen, wann Rechnen mit Mittelwerten zulässig ist und wann es systematisch
|
||||
> danebengeht.
|
||||
>
|
||||
> **Zeitbedarf:** ca. 5,5 Stunden.
|
||||
> **Zeitbedarf:** ca. 6,5 Stunden.
|
||||
>
|
||||
> **Programme:**\
|
||||
> `Fluch_des_Durchschnitts.py`\
|
||||
> `Monte_Carlo.py`\
|
||||
> `Stochastische_Optimierung.py`\
|
||||
> `Robuste_Optimierung.py`
|
||||
> `Robuste_Optimierung.py`\
|
||||
> `Chance_Constraints.py`
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -112,10 +115,13 @@ Nach diesem Kapitel können Sie …
|
|||
2. … ein **zweistufiges stochastisches Programm** mit Recourse formulieren.
|
||||
3. … Monte-Carlo einsetzen, um Verteilungen statt Punktschätzungen zu bewerten.
|
||||
4. … ein **robustes** Modell mit Unsicherheitsmenge aufstellen und seinen Preis beziffern.
|
||||
5. … begründen, welcher der drei Ansätze für ein gegebenes Problem passt.
|
||||
6. … das **kritische Verhältnis** eines Newsvendor-Problems aufstellen und daraus die
|
||||
5. … eine **Wahrscheinlichkeitszusage** („mit 95 % Sicherheit“) als Chance Constraint
|
||||
schreiben — analytisch als Kegelbedingung oder szenariobasiert mit Big-M — und den Preis
|
||||
eines Prozentpunkts Sicherheit beziffern.
|
||||
6. … begründen, welcher der vier Ansätze für ein gegebenes Problem passt.
|
||||
7. … das **kritische Verhältnis** eines Newsvendor-Problems aufstellen und daraus die
|
||||
optimale Bestellmenge als Quantil ablesen.
|
||||
7. … eine Terminzusage als Quantil formulieren statt als Mittelwert.
|
||||
8. … eine Terminzusage als Quantil formulieren statt als Mittelwert.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -256,18 +262,23 @@ Erwartungswert der Kosten ist größer als die Kosten des Erwartungswerts.
|
|||
> Der Durchschnittskunde kauft nie. Das Durchschnittsszenario tritt nie ein. Wer mit
|
||||
> Mittelwerten plant, optimiert eine Welt, die es nicht gibt.
|
||||
|
||||
### Die drei Ansätze im Überblick
|
||||
### Die vier Ansätze im Überblick
|
||||
|
||||

|
||||
|
||||
| | **Monte-Carlo** | **Stochastische Programmierung** | **Robuste Optimierung** |
|
||||
| --- | --- | --- | --- |
|
||||
| Braucht | Verteilung | Szenarien **mit Wahrscheinlichkeiten** | nur eine **Menge** möglicher Werte |
|
||||
| Optimiert | nichts (bewertet nur) | **Erwartungswert** über Szenarien | **Worst Case** in der Menge |
|
||||
| Typische Frage | „Wie riskant ist dieser Plan?“ | „Was ist im Mittel am besten?“ | „Was hält auch im schlimmsten Fall?“ |
|
||||
| Stärke | beliebige Kennzahlen, sehr flexibel | nutzt Wahrscheinlichkeiten voll aus | keine Verteilungsannahme nötig |
|
||||
| Schwäche | keine Optimierung | Wahrscheinlichkeiten müssen stimmen | oft übervorsichtig, kostet Ertrag |
|
||||
| Nachzulesen in | {ref:sec:unsicherheit-monte-carlo-simulation} | {ref:sec:unsicherheit-zweistufige-stochastische-programmierung} | {ref:sec:unsicherheit-robuste-optimierung-gegen-den-worst-case} |
|
||||
| | **Monte-Carlo** | **Stochastische Programmierung** | **Robuste Optimierung** | **Chance Constraints** |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Braucht | Verteilung | Szenarien **mit Wahrscheinlichkeiten** | nur eine **Menge** möglicher Werte | Verteilung **oder** Szenarien |
|
||||
| Optimiert | nichts (bewertet nur) | **Erwartungswert** über Szenarien | **Worst Case** in der Menge | Kosten bei **zugesicherter Quote** |
|
||||
| Typische Frage | „Wie riskant ist dieser Plan?“ | „Was ist im Mittel am besten?“ | „Was hält auch im schlimmsten Fall?“ | „Was hält in 95 % der Fälle?“ |
|
||||
| Stärke | beliebige Kennzahlen, sehr flexibel | nutzt Wahrscheinlichkeiten voll aus | keine Verteilungsannahme nötig | die Zusage steht **im Modell** |
|
||||
| Schwäche | keine Optimierung | Wahrscheinlichkeiten müssen stimmen | oft übervorsichtig, kostet Ertrag | Zusage gilt nur für die unterstellte Verteilung |
|
||||
| Nachzulesen in | {ref:sec:unsicherheit-monte-carlo-simulation} | {ref:sec:unsicherheit-zweistufige-stochastische-programmierung} | {ref:sec:unsicherheit-robuste-optimierung-gegen-den-worst-case} | {ref:sec:unsicherheit-chance-constraints} |
|
||||
|
||||
**Der Unterschied zwischen den letzten beiden** ist der, an dem die meisten Diskussionen
|
||||
hängenbleiben. Die robuste Optimierung sagt: *„Es darf **nie** schiefgehen“* — und zahlt
|
||||
dafür. Die Chance Constraint sagt: *„Es darf in höchstens 5 % der Fälle schiefgehen“* — und
|
||||
macht damit verhandelbar, was die Sicherheit kosten darf.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -791,6 +802,427 @@ if __name__ == "__main__":
|
|||
|
||||
---
|
||||
|
||||
## Wahrscheinlichkeitsbeschränkungen: „mit 95 % Sicherheit“ {#sec:unsicherheit-chance-constraints}
|
||||
|
||||
Die drei bisherigen Ansätze beantworten Fragen, die im Sitzungssaal selten so gestellt
|
||||
werden. „Was ist im Mittel am besten?“ hört ein Vorstand als Ausflucht; „was hält auch im
|
||||
schlimmsten Fall?“ als Einladung, zu viel Geld auszugeben. Gefragt wird fast immer nach einer
|
||||
**Wahrscheinlichkeit**: *Mit welcher Sicherheit hält der Plan?*
|
||||
|
||||
Die **Wahrscheinlichkeitsbeschränkung**{idx:Chance Constraint} schreibt genau das ins Modell:
|
||||
|
||||
$$
|
||||
\mathbb{P}\!\left(\mathbf{a}^\top\mathbf{x} \ge b\right) \ge 1 - \alpha
|
||||
$$
|
||||
|
||||
> **📐 Formel-Lesehilfe**
|
||||
> * $\mathbf{a}$ — der **unsichere** Vektor: Verfügbarkeiten, Erträge, Fahrzeiten. Er ist
|
||||
> keine Zahl, sondern eine Zufallsgröße.
|
||||
> * $\mathbf{x}$ — Ihre Entscheidung. Sie fällt, **bevor** $\mathbf{a}$ sich zeigt.
|
||||
> * $\alpha$ — die Ausfallwahrscheinlichkeit, die Sie akzeptieren. $\alpha = 0{,}05$ heißt
|
||||
> „in höchstens 5 % der Fälle darf es schiefgehen“.
|
||||
>
|
||||
> **Ohne Formel gesagt:** „Plane so, dass die Zusage in 95 von 100 Fällen hält — und sag mir,
|
||||
> was das kostet.“
|
||||
|
||||
**Das Problem daran.** So aufgeschrieben ist die Bedingung nicht lösbar: Ein Solver kann
|
||||
nichts mit einem Wahrscheinlichkeitsoperator anfangen. Es braucht einen Weg, sie in etwas zu
|
||||
übersetzen, das ein Optimierer versteht. Es gibt zwei, und sie unterscheiden sich in dem,
|
||||
was sie über die Verteilung voraussetzen.
|
||||
|
||||
### Weg 1: Normalverteilung — die Bedingung wird ein Kegel
|
||||
|
||||
Ist $\mathbf{a} \sim \mathcal{N}(\hat{\mathbf{a}}, \boldsymbol{\Sigma})$, dann ist
|
||||
$\mathbf{a}^\top\mathbf{x}$ für festes $\mathbf{x}$ selbst normalverteilt, mit Erwartungswert
|
||||
$\hat{\mathbf{a}}^\top\mathbf{x}$ und Standardabweichung
|
||||
$\sqrt{\mathbf{x}^\top\boldsymbol{\Sigma}\mathbf{x}}$. Damit lässt sich die Wahrscheinlichkeit
|
||||
durch ein Quantil ersetzen:
|
||||
|
||||
$$
|
||||
\hat{\mathbf{a}}^\top\mathbf{x} \;-\; z_{1-\alpha}\,\lVert \mathbf{L}^\top\mathbf{x}\rVert_2
|
||||
\;\ge\; b
|
||||
\qquad\text{mit}\qquad
|
||||
\boldsymbol{\Sigma} = \mathbf{L}\mathbf{L}^\top,\quad
|
||||
z_{1-\alpha} = \Phi^{-1}(1-\alpha)
|
||||
$$
|
||||
|
||||
Das ist eine **Second-Order-Cone-Bedingung**{idx:Konische Optimierung (SOCP, SDP)} — dieselbe
|
||||
Bauform, die {ref:kap:qp-nlp} eingeführt hat, und CVXPY löst sie ohne Umstände.
|
||||
|
||||
> **🎯 Warum eine Norm und keine Summe**
|
||||
> Der Sicherheitszuschlag $\lVert\mathbf{L}^\top\mathbf{x}\rVert_2$ ist **keine** Summe von
|
||||
> Einzelzuschlägen je Anlage. Genau darin steckt der Nutzen der Mischung: Zwei gegenläufige
|
||||
> Quellen schwanken **gemeinsam** weniger als jede für sich, und die Norm rechnet das
|
||||
> automatisch mit. Ein fester Aufschlag je Anlage könnte das nicht — er wäre linear und
|
||||
> würde Diversifikation nicht belohnen.
|
||||
|
||||
### Weg 2: Szenarien — Big-M ohne Verteilungsannahme
|
||||
|
||||
Liegen statt einer Verteilung nur $S$ beobachtete Szenarien vor, bekommt jedes eine
|
||||
Binärvariable $z_s$, die sagt, ob es verletzt werden **darf**:
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
\mathbf{a}_s^\top\mathbf{x} &\ge b - M z_s && \forall s\\
|
||||
\sum_{s} z_s &\le \alpha S\\
|
||||
z_s &\in \{0,1\}
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
Aus dem Kegelproblem wird ein MILP mit $S$ Binärvariablen. Für $M$ gilt, was
|
||||
{ref:kap:milp} über die Big-M-Falle sagt: **so klein wie möglich**. Hier ist $M = b$ die
|
||||
kleinste gültige Schranke, denn $\mathbf{a}_s^\top\mathbf{x} \ge 0$ — größer kann eine
|
||||
Verletzung gar nicht ausfallen.
|
||||
|
||||
### Der Fall: ein Kraftwerkspark mit 500 MW Zusage
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Chance_Constraints.py
|
||||
"""
|
||||
Kapitel Unsicherheit: Wahrscheinlichkeitsbeschraenkungen.
|
||||
|
||||
Das Management fragt selten "was ist im Mittel am besten?", sondern "mit
|
||||
welcher Sicherheit haelt der Plan?". Genau das formuliert eine Chance
|
||||
Constraint: P(Versorgung >= Bedarf) >= 1 - alpha.
|
||||
|
||||
Gezeigt werden beide Wege dorthin, an derselben Instanz:
|
||||
(a) analytisch - unter Normalverteilungsannahme wird daraus eine
|
||||
Second-Order-Cone-Bedingung, loesbar mit CVXPY
|
||||
(b) szenariobasiert - Big-M mit Binaervariablen, fuer beliebige
|
||||
empirische Verteilungen
|
||||
|
||||
Und die beiden Messungen, auf die es ankommt: Was kostet ein Prozentpunkt
|
||||
Versorgungssicherheit - und haelt die Zusage auch dann, wenn die Verteilung
|
||||
nicht normal ist?
|
||||
|
||||
Solver: CLARABEL (Kegel) und SciPy/HiGHS (gemischt-ganzzahlig). Weder ortools
|
||||
noch ein direkter highspy-Import, damit alles in einem Prozess laeuft.
|
||||
"""
|
||||
|
||||
import cvxpy as cp
|
||||
import numpy as np
|
||||
from scipy.stats import norm
|
||||
|
||||
# --- Der Kraftwerkspark ----------------------------------------------------
|
||||
# Die Verfuegbarkeit ist der Anteil, den eine installierte MW im Mittel
|
||||
# wirklich liefert: bei Wind und Sonne klein und stark schwankend, bei Gas und
|
||||
# Biomasse gross und stabil. Die Ausbaugrenze ist der Standort - Flaeche,
|
||||
# Genehmigung, Brennstoffversorgung.
|
||||
TECHNIK = ["Gaskraftwerk", "Windpark", "Solarpark", "Biomasse"]
|
||||
KOSTEN = np.array([65_000.0, 24_000.0, 12_000.0, 60_000.0]) # EUR je MW und Jahr
|
||||
VERFUEGBAR = np.array([0.92, 0.35, 0.18, 0.85])
|
||||
STREUUNG = np.array([0.05, 0.16, 0.10, 0.04])
|
||||
GRENZE = np.array([400.0, 250.0, 600.0, 350.0]) # MW
|
||||
|
||||
# Wind und Sonne sind leicht gegenlaeufig: Ein Tiefdruckgebiet bringt Wind und
|
||||
# Wolken zugleich. Genau diese Korrelation macht die Bedingung zu einem Kegel
|
||||
# und nicht zu einer Summe unabhaengiger Einzelzuschlaege.
|
||||
KORRELATION = np.array([
|
||||
[1.00, 0.00, 0.00, 0.05],
|
||||
[0.00, 1.00, -0.25, 0.00],
|
||||
[0.00, -0.25, 1.00, 0.00],
|
||||
[0.05, 0.00, 0.00, 1.00],
|
||||
])
|
||||
SIGMA = np.diag(STREUUNG) @ KORRELATION @ np.diag(STREUUNG)
|
||||
WURZEL = np.linalg.cholesky(SIGMA) # L mit L @ L.T == SIGMA
|
||||
|
||||
BEDARF = 500.0 # MW, die gesichert bereitstehen muessen
|
||||
N = len(TECHNIK)
|
||||
|
||||
# Die Kaeltewelle mit Dunkelflaute: selten, aber sie trifft alles zugleich.
|
||||
# Wind und Sonne brechen fast vollstaendig weg - und, das ist der Punkt, das
|
||||
# Gaskraftwerk liefert ebenfalls weniger, weil bei Frost der Netzdruck faellt.
|
||||
# Eine Kovarianzmatrix mit Korrelationen um null kann das nicht ausdruecken.
|
||||
P_KAELTEWELLE = 0.08
|
||||
EINBRUCH = np.array([0.72, 0.10, 0.15, 0.88])
|
||||
|
||||
|
||||
def mittelwertplan():
|
||||
"""Plant mit den Erwartungswerten - ignoriert die Streuung vollstaendig."""
|
||||
x = cp.Variable(N, nonneg=True)
|
||||
problem = cp.Problem(cp.Minimize(KOSTEN @ x),
|
||||
[VERFUEGBAR @ x >= BEDARF, x <= GRENZE])
|
||||
problem.solve(solver=cp.CLARABEL)
|
||||
return problem.value, x.value
|
||||
|
||||
|
||||
def chance_constraint_analytisch(alpha):
|
||||
"""
|
||||
P(a^T x >= BEDARF) >= 1 - alpha unter a ~ N(VERFUEGBAR, SIGMA).
|
||||
|
||||
Aequivalent zu: VERFUEGBAR^T x - z * ||L^T x||_2 >= BEDARF
|
||||
mit z = Phi^-1(1 - alpha). Das ist eine Second-Order-Cone-Bedingung: Der
|
||||
Sicherheitszuschlag ist eine Norm ueber x, kein fester Aufschlag je Anlage.
|
||||
Deshalb belohnt sie Mischung - zwei gegenlaeufige Quellen schwanken
|
||||
gemeinsam weniger als jede fuer sich.
|
||||
"""
|
||||
x = cp.Variable(N, nonneg=True)
|
||||
z = norm.ppf(1 - alpha)
|
||||
bedingung = VERFUEGBAR @ x - z * cp.norm(WURZEL.T @ x, 2) >= BEDARF
|
||||
problem = cp.Problem(cp.Minimize(KOSTEN @ x), [bedingung, x <= GRENZE])
|
||||
problem.solve(solver=cp.CLARABEL)
|
||||
return problem.value, x.value
|
||||
|
||||
|
||||
def chance_constraint_szenarien(a, alpha):
|
||||
"""
|
||||
Dieselbe Zusage ohne Verteilungsannahme: Fuer jedes Szenario s sagt eine
|
||||
Binaervariable z_s, ob es verletzt werden darf.
|
||||
|
||||
a_s^T x >= BEDARF - M * z_s fuer alle s
|
||||
sum_s z_s <= alpha * S
|
||||
|
||||
M = BEDARF ist die kleinstmoegliche gueltige Schranke, denn a_s^T x >= 0:
|
||||
Groesser kann eine Verletzung gar nicht ausfallen. Ein unnoetig grosses M
|
||||
wuerde die LP-Relaxierung aufweichen und die Suche verlangsamen - die
|
||||
Big-M-Falle aus dem Kapitel Gemischt-ganzzahlige Optimierung.
|
||||
"""
|
||||
S = len(a)
|
||||
x = cp.Variable(N, nonneg=True)
|
||||
z = cp.Variable(S, boolean=True)
|
||||
problem = cp.Problem(
|
||||
cp.Minimize(KOSTEN @ x),
|
||||
[a @ x >= BEDARF - BEDARF * z, cp.sum(z) <= alpha * S, x <= GRENZE])
|
||||
problem.solve(solver=cp.SCIPY)
|
||||
return problem.value, x.value
|
||||
|
||||
|
||||
def ziehe_wetter(anzahl, seed):
|
||||
"""Mischverteilung: normales Wetter, mit P_KAELTEWELLE ein Einbruch."""
|
||||
rng = np.random.default_rng(seed)
|
||||
a = rng.multivariate_normal(VERFUEGBAR, SIGMA, size=anzahl)
|
||||
getroffen = rng.random(anzahl) < P_KAELTEWELLE
|
||||
a[getroffen] *= EINBRUCH
|
||||
return np.clip(a, 0.0, 1.0)
|
||||
|
||||
|
||||
def sicherheit(x, a):
|
||||
"""Anteil der Szenarien, in denen der Plan den Bedarf deckt."""
|
||||
return float(np.mean(a @ x >= BEDARF))
|
||||
|
||||
|
||||
KOPF = (f"{'Plan':<20} {'Kosten (EUR)':>13} {'Gas':>4} {'Wind':>4} "
|
||||
f"{'Sol':>4} {'Bio':>4} {'Normalwelt':>11} {'echte Welt':>11}")
|
||||
|
||||
|
||||
def zeile(name, kosten, x, in_normal, in_echt):
|
||||
mix = " ".join(f"{w:4.0f}" for w in x)
|
||||
return (f"{name:<20} {kosten:>13,.0f} {mix} "
|
||||
f"{in_normal * 100:>9.2f} % {in_echt * 100:>9.2f} %")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 78)
|
||||
print(" WAHRSCHEINLICHKEITSBESCHRAENKUNGEN IM KRAFTWERKSPARK")
|
||||
print("=" * 78)
|
||||
print(f"Gesichert bereitzustellen: {BEDARF:.0f} MW\n")
|
||||
print(f"{'Technologie':<14} {'EUR/MW':>8} {'verfuegbar':>11} {'Streuung':>9} "
|
||||
f"{'Grenze':>8} {'EUR je erw. MW':>15}")
|
||||
print("-" * 78)
|
||||
for i, name in enumerate(TECHNIK):
|
||||
print(f"{name:<14} {KOSTEN[i]:>8,.0f} {VERFUEGBAR[i]:>10.2f} "
|
||||
f"{STREUUNG[i]:>8.2f} {GRENZE[i]:>7.0f} "
|
||||
f"{KOSTEN[i] / VERFUEGBAR[i]:>15,.0f}")
|
||||
print(f"\nVollausbau liefert im Mittel {VERFUEGBAR @ GRENZE:.0f} MW, "
|
||||
f"in der Kaeltewelle {(VERFUEGBAR * EINBRUCH) @ GRENZE:.0f} MW.")
|
||||
|
||||
# Zwei grosse, unabhaengige Testmengen. An ihnen wird JEDER Plan gemessen -
|
||||
# einmal in der unterstellten Normalwelt, einmal in der echten Verteilung.
|
||||
echt = ziehe_wetter(200_000, seed=771)
|
||||
normalwelt = np.random.default_rng(4711).multivariate_normal(
|
||||
VERFUEGBAR, SIGMA, size=200_000)
|
||||
|
||||
print("\n" + "=" * 78)
|
||||
print(" (1) Mittelwertplan und Chance Constraints im Vergleich")
|
||||
print("=" * 78)
|
||||
print(KOPF)
|
||||
print("-" * 78)
|
||||
|
||||
k_mittel, x_mittel = mittelwertplan()
|
||||
stufen = [("Mittelwert", k_mittel, sicherheit(x_mittel, normalwelt))]
|
||||
print(zeile("Mittelwert", k_mittel, x_mittel,
|
||||
sicherheit(x_mittel, normalwelt), sicherheit(x_mittel, echt)))
|
||||
|
||||
plaene = {}
|
||||
for alpha in (0.20, 0.10, 0.05, 0.01):
|
||||
kosten, x = chance_constraint_analytisch(alpha)
|
||||
plaene[alpha] = (kosten, x)
|
||||
quote_normal = sicherheit(x, normalwelt)
|
||||
stufen.append((f"Zusage {(1 - alpha) * 100:.0f} %", kosten, quote_normal))
|
||||
print(zeile(f"Zusage {(1 - alpha) * 100:.0f} %", kosten, x,
|
||||
quote_normal, sicherheit(x, echt)))
|
||||
|
||||
print("\n In der Normalwelt trifft jede Zusage ihren Wert - das Verfahren")
|
||||
print(" rechnet richtig. Die Spalte 'echte Welt' kommt in Teil (3).")
|
||||
|
||||
print("\n" + "=" * 78)
|
||||
print(" (2) Was kostet ein Prozentpunkt Versorgungssicherheit?")
|
||||
print("=" * 78)
|
||||
print(f"{'von -> nach':<26} {'Prozentpunkte':>13} {'Mehrkosten':>13} "
|
||||
f"{'EUR je Punkt':>13}")
|
||||
print("-" * 78)
|
||||
for (n1, k1, q1), (n2, k2, q2) in zip(stufen, stufen[1:]):
|
||||
d_punkte = (q2 - q1) * 100
|
||||
d_kosten = k2 - k1
|
||||
print(f"{n1 + ' -> ' + n2:<26} {d_punkte:>13.2f} {d_kosten:>13,.0f} "
|
||||
f"{d_kosten / d_punkte:>13,.0f}")
|
||||
erst = (stufen[1][1] - stufen[0][1]) / ((stufen[1][2] - stufen[0][2]) * 100)
|
||||
letzt = (stufen[-1][1] - stufen[-2][1]) / ((stufen[-1][2] - stufen[-2][2]) * 100)
|
||||
print(f"\n Der letzte Prozentpunkt kostet das {letzt / erst:.1f}-fache des ersten.")
|
||||
print(" Sicherheit ist konvex bepreist - genau deshalb muss jemand")
|
||||
print(" entscheiden, wie viel davon das Unternehmen kaufen will.")
|
||||
|
||||
print("\n" + "=" * 78)
|
||||
print(" (3) Und wenn die Verteilung nicht normal ist?")
|
||||
print("=" * 78)
|
||||
k_soc, x_soc = plaene[0.05]
|
||||
print(f"Die echte Welt kennt die Kaeltewelle mit Dunkelflaute: in "
|
||||
f"{P_KAELTEWELLE * 100:.0f} % der Faelle liefern")
|
||||
print(f"Wind {EINBRUCH[1] * 100:.0f} %, Sonne {EINBRUCH[2] * 100:.0f} % "
|
||||
f"und - entscheidend - auch das Gaskraftwerk nur "
|
||||
f"{EINBRUCH[0] * 100:.0f} %")
|
||||
print("des Ueblichen. Alles bricht gleichzeitig ein.\n")
|
||||
|
||||
a_bau = ziehe_wetter(400, seed=20260908)
|
||||
k_sz, x_sz = chance_constraint_szenarien(a_bau, 0.05)
|
||||
|
||||
print(KOPF)
|
||||
print("-" * 78)
|
||||
print(zeile("SOC, Zusage 95 %", k_soc, x_soc,
|
||||
sicherheit(x_soc, normalwelt), sicherheit(x_soc, echt)))
|
||||
print(zeile("Szenarien, 95 %", k_sz, x_sz,
|
||||
sicherheit(x_sz, normalwelt), sicherheit(x_sz, echt)))
|
||||
|
||||
print(f"\n Der SOC-Plan verspricht 95 % und haelt "
|
||||
f"{sicherheit(x_soc, echt) * 100:.1f} %. Nicht das Verfahren ist")
|
||||
print(f" falsch, sondern die Annahme: In der Normalwelt liefert derselbe")
|
||||
print(f" Plan {sicherheit(x_soc, normalwelt) * 100:.1f} %.")
|
||||
print(f"\n Der Szenarioplan ({len(a_bau)} Szenarien, {len(a_bau)} "
|
||||
f"Binaervariablen) kommt auf")
|
||||
print(f" {sicherheit(x_sz, echt) * 100:.1f} % - und kostet dafuer "
|
||||
f"{(k_sz / k_soc - 1) * 100:+.1f} %. Er kauft keine Windkraft mehr:")
|
||||
print(" Was im Ernstfall ausfaellt, hilft der Zusage nicht.")
|
||||
print("=" * 78)
|
||||
```
|
||||
|
||||
**Ausgabe:**
|
||||
|
||||
```
|
||||
==============================================================================
|
||||
WAHRSCHEINLICHKEITSBESCHRAENKUNGEN IM KRAFTWERKSPARK
|
||||
==============================================================================
|
||||
Gesichert bereitzustellen: 500 MW
|
||||
|
||||
Technologie EUR/MW verfuegbar Streuung Grenze EUR je erw. MW
|
||||
------------------------------------------------------------------------------
|
||||
Gaskraftwerk 65,000 0.92 0.05 400 70,652
|
||||
Windpark 24,000 0.35 0.16 250 68,571
|
||||
Solarpark 12,000 0.18 0.10 600 66,667
|
||||
Biomasse 60,000 0.85 0.04 350 70,588
|
||||
|
||||
Vollausbau liefert im Mittel 861 MW, in der Kaeltewelle 552 MW.
|
||||
|
||||
==============================================================================
|
||||
(1) Mittelwertplan und Chance Constraints im Vergleich
|
||||
==============================================================================
|
||||
Plan Kosten (EUR) Gas Wind Sol Bio Normalwelt echte Welt
|
||||
------------------------------------------------------------------------------
|
||||
Mittelwert 34,694,565 8 250 600 350 50.08 % 46.18 %
|
||||
Zusage 80 % 36,382,277 226 25 44 343 80.06 % 73.61 %
|
||||
Zusage 90 % 36,994,777 233 20 35 349 89.99 % 82.82 %
|
||||
Zusage 95 % 37,514,307 241 19 31 350 94.97 % 87.44 %
|
||||
Zusage 99 % 38,529,698 258 18 28 350 98.97 % 91.05 %
|
||||
|
||||
In der Normalwelt trifft jede Zusage ihren Wert - das Verfahren
|
||||
rechnet richtig. Die Spalte 'echte Welt' kommt in Teil (3).
|
||||
|
||||
==============================================================================
|
||||
(2) Was kostet ein Prozentpunkt Versorgungssicherheit?
|
||||
==============================================================================
|
||||
von -> nach Prozentpunkte Mehrkosten EUR je Punkt
|
||||
------------------------------------------------------------------------------
|
||||
Mittelwert -> Zusage 80 % 29.98 1,687,712 56,289
|
||||
Zusage 80 % -> Zusage 90 % 9.93 612,500 61,685
|
||||
Zusage 90 % -> Zusage 95 % 4.98 519,530 104,365
|
||||
Zusage 95 % -> Zusage 99 % 4.00 1,015,390 253,848
|
||||
|
||||
Der letzte Prozentpunkt kostet das 4.5-fache des ersten.
|
||||
Sicherheit ist konvex bepreist - genau deshalb muss jemand
|
||||
entscheiden, wie viel davon das Unternehmen kaufen will.
|
||||
|
||||
==============================================================================
|
||||
(3) Und wenn die Verteilung nicht normal ist?
|
||||
==============================================================================
|
||||
Die echte Welt kennt die Kaeltewelle mit Dunkelflaute: in 8 % der Faelle liefern
|
||||
Wind 10 %, Sonne 15 % und - entscheidend - auch das Gaskraftwerk nur 72 %
|
||||
des Ueblichen. Alles bricht gleichzeitig ein.
|
||||
|
||||
Plan Kosten (EUR) Gas Wind Sol Bio Normalwelt echte Welt
|
||||
------------------------------------------------------------------------------
|
||||
SOC, Zusage 95 % 37,514,307 241 19 31 350 94.97 % 87.44 %
|
||||
Szenarien, 95 % 43,760,709 350 0 0 350 100.00 % 94.84 %
|
||||
|
||||
Der SOC-Plan verspricht 95 % und haelt 87.4 %. Nicht das Verfahren ist
|
||||
falsch, sondern die Annahme: In der Normalwelt liefert derselbe
|
||||
Plan 95.0 %.
|
||||
|
||||
Der Szenarioplan (400 Szenarien, 400 Binaervariablen) kommt auf
|
||||
94.8 % - und kostet dafuer +16.7 %. Er kauft keine Windkraft mehr:
|
||||
Was im Ernstfall ausfaellt, hilft der Zusage nicht.
|
||||
==============================================================================
|
||||
```
|
||||
|
||||
**Drei Befunde, die man dem Plan nicht ansieht.**
|
||||
|
||||
**Erstens: Der Mittelwertplan fällt in der Hälfte aller Fälle aus.** Das ist kein Fehler,
|
||||
sondern die Definition des Erwartungswerts — und dieselbe Falle wie in
|
||||
{ref:sec:unsicherheit-der-fluch-des-durchschnitts}, nur teurer. Er kauft die billigsten
|
||||
Quellen je *erwarteter* Megawattstunde und maximiert Wind und Sonne bis an die Ausbaugrenze.
|
||||
Sobald die Zusage im Modell steht, dreht sich das Bild: Gas und Biomasse tragen den Plan,
|
||||
Wind und Sonne schrumpfen auf einen Rest.
|
||||
|
||||
**Zweitens: Sicherheit ist konvex bepreist.** Die ersten dreißig Prozentpunkte kosten rund
|
||||
56 000 € pro Punkt, die letzten vier rund 254 000 € — das **4,5-fache**. Das ist die Zahl,
|
||||
die in die Vorlage gehört: Nicht „was kostet Versorgungssicherheit“, sondern „was kostet der
|
||||
*nächste* Prozentpunkt“. Wer 99,9 % fordert, ohne diese Kurve gesehen zu haben, fordert ins
|
||||
Blaue.
|
||||
|
||||
**Drittens — und das ist der unangenehme Befund: Die Zusage gilt nur für die unterstellte
|
||||
Verteilung.** Der Plan verspricht 95 % und hält **87,4 %**. Nicht weil das Verfahren falsch
|
||||
rechnet: In einer reinen Normalwelt liefert derselbe Plan exakt seine 95,0 %. Sondern weil
|
||||
die Normalverteilung eine Kältewelle mit Dunkelflaute nicht kennt. In der bricht **alles
|
||||
zugleich** ein — auch das Gaskraftwerk, weil bei Frost der Netzdruck fällt. Eine
|
||||
Kovarianzmatrix mit Korrelationen um null kann so etwas nicht ausdrücken.
|
||||
|
||||
Der szenariobasierte Weg kennt diese Fälle, weil sie in den Daten stehen. Er kommt auf
|
||||
94,8 %, kostet dafür 16,7 % mehr — und kauft **keine Windkraft mehr**. Die Logik dahinter ist
|
||||
hart und richtig: Was im Ernstfall ausfällt, hilft der Zusage nicht.
|
||||
|
||||
> **⚠️ Die Szenariomethode überanpasst — und mehr Szenarien helfen nicht verlässlich**
|
||||
> Bei $S$ Szenarien und $\alpha = 5\,\%$ darf das Modell genau $0{,}05 \cdot S$ davon
|
||||
> ignorieren — und es sucht sich die **teuersten** aus. In der Stichprobe trifft es seine
|
||||
> Quote dadurch immer; außerhalb streut sie.
|
||||
>
|
||||
> Gemessen an zwölf Läufen dieses Modells (je vier Ziehungen bei $S = 200$, $400$, $800$,
|
||||
> geprüft an 200 000 unabhängigen Szenarien): Die tatsächliche Quote lag zwischen
|
||||
> **93,1 % und 96,7 %**. Die Spanne wurde von $S = 200$ auf $400$ enger (3,5 → 1,2
|
||||
> Prozentpunkte), bei $S = 800$ aber wieder breiter (3,1) — die Zahl der Szenarien allein
|
||||
> schließt die Lücke also nicht.
|
||||
>
|
||||
> **Konsequenz für die Praxis:** Eine mit Szenarien erkaufte Zusage immer an einer
|
||||
> **zurückgehaltenen** Stichprobe nachmessen, so wie es das Programm oben tut. Wer nur die
|
||||
> Trefferquote in den Baudaten berichtet, berichtet eine Tautologie — dieselbe Falle wie beim
|
||||
> Backtest in {ref:kap:handelsmaschine}.
|
||||
|
||||
> **🎯 Merksatz**
|
||||
> Die robuste Optimierung fragt „was, wenn alles schiefgeht?“, die Chance Constraint „wie oft
|
||||
> darf es schiefgehen?“. Nur die zweite Frage hat eine Antwort, über die man verhandeln
|
||||
> kann — und nur sie zwingt dazu, den Preis eines Prozentpunkts Sicherheit zu beziffern.
|
||||
|
||||
---
|
||||
|
||||
## Übungsaufgaben {#sec:unsicherheit-uebungsaufgaben}
|
||||
|
||||
> Lösungen: {ref:sec:loesungen-unsicherheit}.
|
||||
|
|
@ -801,11 +1233,12 @@ Ein Bauunternehmer plant mit der *durchschnittlichen* Bauzeit von 8 Monaten. War
|
|||
sind als Beschleunigungen? Nennen Sie zwei weitere Alltagsbeispiele.
|
||||
|
||||
**Aufgabe ⭐ — Ansatz wählen.**
|
||||
Welcher der drei Ansätze passt? Begründen Sie:
|
||||
Welcher der vier Ansätze passt? Begründen Sie:
|
||||
(a) Wie viele Notstromaggregate für ein Krankenhaus?
|
||||
(b) Wie viel Weizen einkaufen bei bekannter Preisverteilung?
|
||||
(c) Wie hoch ein Deich gebaut werden muss?
|
||||
(d) Wie viele Saisonkräfte einstellen bei bekannten Nachfrageszenarien?
|
||||
(e) Wie viel Speicherkapazität, damit ein Gasnetz an 99 % aller Wintertage hält?
|
||||
|
||||
**Aufgabe ⭐⭐ — Zweistufiges Modell rechnen.**
|
||||
Wiederholen Sie die Handrechnung *Warum der Mittelwert in die Irre führt* mit geänderten Kosten: Spot 60 € statt 120 €.
|
||||
|
|
@ -824,6 +1257,16 @@ Erweitern Sie `Monte_Carlo.py`:
|
|||
(b) Berechnen Sie den CVaR der Kosten (Mittelwert der schlechtesten 5 %).
|
||||
(c) Zeichnen Sie ein Histogramm der Kosten für drei Kapazitäten.
|
||||
|
||||
**Aufgabe ⭐⭐ — Den Preis der Zusage selbst bestimmen.**
|
||||
`Chance_Constraints.py` beziffert die Kosten für 80, 90, 95 und 99 %.
|
||||
(a) Ergänzen Sie die Stufen 99,5 % und 99,9 % und setzen Sie die Kosten je Prozentpunkt fort.
|
||||
Was passiert mit dem Anlagenmix?
|
||||
(b) Drosseln Sie die Ausbaugrenze der Biomasse von 350 auf 200 MW. Das **szenariobasierte**
|
||||
Modell meldet dann bei 95 % `infeasible`, das **analytische** dagegen `optimal`. Erklären
|
||||
Sie den Unterschied. Welchem der beiden würden Sie glauben?
|
||||
(c) Ein Vorstand fordert „99,99 % Versorgungssicherheit“. Formulieren Sie in drei Sätzen,
|
||||
was Sie ihm mit dieser Kurve antworten.
|
||||
|
||||
**Aufgabe ⭐⭐⭐ — Budgeted Uncertainty.**
|
||||
Erweitern Sie `Robuste_Optimierung.py` um den Ansatz von Bertsimas/Sim: Höchstens
|
||||
$\Gamma$ Titel nehmen gleichzeitig ihren Worst Case an. Variieren Sie
|
||||
|
|
@ -931,6 +1374,10 @@ das lässt sich in CVXPY mit `cp.sum_largest` formulieren.)
|
|||
3. Was misst der EVPI, und wofür ist er praktisch nützlich?
|
||||
4. Warum braucht robuste Optimierung keine Wahrscheinlichkeiten?
|
||||
5. Wie macht man ein Min-Max-Problem mit Box-Unsicherheit lösbar?
|
||||
6. Warum wird aus $\mathbb{P}(\mathbf{a}^\top\mathbf{x} \ge b) \ge 1-\alpha$ unter
|
||||
Normalverteilung eine **Norm** und nicht ein fester Zuschlag je Variable?
|
||||
7. Ein Plan mit Chance Constraint verspricht 95 % und hält gemessen 87 %. Woran liegt das —
|
||||
und was ändert die szenariobasierte Formulierung daran?
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -951,6 +1398,16 @@ das lässt sich in CVXPY mit `cp.sum_largest` formulieren.)
|
|||
* **Der EVPI** begrenzt, was eine perfekte Prognose wert sein darf.
|
||||
* **Robuste Optimierung** braucht keine Wahrscheinlichkeiten, nur eine Unsicherheitsmenge —
|
||||
und wird für einfache Mengen zu einem gewöhnlichen Problem mit Abzugsterm.
|
||||
* **Chance Constraints** schreiben die Zusage selbst ins Modell. Unter Normalverteilung wird
|
||||
daraus eine **Kegelbedingung** (der Sicherheitszuschlag ist eine Norm, deshalb belohnt sie
|
||||
Mischung), szenariobasiert ein **MILP mit Big-M** ohne jede Verteilungsannahme.
|
||||
* **Sicherheit ist konvex bepreist.** Im Beispiel kostet der letzte Prozentpunkt das
|
||||
4,5-fache des ersten. Die richtige Managementfrage lautet nicht „was kostet Sicherheit“,
|
||||
sondern „was kostet der *nächste* Prozentpunkt“.
|
||||
* **Eine Zusage gilt nur für die unterstellte Verteilung.** Ein Plan, der unter
|
||||
Normalverteilung 95 % verspricht, hielt gemessen 87 %, weil das Modell die Kältewelle
|
||||
nicht kannte, in der *alles* zugleich ausfällt. Szenariobasierte Zusagen wiederum
|
||||
überanpassen — beide müssen an zurückgehaltenen Daten nachgemessen werden.
|
||||
* **Beziffern Sie immer Preis und Nutzen der Absicherung.** Ohne beide Zahlen ist die
|
||||
Entscheidung nicht begründbar.
|
||||
|
||||
|
|
|
|||
|
|
@ -1492,6 +1492,9 @@ Projektkosten mit Nachträgen.
|
|||
(b) stochastisch (Verteilung bekannt).
|
||||
(c) robust bzw. Extremwertstatistik (seltene Ereignisse, katastrophale Folgen).
|
||||
(d) stochastisch (Szenarien mit Wahrscheinlichkeiten liegen vor).
|
||||
(e) Chance Constraint — die Zusage ist bereits als Quote formuliert („an 99 % aller
|
||||
Wintertage“). Robust wäre hier zu teuer (es gibt immer einen kälteren Tag), der
|
||||
Erwartungswert zu schwach (er sagt nichts über die Zusage).
|
||||
|
||||
**9.3 — Zweistufig rechnen.**
|
||||
(a) Mit Spot = 60: Ableitung bei $x \in (100,250)$: $40 - 60\cdot0{,}5 + 5\cdot0{,}5 =
|
||||
|
|
@ -1514,7 +1517,27 @@ genau diese Zahl braucht die Geschäftsleitung für die Entscheidung.
|
|||
(c) Erwartetes Bild: Bei kleiner Kapazität ist die Kostenverteilung stark rechtsschief
|
||||
(seltene, teure Notzukäufe); bei großer Kapazität schmal und nach rechts verschoben.
|
||||
|
||||
**9.6 — Budgeted Uncertainty.**
|
||||
**9.6 — Den Preis der Zusage selbst bestimmen.**
|
||||
(a) Die Kosten je Prozentpunkt steigen weiter steil an; der Mix verschiebt sich dabei fast
|
||||
nur noch zugunsten des Gaskraftwerks, weil Biomasse längst an ihrer Ausbaugrenze liegt.
|
||||
Wind und Sonne bleiben bei einem kleinen Rest — sie senken über ihre Gegenläufigkeit die
|
||||
Norm, tragen zur gesicherten Leistung aber kaum bei.
|
||||
(b) Der Unterschied ist **nicht** numerisch, sondern inhaltlich. Bei 200 MW Biomasse liefert
|
||||
selbst der **Vollausbau** in der Kältewelle nur rund 440 MW — 7,5 % der Szenarien sind
|
||||
schlicht nicht bedienbar, egal wie viel Geld man ausgibt. Das Szenariomodell sieht diese
|
||||
Fälle in den Daten und meldet korrekt `infeasible`, sobald die Zusage über 92 % steigt. Das
|
||||
analytische Modell kennt sie nicht: Für eine Normalverteilung ist jede Zusage unter 100 %
|
||||
erfüllbar, wenn man nur genug Streuung wegkauft. Es meldet `optimal` — und der Plan hält
|
||||
gemessen 87,4 %.
|
||||
Glauben sollte man dem Szenariomodell: Ein `infeasible` ist hier die **richtige** Antwort.
|
||||
Es sagt, dass die Zusage nicht am Budget scheitert, sondern am Kraftwerkspark, und dass
|
||||
nicht mehr Geld hilft, sondern nur eine andere Anlage oder eine kleinere Zusage.
|
||||
(c) Sinngemäß: „99,99 % kosten nicht 5 % mehr als 99 %, sondern ein Vielfaches — der letzte
|
||||
Prozentpunkt ist bereits 4,5-mal so teuer wie der erste. Sagen Sie mir, was ein Ausfalltag
|
||||
das Unternehmen kostet, dann rechne ich aus, welche Quote sich lohnt. Und die Zusage gilt
|
||||
nur für die Wetterlagen, die wir modelliert haben — die Kältewelle gehört hinein.“
|
||||
|
||||
**9.7 — Budgeted Uncertainty.**
|
||||
```python
|
||||
abzug = cp.sum_largest(cp.multiply(UNSICHERHEIT, w), Gamma)
|
||||
ziel = cp.Maximize(MU_SCHAETZUNG @ w - abzug - 0.5*LAMBDA*cp.quad_form(w, SIGMA))
|
||||
|
|
@ -1625,6 +1648,16 @@ Fall, in dem es tatsächlich zulässig ist.
|
|||
optimiert gegen das schlechteste Element dieser Menge.
|
||||
5. Für einfache Mengen (Box, Ellipsoid) lässt sich das innere Maximum geschlossen ausrechnen
|
||||
und wird zu einem Abzugsterm; das Gesamtproblem bleibt konvex.
|
||||
6. Weil die Streuung der Summe $\mathbf{a}^\top\mathbf{x}$ nicht die Summe der Streuungen
|
||||
ist: $\sqrt{\mathbf{x}^\top\boldsymbol{\Sigma}\mathbf{x}}$ enthält die **Kovarianzen**.
|
||||
Ein fester Zuschlag je Variable wäre linear und würde deshalb übersehen, dass sich
|
||||
gegenläufige Größen teilweise aufheben — die Norm belohnt Mischung, ein linearer
|
||||
Aufschlag nicht.
|
||||
7. Weil die Zusage nur so gut ist wie die unterstellte Verteilung. Die Normalverteilung
|
||||
kennt keine Ereignisse, in denen alle Quellen **gleichzeitig** ausfallen; ihre schwachen
|
||||
Korrelationen unterschätzen genau den Fall, der die Zusage bricht. Die szenariobasierte
|
||||
Formulierung hat diese Fälle in den Daten und trifft die Quote — erkauft mit Mehrkosten
|
||||
und mit dem Risiko, sich an die verwendete Stichprobe anzupassen.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue