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
|
|
@ -801,11 +801,12 @@
|
|||
<hr />
|
||||
<h2 id="sec:loesungen-unsicherheit">A.12 Lösungen zu Kapitel „Optimierung unter Unsicherheit — Monte-Carlo, Stochastik, Robustheit“</h2>
|
||||
<p><strong>9.1 — Fluch des Durchschnitts.</strong> Weil sich Verzögerungen <strong>fortpflanzen</strong> und die Verteilung rechtsschief ist: Ein Gewerk, das früher fertig wird, beschleunigt selten den Gesamtablauf (der nächste Schritt ist noch nicht bereit), ein verspätetes verzögert alles. Weitere Beispiele: Wartezeiten in Warteschlangen (nichtlinear in der Auslastung), Projektkosten mit Nachträgen.</p>
|
||||
<p><strong>9.2 — Ansatz wählen.</strong> (a) robust (Ausfall ist existenziell, Wahrscheinlichkeiten unzuverlässig). (b) stochastisch (Verteilung bekannt). (c) robust bzw. Extremwertstatistik (seltene Ereignisse, katastrophale Folgen). (d) stochastisch (Szenarien mit Wahrscheinlichkeiten liegen vor).</p>
|
||||
<p><strong>9.2 — Ansatz wählen.</strong> (a) robust (Ausfall ist existenziell, Wahrscheinlichkeiten unzuverlässig). (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).</p>
|
||||
<p><strong>9.3 — Zweistufig rechnen.</strong> (a) Mit Spot = 60: Ableitung bei <span class="math inline">x \in (100,250)</span>: <span class="math inline">40 - 60\cdot0{,}5 + 5\cdot0{,}5 = 40-30+2{,}5 = +12{,}5 > 0</span> → Kapazität <strong>senken</strong>. Bei <span class="math inline">x < 100</span>: <span class="math inline">40 - 60 = -20 < 0</span> → erhöhen. Optimum daher <span class="math inline">x^* = 100</span>. (b) Billige Nachbesserung macht Vorhalten unattraktiv. (c) Bei <span class="math inline">x = 225</span> optimal müsste die Ableitung dort das Vorzeichen wechseln — das ist bei diskreten Szenarien nur zufällig der Fall; der Mittelwert ist nur bei symmetrischen Kosten und stetiger Verteilung optimal.</p>
|
||||
<p><strong>9.4 — EVPI interpretieren.</strong> Selbst eine <strong>perfekte</strong> Prognose wäre nur 8 400 € pro Jahr wert. Eine Lösung für 15 000 € kann sich also <strong>niemals</strong> rechnen — unabhängig von ihrer Güte. Argument: „Der theoretische Maximalnutzen liegt unter dem Preis.“</p>
|
||||
<p><strong>9.5 — Monte-Carlo erweitern.</strong> (a) Servicelevel 95 %: Kapazität = 95 %-Quantil des Bedarfs (ca. 485). Die Zusatzkosten gegenüber dem Kostenoptimum (180) betragen ein Vielfaches — Servicelevel ist teuer, und genau diese Zahl braucht die Geschäftsleitung für die Entscheidung. (b) <code>cvar = kosten[kosten >= np.quantile(kosten, 0.95)].mean()</code>. (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.</p>
|
||||
<p><strong>9.6 — Budgeted Uncertainty.</strong></p>
|
||||
<p><strong>9.6 — Den Preis der Zusage selbst bestimmen.</strong> (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 <strong>nicht</strong> numerisch, sondern inhaltlich. Bei 200 MW Biomasse liefert selbst der <strong>Vollausbau</strong> 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 <code>infeasible</code>, 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 <code>optimal</code> — und der Plan hält gemessen 87,4 %. Glauben sollte man dem Szenariomodell: Ein <code>infeasible</code> ist hier die <strong>richtige</strong> 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.“</p>
|
||||
<p><strong>9.7 — Budgeted Uncertainty.</strong></p>
|
||||
<div class="sourceCode" id="cb14"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>abzug <span class="op">=</span> cp.sum_largest(cp.multiply(UNSICHERHEIT, w), Gamma)</span>
|
||||
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>ziel <span class="op">=</span> cp.Maximize(MU_SCHAETZUNG <span class="op">@</span> w <span class="op">-</span> abzug <span class="op">-</span> <span class="fl">0.5</span><span class="op">*</span>LAMBDA<span class="op">*</span>cp.quad_form(w, SIGMA))</span></code></pre></div>
|
||||
<p><span class="math inline">\Gamma = 0</span> entspricht dem nominalen Fall, <span class="math inline">\Gamma = n</span> dem vollen Worst Case. Dazwischen steuert <span class="math inline">\Gamma</span> die Vorsicht stufenlos — der praktisch nützlichste Bereich liegt meist bei <span class="math inline">\Gamma \approx \sqrt{n}</span>.</p>
|
||||
|
|
@ -852,6 +853,8 @@ F(11{,}33) = 1 - \frac{(18-11{,}33)^2}{(18-6)(18-10)} = 1 - \frac{44{,}4}{96} =
|
|||
<li>Die Differenz zwischen Kosten unter Unsicherheit und Kosten bei perfektem Wissen — eine <strong>Obergrenze</strong> für den Wert jeder Prognoseverbesserung.</li>
|
||||
<li>Weil sie nur eine <strong>Menge</strong> möglicher Werte braucht, nicht deren Verteilung — sie optimiert gegen das schlechteste Element dieser Menge.</li>
|
||||
<li>Für einfache Mengen (Box, Ellipsoid) lässt sich das innere Maximum geschlossen ausrechnen und wird zu einem Abzugsterm; das Gesamtproblem bleibt konvex.</li>
|
||||
<li>Weil die Streuung der Summe <span class="math inline">\mathbf{a}^\top\mathbf{x}</span> nicht die Summe der Streuungen ist: <span class="math inline">\sqrt{\mathbf{x}^\top\boldsymbol{\Sigma}\mathbf{x}}</span> enthält die <strong>Kovarianzen</strong>. 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.</li>
|
||||
<li>Weil die Zusage nur so gut ist wie die unterstellte Verteilung. Die Normalverteilung kennt keine Ereignisse, in denen alle Quellen <strong>gleichzeitig</strong> 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.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<h2 id="sec:loesungen-dynamische-programmierung">A.13 Lösungen zu Kapitel „Dynamische Programmierung — Die Bellman-Gleichung und Order-Execution“</h2>
|
||||
|
|
|
|||
Loading…
Reference in a new issue