Glossar: Sprungleiste, Abkürzungen ausschreiben, CLAUDE.md-Regel
Sprungleiste (A B C ... Z) im Glossar — wie im Stichwortverzeichnis:
ein Klick je Buchstabe springt zur '## <Buchstabe>'-Überschrift.
Eingebaut in erzeuge_glossar_04.py als {=html}-Rohblock (nur HTML,
im PDF bedeutungslos).
Abkürzungen beim ersten Mal ausschreiben: 'VaR' → 'VaR (Value at Risk)',
'EVPI' → 'EVPI (Expected Value of Perfect Information)' als Link-Text
bei der ersten Nennung je Datei; danach nur die Abkürzung. 19 Abkürzungen
erfasst (VaR, CVaR, KKT, NLP, MILP, EVPI, LP, QP, ...).
CLAUDE.md: Regel 'Glossar-Links: Fachbegriffe im Fließtext automatisch
verlinkt' dokumentiert — resolve_glossar(), LINK_TEXTE,
ABBREV_ERSTE_NENNUNG, _NICHT_AUTO_LINKEN, _ZU_KURZ_ABK, .glossar-link,
{gl:}-Marke, Sprungleiste, {#gloss:<slug>}-Anchor.
This commit is contained in:
parent
e8abb66d75
commit
0e2c011732
47 changed files with 545 additions and 561 deletions
21
CLAUDE.md
21
CLAUDE.md
|
|
@ -113,7 +113,7 @@ bewacht jede Familie. Konkret:
|
|||
einer bereits nummerierten Überschrift. Verwiesen wird auf
|
||||
`{ref:sec:<kapitel>-denkfehler}`.
|
||||
* Im Fließtext `{ref:<label>}`, nie eine Literalzahl.
|
||||
* **Das Glossar (Anhang E) wird erzeugt.** Die 234 Einträge stehen in
|
||||
* **Das Glossar (Anhang E) wird erzeugt.** Die 239 Einträge stehen in
|
||||
`glossar_eintraege_04.py` als Viertupel *(Anzeigename, Indexmarke, Definition,
|
||||
Verweisziel)*; `erzeuge_glossar_04.py` schreibt daraus `94_Anhang_Glossar.md`. Die `.md`
|
||||
**nicht** von Hand bearbeiten — `--check` bemerkt es und nennt die Quelle. Der Erzeuger
|
||||
|
|
@ -122,6 +122,25 @@ bewacht jede Familie. Konkret:
|
|||
existieren, und kein Verweis darf auf das Glossar selbst zeigen. Begriffe, die es nur im
|
||||
Glossar gibt, stehen ausdrücklich in `NUR_IM_GLOSSAR` — sonst ließe sich ein solcher Fall
|
||||
nicht von einem Tippfehler unterscheiden.
|
||||
* **Glossar-Links: Fachbegriffe im Fließtext werden automatisch verlinkt.**
|
||||
`resolve_glossar()` in `build_version_04.py` sucht beim Bau jeden Fließtext nach
|
||||
Glossar-Begriffen ab und ersetzt die **erste Nennung je Begriff je Datei** durch einen
|
||||
Link auf den Glossar-Eintrag (`#gloss:<slug>` im Gesamtdokument,
|
||||
`anhang-glossar.md#gloss:<slug>` in den Einzelseiten). Die `.md`-Quelldateien enthalten
|
||||
**keine** manuellen Link-Marken — der Build macht es automatisch, sodass Textänderungen
|
||||
nichts nachziehen. Ausgenommen vom Auto-Linking: Code-Blöcke, Inline-Code, Marken
|
||||
(`{idx:}`, `{ref:}`), Markdown-Links und Überschriften. Die Slug-Map `LINK_TEXTE` und
|
||||
die Erste-Nennung-Map `ABBREV_ERSTE_NENNUNG` werden in `glossar_eintraege_04.py`
|
||||
automatisch aus `EINTRAEGE` generiert. **Abkürzungen** (`VaR`, `CVaR`, `KKT` …) werden
|
||||
beim ersten Vorkommen ausgeschrieben: „VaR (Value at Risk)“ als Link-Text, danach nur
|
||||
„VaR“. **Mehrdeutige** Begriffe („Lösung“, „Matrix“, „Variable“ …), die im Glossar
|
||||
stehen aber nicht jedes Vorkommen verlinkt werden soll, stehen in `_NICHT_AUTO_LINKEN`;
|
||||
wer sie an einer Stelle trotzdem verlinken will, setzt `{gl:Begriff}`. **Zu kurze**
|
||||
Abkürzungen (`OR` — taucht als Teilstring in `OR-Tools` auf) stehen in `_ZU_KURZ_ABK`
|
||||
und werden nur mit `{gl:OR}` verlinkt. Die CSS-Klasse `.glossar-link` (dezente
|
||||
gestrichelte Unterstreichung, nicht blau) steht in `web_04/assets/site.css`.
|
||||
`erzeuge_glossar_04.py` gibt jedem Eintrag einen `{#gloss:<slug>}`-Anchor und eine
|
||||
alphabetische **Sprungleiste** (A B C …) wie das Stichwortverzeichnis.
|
||||
* **Der Titeltext steht in `Operations_Research_mit_Python_Version_04/NEUER_TITEL.md`** und
|
||||
nirgends sonst. `titeltexte_04.py` liest ihn; die PDF-Titelseite
|
||||
(`bilder_04/erzeuge_titelseite.py`) und der Hero-Block der Startseite
|
||||
|
|
|
|||
BIN
OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf
generated
BIN
OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf
generated
Binary file not shown.
10
OR_HTML_04/anhang-fehlerdiagnose.html
generated
10
OR_HTML_04/anhang-fehlerdiagnose.html
generated
|
|
@ -197,7 +197,7 @@
|
|||
<blockquote>
|
||||
<p>Nimm eine Bedingung versuchsweise heraus. Bleibt der Rest unlösbar, wurde sie nicht gebraucht: weg damit, endgültig. Wird der Rest lösbar, war sie beteiligt: sie bleibt.</p>
|
||||
</blockquote>
|
||||
<p>Nach genau einem Durchlauf über alle <span class="math inline">n</span> Bedingungen ist die übrig gebliebene Menge <strong>unreduzierbar</strong> — entfernt man aus ihr irgendeine Bedingung, ist der Rest lösbar. Das ist ein <em>Irreducible Infeasible Subset</em>, kurz <a href="anhang-glossar.md#gloss:iis-irreducible-infeasible-subset" class="glossar-link">IIS</a>. Kommerzielle Solver bieten das als fertige Funktion an (<code>computeIIS</code> bei <a href="anhang-glossar.md#gloss:gurobi" class="glossar-link">Gurobi</a>, der Conflict Refiner bei CPLEX); im Open-Source-Werkzeugkasten dieses Buchs gibt es sie nicht — sie ist aber in zwanzig Zeilen selbst geschrieben, und sie kostet <span class="math inline">n</span> Aufrufe des Solvers statt <span class="math inline">2^n</span> durchprobierter Teilmengen.</p>
|
||||
<p>Nach genau einem Durchlauf über alle <span class="math inline">n</span> Bedingungen ist die übrig gebliebene Menge <strong>unreduzierbar</strong> — entfernt man aus ihr irgendeine Bedingung, ist der Rest lösbar. Das ist ein <em>Irreducible Infeasible Subset</em>, kurz <a href="anhang-glossar.md#gloss:iis-irreducible-infeasible-subset" class="glossar-link">IIS (Irreducible Infeasible Subset)</a>. Kommerzielle Solver bieten das als fertige Funktion an (<code>computeIIS</code> bei <a href="anhang-glossar.md#gloss:gurobi" class="glossar-link">Gurobi</a>, der Conflict Refiner bei CPLEX); im Open-Source-Werkzeugkasten dieses Buchs gibt es sie nicht — sie ist aber in zwanzig Zeilen selbst geschrieben, und sie kostet <span class="math inline">n</span> Aufrufe des Solvers statt <span class="math inline">2^n</span> durchprobierter Teilmengen.</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/usr/bin/env python3</span></span>
|
||||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="co"># Konfliktsuche.py</span></span>
|
||||
|
|
@ -567,9 +567,9 @@ Insgesamt 2874 Solveraufrufe fuer die gesamte Diagnose.
|
|||
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>loesen()<span class="op">;</span> t2 <span class="op">=</span> time.perf_counter()</span>
|
||||
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="ss">f"Aufbau </span><span class="sc">{</span>t1<span class="op">-</span>t0<span class="sc">:.2f}</span><span class="ss">s | Loesen </span><span class="sc">{</span>t2<span class="op">-</span>t1<span class="sc">:.2f}</span><span class="ss">s"</span>)</span></code></pre></div>
|
||||
<p>Bei CVXPY und bei Schleifen über Szenarien ist oft der <strong>Aufbau</strong> der Engpass, nicht der Solver (siehe <a href="cvar.html#sec:cvar-implementierung-cvar-portfolio-mit-reibung">Abschnitt 20.6</a>).</p>
|
||||
<p><strong>2. Big-M zu groß?</strong> Der häufigste Grund für explodierende <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a>-Laufzeiten. Setzen Sie <span class="math inline">M</span> auf die kleinste gültige Schranke (<a href="milp.html#sec:milp-modellierungstricks-big-m-und-logische-bedingungen">Abschnitt 6.5</a>).</p>
|
||||
<p><strong>2. Big-M zu groß?</strong> Der häufigste Grund für explodierende <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a>-Laufzeiten. Setzen Sie <span class="math inline">M</span> auf die kleinste gültige Schranke (<a href="milp.html#sec:milp-modellierungstricks-big-m-und-logische-bedingungen">Abschnitt 6.5</a>).</p>
|
||||
<p><strong>3. Symmetrie im Modell?</strong> Identische Maschinen, austauschbare Mitarbeitende, gleichwertige Fahrzeuge — der Solver durchsucht alle Vertauschungen. Abhilfe: Ordnungsbedingungen (Muster B20).</p>
|
||||
<p><strong>4. Falsche Solverfamilie?</strong> Zuordnungsprobleme mit MILP, Routing mit <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> von Hand nachgebaut, konvexe Probleme mit <code>scipy.optimize.minimize</code> — jeweils Größenordnungen langsamer als das passende Werkzeug (<a href="oekosystem.html#sec:oekosystem-wann-lohnt-sich-welche-ebene">Abschnitt 3.6</a>).</p>
|
||||
<p><strong>4. Falsche Solverfamilie?</strong> Zuordnungsprobleme mit MILP, Routing mit <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> von Hand nachgebaut, konvexe Probleme mit <code>scipy.optimize.minimize</code> — jeweils Größenordnungen langsamer als das passende Werkzeug (<a href="oekosystem.html#sec:oekosystem-wann-lohnt-sich-welche-ebene">Abschnitt 3.6</a>).</p>
|
||||
<p><strong>5. Wird vektorisiert?</strong></p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co"># langsam: # schnell:</span></span>
|
||||
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> s <span class="kw">in</span> <span class="bu">range</span>(S): constraints.append(u <span class="op">>=</span> <span class="op">-</span>(R <span class="op">@</span> w) <span class="op">-</span> gamma)</span>
|
||||
|
|
@ -694,7 +694,7 @@ Insgesamt 2874 Solveraufrufe fuer die gesamte Diagnose.
|
|||
<tr class="odd">
|
||||
<td><code>x * y</code> (beide Variablen)</td>
|
||||
<td>bilinear</td>
|
||||
<td>umformulieren oder MILP/<a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP</a></td>
|
||||
<td>umformulieren oder MILP/<a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP (Nichtlineare Programmierung)</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><code>a / x</code></td>
|
||||
|
|
@ -703,7 +703,7 @@ Insgesamt 2874 Solveraufrufe fuer die gesamte Diagnose.
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td><code>cp.sqrt(cp.quad_form(w, S))</code></td>
|
||||
<td><code>cp.sqrt</code> ist <strong>konkav</strong> und verlangt ein konkaves Argument — <code>quad_form</code> ist konvex. Der Ausdruck ist nie <a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP</a>, egal wie sauber <span class="math inline">S</span> ist</td>
|
||||
<td><code>cp.sqrt</code> ist <strong>konkav</strong> und verlangt ein konkaves Argument — <code>quad_form</code> ist konvex. Der Ausdruck ist nie <a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP (Disciplined Convex Programming)</a>, egal wie sauber <span class="math inline">S</span> ist</td>
|
||||
<td>Cholesky <span class="math inline">S = LL^\top</span>, dann <code>cp.norm2(L.T @ w)</code>: die 2-Norm eines <strong>affinen</strong> Ausdrucks (siehe <code>CVaR_Portfolio.py</code>)</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
|
|||
1
OR_HTML_04/anhang-glossar.html
generated
1
OR_HTML_04/anhang-glossar.html
generated
|
|
@ -101,6 +101,7 @@
|
|||
<article>
|
||||
<h1 id="anhang-glossar">Anhang E: Glossar</h1>
|
||||
<p>Nachschlagewerk zu allen Fachbegriffen, Abkürzungen, Algorithmen und Bibliotheken dieses Buchs. Jeder Eintrag nennt am Ende den Abschnitt, in dem der Begriff eingeführt wird — ein Klick dorthin führt in der Online-Fassung direkt zur Erklärung im Zusammenhang. Wer einen Begriff an <em>allen</em> Fundstellen sucht, benutzt das Stichwortverzeichnis.</p>
|
||||
<nav class="register-sprungleiste"><a href="#a">A</a> <a href="#b">B</a> <a href="#c">C</a> <a href="#d">D</a> <a href="#e">E</a> <a href="#f">F</a> <a href="#g">G</a> <a href="#h">H</a> <a href="#i">I</a> <a href="#j">J</a> <a href="#k">K</a> <a href="#l">L</a> <a href="#m">M</a> <a href="#n">N</a> <a href="#o">O</a> <a href="#p">P</a> <a href="#q">Q</a> <a href="#r">R</a> <a href="#s">S</a> <a href="#t">T</a> <a href="#u">U</a> <a href="#v">V</a> <a href="#w">W</a> <a href="#y">Y</a> <a href="#z">Z</a></nav>
|
||||
<h2 id="a">A</h2>
|
||||
<div id="gloss:absolutbetrag">
|
||||
<p><strong>Absolutbetrag</strong> — Modellierungsmuster für <span class="math inline">|x-z|</span>: Der Betrag selbst ist nicht linear, lässt sich aber durch eine Hilfsvariable <span class="math inline">d</span> mit den beiden Bedingungen <span class="math inline">x-z \le d</span> und <span class="math inline">z-x \le d</span> ersetzen. Das funktioniert nur, wenn <span class="math inline">d</span> minimiert wird — sonst bleibt die Schranke unausgeschöpft. → <a href="anhang-modellierungsmuster.html#anhang-modellierungsmuster">Anhang B</a></p>
|
||||
|
|
|
|||
18
OR_HTML_04/anhang-literatur.html
generated
18
OR_HTML_04/anhang-literatur.html
generated
|
|
@ -132,14 +132,14 @@
|
|||
<li>★★★ <strong>Wolsey, L. A. (2020):</strong> <em>Integer Programming</em> (2. Aufl.). Wiley, Hoboken. DOI: 10.1002/9781119606475 [Ganzzahlige Optimierung] <em><a href="anhang-glossar.md#gloss:branch-and-bound" class="glossar-link">Branch-and-Bound</a>, <a href="anhang-glossar.md#gloss:branch-and-cut" class="glossar-link">Branch-and-Cut</a>, Polyedertheorie, Formulierungsstärke. Die Begründung dafür, warum ein kleines <span class="math inline">M</span> besser ist als ein großes.</em></li>
|
||||
<li>★★★ <strong>Conforti, M., Cornuéjols, G. & Zambelli, G. (2014):</strong> <em>Integer Programming.</em> Springer, Cham. DOI: 10.1007/978-3-319-11008-0 [Ganzzahlige Optimierung] <em>Modernere Darstellung als Wolsey, mit ausführlicher Behandlung von Schnittebenen und totaler Unimodularität.</em></li>
|
||||
<li>★★ <strong>Klotz, E. & Newman, A. M. (2013):</strong> <em>Practical guidelines for solving difficult mixed integer linear programs.</em> In: <em>Surveys in Operations Research and Management Science</em> 18(1–2), S. 18–32. DOI: 10.1016/j.sorms.2012.12.001 [Ganzzahlige Optimierung] <em>Was zu tun ist, wenn ein Modell nicht fertig rechnet — Skalierung, Formulierung, Symmetrie. Die Literaturgrundlage von <a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a>.</em></li>
|
||||
<li>★★ <strong>Achterberg, T. (2009):</strong> <em><a href="anhang-glossar.md#gloss:scip" class="glossar-link">SCIP</a>: solving constraint integer programs.</em> In: <em>Mathematical Programming Computation</em> 1(1), S. 1–41. DOI: 10.1007/s12532-008-0001-1 [<a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a>: SCIP] <em>Beschreibt die Verbindung von <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> und Constraint Programming in einem Solver.</em></li>
|
||||
<li>★★ <strong>Achterberg, T. (2009):</strong> <em><a href="anhang-glossar.md#gloss:scip" class="glossar-link">SCIP</a>: solving constraint integer programs.</em> In: <em>Mathematical Programming Computation</em> 1(1), S. 1–41. DOI: 10.1007/s12532-008-0001-1 [<a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a>: SCIP] <em>Beschreibt die Verbindung von <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> und Constraint Programming in einem Solver.</em></li>
|
||||
</ul>
|
||||
<h2 id="moderne-solver-implementierung-vergleich-und-benchmarks">Moderne Solver: Implementierung, Vergleich und Benchmarks</h2>
|
||||
<p><em>Zu <a href="oekosystem.html#kap-oekosystem">Kapitel 3</a> und <a href="anhang-spickzettel.html#anhang-spickzettel">Anhang D</a>. Neuer Abschnitt: Das Buch vergleicht durchgehend Solver, die Literatur dazu stand bisher verstreut.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Huangfu, Q. & Hall, J. A. J. (2018):</strong> <em>Parallelizing the dual revised simplex method.</em> In: <em>Mathematical Programming Computation</em> 10(1), S. 119–142. DOI: 10.1007/s12532-017-0130-5 [Solver: <a href="anhang-glossar.md#gloss:highs" class="glossar-link">HiGHS</a>] <em>Die vom HiGHS-Projekt selbst benannte Zitierquelle. HiGHS ist das Backend von <code>scipy.optimize.linprog</code> und CVXPY. <a href="https://highs.dev">highs.dev</a></em></li>
|
||||
<li>★★★ <strong>Gleixner, A., Hendel, G., Gamrath, G. et al. (2021):</strong> <em>MIPLIB 2017: data-driven compilation of the 6th mixed-integer programming library.</em> In: <em>Mathematical Programming Computation</em> 13(3), S. 443–490. DOI: 10.1007/s12532-020-00194-3 [Benchmarks] <em>Die Testmenge, auf der praktisch jeder Solververgleich beruht: 1065 Instanzen, davon 240 als Benchmark-Teilmenge. Frei zugänglich; Daten unter <a href="https://miplib.zib.de">miplib.zib.de</a>.</em></li>
|
||||
<li>★★★ <strong>Mittelmann, H. D.:</strong> <em>Benchmarks for Optimization Software.</em> Arizona State University. <a href="https://plato.asu.edu/bench.html">plato.asu.edu/bench.html</a> [Benchmarks] <em>Die laufend aktualisierte Referenzmessung für <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>-, MILP- und <a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a>-Solver. <strong>Wichtige Einschränkung:</strong> Seit 2024 sind die kommerziellen Solver auf eigenen Wunsch nicht mehr enthalten; ein direkter Vergleich <a href="anhang-glossar.md#gloss:gurobi" class="glossar-link">Gurobi</a> gegen HiGHS ist dort nicht mehr möglich.</em></li>
|
||||
<li>★★★ <strong>Mittelmann, H. D.:</strong> <em>Benchmarks for Optimization Software.</em> Arizona State University. <a href="https://plato.asu.edu/bench.html">plato.asu.edu/bench.html</a> [Benchmarks] <em>Die laufend aktualisierte Referenzmessung für <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>-, MILP- und <a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a>-Solver. <strong>Wichtige Einschränkung:</strong> Seit 2024 sind die kommerziellen Solver auf eigenen Wunsch nicht mehr enthalten; ein direkter Vergleich <a href="anhang-glossar.md#gloss:gurobi" class="glossar-link">Gurobi</a> gegen HiGHS ist dort nicht mehr möglich.</em></li>
|
||||
<li>★★ <strong>Bolusani, S., Besançon, M., Bestuzheva, K. et al. (2024):</strong> <em>The SCIP Optimization Suite 9.0.</em> Technischer Bericht, Zuse-Institut Berlin. arXiv:2402.17702 [Solver: SCIP] <em>Beschreibt Aufbau und Komponenten der Suite. Die Reihe wird fortgeschrieben — die jeweils aktuelle Fassung steht unter <a href="https://www.scipopt.org">scipopt.org</a>; beim Zitieren die tatsächlich benutzte Version angeben.</em></li>
|
||||
<li>★★ <strong>Perron, L. & Furnon, V.:</strong> <em><a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a>.</em> Google. <a href="https://developers.google.com/optimization">developers.google.com/optimization</a> · Quellcode: <a href="https://github.com/google/or-tools">github.com/google/or-tools</a> [Solver: OR-Tools] <em>Die Sammlung, aus der das Buch <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> und die <a href="anhang-glossar.md#gloss:routing-bibliothek" class="glossar-link">Routing-Bibliothek</a> benutzt.</em></li>
|
||||
</ul>
|
||||
|
|
@ -147,7 +147,7 @@
|
|||
<p><em>Zu <a href="cpsat.html#kap-cpsat">Kapitel 7</a>.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Rossi, F., van Beek, P. & Walsh, T. (Hrsg., 2006):</strong> <em>Handbook of Constraint Programming.</em> Foundations of Artificial Intelligence, Bd. 2. Elsevier, Amsterdam. [Constraint Programming] <em>Nach wie vor das Referenzwerk zu Propagation, globalen Constraints und Suchstrategien.</em></li>
|
||||
<li>★★★ <strong>Perron, L. & Furnon, V.:</strong> <em>OR-Tools <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> Solver Documentation.</em> Google. <a href="https://developers.google.com/optimization/cp">developers.google.com/optimization/cp</a> [Solver: CP-SAT] <em>Die einzige vollständige Beschreibung des im Buch benutzten Solvers. Der Abschnitt zu <code>AddNoOverlap</code> und <code>AddCumulative</code> deckt sich mit <a href="cpsat.html#kap-cpsat">Kapitel 7</a>.</em></li>
|
||||
<li>★★★ <strong>Perron, L. & Furnon, V.:</strong> <em>OR-Tools <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> Solver Documentation.</em> Google. <a href="https://developers.google.com/optimization/cp">developers.google.com/optimization/cp</a> [Solver: CP-SAT] <em>Die einzige vollständige Beschreibung des im Buch benutzten Solvers. Der Abschnitt zu <code>AddNoOverlap</code> und <code>AddCumulative</code> deckt sich mit <a href="cpsat.html#kap-cpsat">Kapitel 7</a>.</em></li>
|
||||
<li>★★ <strong>Laborie, P., Rogerie, J., Shaw, P. & Vilím, P. (2018):</strong> <em>IBM ILOG CP Optimizer for scheduling.</em> In: <em>Constraints</em> 23(2), S. 210–250. DOI: 10.1007/s10601-018-9281-x [<a href="anhang-glossar.md#gloss:scheduling" class="glossar-link">Scheduling</a>] <em>Intervallvariablen und Ressourcenprofile aus Sicht des konkurrierenden Solvers — lehrreich für das Verständnis der Modellierungsprimitive.</em></li>
|
||||
<li>★★ <strong>Biere, A., Heule, M., van Maaren, H. & Walsh, T. (Hrsg., 2021):</strong> <em>Handbook of Satisfiability</em> (2. Aufl.). Frontiers in Artificial Intelligence and Applications, Bd. 336. IOS Press, Amsterdam. DOI: 10.3233/FAIA336 [SAT] <em>Die Grundlage dessen, was CP-SAT unter der Haube tut: Conflict-Driven Clause Learning, Klausellernen, Neustarts.</em></li>
|
||||
</ul>
|
||||
|
|
@ -155,14 +155,14 @@
|
|||
<p><em>Zu <a href="graphen.html#kap-graphen">Kapitel 8</a>. Neuer Abschnitt.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Ahuja, R. K., Magnanti, T. L. & Orlin, J. B. (1993):</strong> <em>Network Flows: Theory, Algorithms, and Applications.</em> Prentice Hall, Englewood Cliffs. [Netzwerkflüsse] <em>Das Standardwerk zu Min-Cost-Flow, Matching und totaler Unimodularität — der Grund, warum diese Modelle schon als LP ganzzahlig lösen.</em></li>
|
||||
<li>★★★ <strong>Toth, P. & Vigo, D. (Hrsg., 2014):</strong> <em>Vehicle Routing: Problems, Methods, and Applications</em> (2. Aufl.). SIAM, Philadelphia. DOI: 10.1137/1.9781611973594 [<a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP</a>] <em>Das Referenzwerk zur Tourenplanung, einschließlich Kapazitäten, Zeitfenstern und <a href="anhang-glossar.md#gloss:subtour" class="glossar-link">Subtour</a>-Eliminierung.</em></li>
|
||||
<li>★★★ <strong>Toth, P. & Vigo, D. (Hrsg., 2014):</strong> <em>Vehicle Routing: Problems, Methods, and Applications</em> (2. Aufl.). SIAM, Philadelphia. DOI: 10.1137/1.9781611973594 [<a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP (Vehicle Routing Problem)</a>] <em>Das Referenzwerk zur Tourenplanung, einschließlich Kapazitäten, Zeitfenstern und <a href="anhang-glossar.md#gloss:subtour" class="glossar-link">Subtour</a>-Eliminierung.</em></li>
|
||||
<li>★★ <strong>Vidal, T., Laporte, G. & Matl, P. (2020):</strong> <em>A concise guide to existing and emerging vehicle routing problem variants.</em> In: <em>European Journal of Operational Research</em> 286(2), S. 401–416. DOI: 10.1016/j.ejor.2019.10.010 [VRP] <em>Übersicht über die Variantenvielfalt — hilfreich, um die eigene Aufgabe einzuordnen, bevor man modelliert. Frei zugänglich als arXiv:1906.06750.</em></li>
|
||||
<li>★ <strong>Kuhn, H. W. (1955):</strong> <em>The Hungarian method for the assignment problem.</em> In: <em>Naval Research Logistics Quarterly</em> 2(1–2), S. 83–97. DOI: 10.1002/nav.3800020109 [<a href="anhang-glossar.md#gloss:zuordnungsproblem" class="glossar-link">Zuordnungsproblem</a>] <em>Das Originalverfahren hinter <code>scipy.optimize.linear_sum_assignment</code>.</em></li>
|
||||
</ul>
|
||||
<h2 id="metaheuristiken">Metaheuristiken</h2>
|
||||
<p><em>Zu <a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a>. Neuer Abschnitt.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Gendreau, M. & Potvin, J.-Y. (Hrsg., 2019):</strong> <em>Handbook of Metaheuristics</em> (3. Aufl.). Springer, Cham. DOI: 10.1007/978-3-319-91086-4 <a href="#metaheuristiken">Metaheuristiken</a> <em>Sammelband zu <a href="anhang-glossar.md#gloss:tabu-suche" class="glossar-link">Tabu-Suche</a>, <a href="anhang-glossar.md#gloss:simulated-annealing" class="glossar-link">Simulated Annealing</a>, <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS</a>, genetischen Verfahren — jeweils von den Urhebern geschrieben.</em></li>
|
||||
<li>★★★ <strong>Gendreau, M. & Potvin, J.-Y. (Hrsg., 2019):</strong> <em>Handbook of Metaheuristics</em> (3. Aufl.). Springer, Cham. DOI: 10.1007/978-3-319-91086-4 <a href="#metaheuristiken">Metaheuristiken</a> <em>Sammelband zu <a href="anhang-glossar.md#gloss:tabu-suche" class="glossar-link">Tabu-Suche</a>, <a href="anhang-glossar.md#gloss:simulated-annealing" class="glossar-link">Simulated Annealing</a>, <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS (Large Neighborhood Search)</a>, genetischen Verfahren — jeweils von den Urhebern geschrieben.</em></li>
|
||||
<li>★★★ <strong>Pisinger, D. & Ropke, S. (2010):</strong> <em>Large Neighborhood Search.</em> In: Gendreau, M. & Potvin, J.-Y. (Hrsg.): <em>Handbook of Metaheuristics</em>, S. 399–419. Springer. DOI: 10.1007/978-1-4419-1665-5_13 <a href="#metaheuristiken">Metaheuristiken</a> <em>Die Darstellung des Verfahrens, das im Buch die exakte Suche auf Teilproblemen mit heuristischem Zerstören verbindet.</em></li>
|
||||
<li>★★ <strong>Kirkpatrick, S., Gelatt, C. D. & Vecchi, M. P. (1983):</strong> <em>Optimization by Simulated Annealing.</em> In: <em>Science</em> 220(4598), S. 671–680. DOI: 10.1126/science.220.4598.671 <a href="#metaheuristiken">Metaheuristiken</a> <em>Die Originalarbeit; die Abkühlungsanalogie stammt von hier.</em></li>
|
||||
<li>★★ <strong>Sörensen, K. (2015):</strong> <em>Metaheuristics — the metaphor exposed.</em> In: <em>International Transactions in Operational Research</em> 22(1), S. 3–18. DOI: 10.1111/itor.12001 <a href="#metaheuristiken">Metaheuristiken</a> <em>Kritik an der Flut naturanaloger „neuer” Verfahren. Vor der Auswahl einer <a href="anhang-glossar.md#gloss:metaheuristik" class="glossar-link">Metaheuristik</a> zu lesen — sie erspart viel Zeit.</em></li>
|
||||
|
|
@ -177,14 +177,14 @@
|
|||
<h2 id="konvexe-und-nichtlineare-optimierung">Konvexe und nichtlineare Optimierung</h2>
|
||||
<p><em>Zu <a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a>.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Boyd, S. & Vandenberghe, L. (2004):</strong> <em>Convex Optimization.</em> Cambridge University Press. DOI: 10.1017/CBO9780511804441 [Konvexe Optimierung] <em>Referenzwerk für konvexe Mengen, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a>-Bedingungen, QP und SDP; die theoretische Basis von CVXPY. Frei verfügbar unter <a href="https://web.stanford.edu/~boyd/cvxbook/">stanford.edu/~boyd/cvxbook</a>.</em></li>
|
||||
<li>★★★ <strong>Boyd, S. & Vandenberghe, L. (2004):</strong> <em>Convex Optimization.</em> Cambridge University Press. DOI: 10.1017/CBO9780511804441 [Konvexe Optimierung] <em>Referenzwerk für konvexe Mengen, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a>-Bedingungen, QP und SDP; die theoretische Basis von CVXPY. Frei verfügbar unter <a href="https://web.stanford.edu/~boyd/cvxbook/">stanford.edu/~boyd/cvxbook</a>.</em></li>
|
||||
<li>★★ <strong>Kraft, D. (1988):</strong> <em>A Software Package for Sequential Quadratic Programming.</em> DFVLR-FB 88-28, Deutsche Forschungs- und Versuchsanstalt für Luft- und Raumfahrt, Köln. [Nichtlineare Optimierung] <em>Die Originalarbeit zu <a href="anhang-glossar.md#gloss:slsqp" class="glossar-link">SLSQP</a> — dem Verfahren hinter <code>scipy.optimize.minimize</code>.</em></li>
|
||||
<li>★★ <strong>Lobo, M. S., Vandenberghe, L., Boyd, S. & Lebret, H. (1998):</strong> <em>Applications of second-order cone programming.</em> In: <em>Linear Algebra and its Applications</em> 284(1–3), S. 193–228. DOI: 10.1016/S0024-3795(98)10032-0 [<a href="anhang-glossar.md#gloss:konische-optimierung" class="glossar-link">Konische Optimierung</a>] <em>Warum sich Risikoschranken und Normbedingungen als SOCP schreiben lassen — die Grundlage der Chance-Constraints-Formulierung in <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a>.</em></li>
|
||||
</ul>
|
||||
<h2 id="optimierung-unter-unsicherheit-stochastisch-robust-chance-constraints">Optimierung unter Unsicherheit: stochastisch, robust, Chance Constraints</h2>
|
||||
<p><em>Zu <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a> und <a href="supplychain.html#kap-supplychain">Kapitel 17</a>. Aus dem früheren Block „Konvexe, nichtlineare und robuste Optimierung” herausgelöst und erweitert.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Birge, J. R. & Louveaux, F. (2011):</strong> <em>Introduction to Stochastic Programming</em> (2. Aufl.). Springer, New York. DOI: 10.1007/978-1-4614-0237-4 [Stochastische Optimierung] <em>Das Standardwerk zur zweistufigen Optimierung, Szenariobäumen und dem Wert perfekter Information (<a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI</a>).</em></li>
|
||||
<li>★★★ <strong>Birge, J. R. & Louveaux, F. (2011):</strong> <em>Introduction to Stochastic Programming</em> (2. Aufl.). Springer, New York. DOI: 10.1007/978-1-4614-0237-4 [Stochastische Optimierung] <em>Das Standardwerk zur zweistufigen Optimierung, Szenariobäumen und dem Wert perfekter Information (<a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI (Expected Value of Perfect Information)</a>).</em></li>
|
||||
<li>★★★ <strong>Ben-Tal, A., El Ghaoui, L. & Nemirovski, A. (2009):</strong> <em>Robust Optimization.</em> Princeton University Press. DOI: 10.1515/9781400831050 [<a href="anhang-glossar.md#gloss:robuste-optimierung" class="glossar-link">Robuste Optimierung</a>] <em>Die geschlossene Darstellung der robusten Gegenstücke und ihrer konischen Umformung.</em></li>
|
||||
<li>★★★ <strong>Bertsimas, D. & Sim, M. (2004):</strong> <em>The Price of Robustness.</em> In: <em>Operations Research</em> 52(1), S. 35–53. DOI: 10.1287/opre.1030.0065 [Robuste Optimierung] <em>Quelle des Budgeted-Uncertainty-Ansatzes: Der <a href="anhang-glossar.md#gloss:parameter" class="glossar-link">Parameter</a> <span class="math inline">\Gamma</span> regelt stufenlos, wie vorsichtig die Lösung wird.</em></li>
|
||||
<li>★★ <strong>Nemirovski, A. & Shapiro, A. (2007):</strong> <em>Convex Approximations of Chance Constrained Programs.</em> In: <em>SIAM Journal on Optimization</em> 17(4), S. 969–996. DOI: 10.1137/050622328 [Chance Constraints] <em>Zeigt, wann sich eine Wahrscheinlichkeitsbedingung konvex annähern lässt — und wann nicht.</em></li>
|
||||
|
|
@ -226,7 +226,7 @@
|
|||
<p><em>Zu <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a>, <a href="markowitz.html#kap-markowitz">Kapitel 19</a>, <a href="cvar.html#kap-cvar">Kapitel 20</a> und <a href="handelsmaschine.html#kap-handelsmaschine">Kapitel 21</a>.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Markowitz, H. (1952):</strong> <em>Portfolio Selection.</em> In: <em>The Journal of Finance</em> 7(1), S. 77–91. DOI: 10.2307/2975974 [Portfoliotheorie] <em>Die Arbeit, die das Zusammenspiel von Rendite und Kovarianz zum Optimierungsproblem gemacht hat.</em></li>
|
||||
<li>★★★ <strong>Rockafellar, R. T. & Uryasev, S. (2000):</strong> <em>Optimization of Conditional Value-at-Risk.</em> In: <em>Journal of Risk</em> 2(3), S. 21–41. DOI: 10.21314/JOR.2000.038 [Risikomaße] <em>Der Satz, der die <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a>-Minimierung in ein lineares Programm überführt.</em></li>
|
||||
<li>★★★ <strong>Rockafellar, R. T. & Uryasev, S. (2000):</strong> <em>Optimization of Conditional Value-at-Risk.</em> In: <em>Journal of Risk</em> 2(3), S. 21–41. DOI: 10.21314/JOR.2000.038 [Risikomaße] <em>Der Satz, der die <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a>-Minimierung in ein lineares Programm überführt.</em></li>
|
||||
<li>★★★ <strong>Ledoit, O. & Wolf, M. (2004):</strong> <em>A well-conditioned estimator for large-dimensional covariance matrices.</em> In: <em>Journal of Multivariate Analysis</em> 88(2), S. 365–411. DOI: 10.1016/S0047-259X(03)00096-4 [Kovarianzschätzung] <em>Quelle des von <code>scikit-learn</code> verwendeten Shrinkage-Ziels (skalierte Einheitsmatrix).</em></li>
|
||||
<li>★★★ <strong>Cornuéjols, G., Peña, J. & Tütüncü, R. (2018):</strong> <em>Optimization Methods in Finance</em> (2. Aufl.). Cambridge University Press. DOI: 10.1017/9781107297340 [Finanzoptimierung] <em>Die Brücke zwischen Optimierungstheorie und Finanzanwendung; deckt QP, SOCP und robuste Portfolios ab.</em></li>
|
||||
<li>★★★ <strong>Almgren, R. & Chriss, N. (2001):</strong> <em>Optimal Execution of Portfolio Transactions.</em> In: <em>Journal of Risk</em> 3(2), S. 5–39. DOI: 10.21314/jor.2001.041 [Orderausführung] <em>Das Modell hinter dem Beispiel zur optimalen Orderausführung in <a href="dynamische-programmierung.html#kap-dynamische-programmierung">Kapitel 13</a>.</em></li>
|
||||
|
|
@ -238,7 +238,7 @@
|
|||
<h2 id="praxis-betrieb-test-und-auslieferung-von-optimierungsmodellen">Praxis: Betrieb, Test und Auslieferung von Optimierungsmodellen</h2>
|
||||
<p><em>Zu <a href="praxisfallen.html#kap-praxisfallen">Kapitel 22</a> und <a href="testing.html#kap-testing">Kapitel 23</a>. Neuer Abschnitt.</em></p>
|
||||
<ul>
|
||||
<li>★★★ <strong>Chinneck, J. W. (2008):</strong> <em>Feasibility and <a href="anhang-glossar.md#gloss:infeasibility" class="glossar-link">Infeasibility</a> in Optimization: Algorithms and Computational Methods.</em> Springer, New York. DOI: 10.1007/978-0-387-74932-7 [Fehlerdiagnose] <em>Das Standardwerk zur Unlösbarkeitsdiagnose, einschließlich des Deletion Filters und der irreduziblen unlösbaren Teilmengen (<a href="anhang-glossar.md#gloss:iis-irreducible-infeasible-subset" class="glossar-link">IIS</a>). Direkte Grundlage von <a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a>.</em></li>
|
||||
<li>★★★ <strong>Chinneck, J. W. (2008):</strong> <em>Feasibility and <a href="anhang-glossar.md#gloss:infeasibility" class="glossar-link">Infeasibility</a> in Optimization: Algorithms and Computational Methods.</em> Springer, New York. DOI: 10.1007/978-0-387-74932-7 [Fehlerdiagnose] <em>Das Standardwerk zur Unlösbarkeitsdiagnose, einschließlich des Deletion Filters und der irreduziblen unlösbaren Teilmengen (<a href="anhang-glossar.md#gloss:iis-irreducible-infeasible-subset" class="glossar-link">IIS (Irreducible Infeasible Subset)</a>). Direkte Grundlage von <a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a>.</em></li>
|
||||
<li>★★ <strong>Sculley, D., Holt, G., Golovin, D. et al. (2015):</strong> <em>Hidden Technical Debt in Machine Learning Systems.</em> In: <em>Advances in Neural Information Processing Systems</em> 28, S. 2503–2511. [Betrieb] <em>Über Systeme, deren Modell nur ein kleiner Teil ist — überträgt sich unmittelbar auf den Betrieb von Optimierungsdiensten. Frei zugänglich.</em></li>
|
||||
<li>★★ <strong>Kleppmann, M. (2017):</strong> <em>Designing Data-Intensive Applications.</em> O’Reilly, Sebastopol. [Betrieb] <em><a href="anhang-glossar.md#gloss:snapshot-prinzip" class="glossar-link">Snapshot-Prinzip</a>, <a href="anhang-glossar.md#gloss:zustandslosigkeit" class="glossar-link">Zustandslosigkeit</a>, Versionierung und Reproduzierbarkeit — die Architekturfragen hinter der OR-Plattform in <a href="praxisfallen.html#kap-praxisfallen">Kapitel 22</a>.</em></li>
|
||||
<li>★★ <strong>Ramírez, S.:</strong> <em>FastAPI Documentation.</em> <a href="https://fastapi.tiangolo.com">fastapi.tiangolo.com</a> [Betrieb] <em>Die Grundlage des Optimierungsdienstes in <a href="testing.html#kap-testing">Kapitel 23</a>, einschließlich der Eingabevalidierung über <code>pydantic</code>.</em></li>
|
||||
|
|
|
|||
24
OR_HTML_04/anhang-loesungen.html
generated
24
OR_HTML_04/anhang-loesungen.html
generated
|
|
@ -169,7 +169,7 @@
|
|||
<p>Für <span class="math inline">\mathbf{P}_2</span> ergibt sich eine PSD-Matrix mit Korrelation exakt <span class="math inline">1{,}0</span> — das Verfahren zieht die unmögliche Korrelation auf den nächstgelegenen zulässigen Wert. Für Kovarianzmatrizen setzt man in der Praxis auf einen kleinen positiven Wert statt auf 0 (<code>np.maximum(lam, 1e-10)</code>), damit die Matrix invertierbar bleibt.</p>
|
||||
<h3 id="finde-den-denkfehler-die-unauffällige-transposition">Finde den Denkfehler — Die unauffällige Transposition</h3>
|
||||
<ol type="a">
|
||||
<li><p><strong>Warum nichts auffällt.</strong> <span class="math inline">\mathbf{A}</span> ist quadratisch, also passen die Dimensionen auch transponiert. <a href="anhang-glossar.md#gloss:numpy" class="glossar-link">NumPy</a> prüft Formen, nicht Bedeutungen; der Solver bekommt ein vollkommen zulässiges <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> vorgelegt und löst es korrekt — nur eben ein <strong>anderes</strong>. Eine Transposition ist genau dann gefährlich, wenn sie folgenlos <em>aussieht</em>: Wäre die Matrix <span class="math inline">2 \times 3</span> gewesen, hätte NumPy sofort einen Dimensionsfehler geworfen.</p></li>
|
||||
<li><p><strong>Warum nichts auffällt.</strong> <span class="math inline">\mathbf{A}</span> ist quadratisch, also passen die Dimensionen auch transponiert. <a href="anhang-glossar.md#gloss:numpy" class="glossar-link">NumPy</a> prüft Formen, nicht Bedeutungen; der Solver bekommt ein vollkommen zulässiges <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> vorgelegt und löst es korrekt — nur eben ein <strong>anderes</strong>. Eine Transposition ist genau dann gefährlich, wenn sie folgenlos <em>aussieht</em>: Wäre die Matrix <span class="math inline">2 \times 3</span> gewesen, hätte NumPy sofort einen Dimensionsfehler geworfen.</p></li>
|
||||
<li><p><strong>Der Plan an den echten Restriktionen.</strong> Mit <span class="math inline">\mathbf{A} = \begin{pmatrix} 1 & 2 \\ 3 & 1\end{pmatrix}</span> und <span class="math inline">\mathbf{x} = (5{,}6;\ 0{,}8)</span>:</p></li>
|
||||
</ol>
|
||||
<p><span class="math display">\mathbf{A}\mathbf{x} = \begin{pmatrix} 1\cdot5{,}6 + 2\cdot0{,}8 \\ 3\cdot5{,}6 + 1\cdot0{,}8\end{pmatrix} = \begin{pmatrix} 7{,}2 \\ 17{,}6 \end{pmatrix} \quad\text{gegen}\quad \mathbf{b} = \begin{pmatrix} 8 \\ 12\end{pmatrix}</span></p>
|
||||
|
|
@ -196,7 +196,7 @@
|
|||
</ol>
|
||||
<hr />
|
||||
<h2 id="sec:loesungen-oekosystem">A.3 Lösungen zu Kapitel „Das Python-Ökosystem für OR — Solver, Bindings und Modellierungsschichten“</h2>
|
||||
<p><strong>3.1 — Solverwahl.</strong> (a) <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> (diskrete Zuordnung mit Zeitfenstern). (b) <code>scipy.optimize.linprog</code> (klassisches Mischungs-LP, klein). (c) <a href="anhang-glossar.md#gloss:cvxpy" class="glossar-link">CVXPY</a> (konvexes <a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a>). (d) <a href="anhang-glossar.md#gloss:miqp" class="glossar-link">MIQP</a> — CVXPY mit Binärvariablen und MIQP-fähigem Solver, oder Heuristik. (e) <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> über <code>highspy</code> oder <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> (Standortproblem mit Fixkosten). (f) <code>scipy.optimize.minimize</code> mit Multistart (nicht konvex).</p>
|
||||
<p><strong>3.1 — Solverwahl.</strong> (a) <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> (diskrete Zuordnung mit Zeitfenstern). (b) <code>scipy.optimize.linprog</code> (klassisches Mischungs-LP, klein). (c) <a href="anhang-glossar.md#gloss:cvxpy" class="glossar-link">CVXPY</a> (konvexes <a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a>). (d) <a href="anhang-glossar.md#gloss:miqp" class="glossar-link">MIQP</a> — CVXPY mit Binärvariablen und MIQP-fähigem Solver, oder Heuristik. (e) <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> über <code>highspy</code> oder <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> (Standortproblem mit Fixkosten). (f) <code>scipy.optimize.minimize</code> mit Multistart (nicht konvex).</p>
|
||||
<p><strong>3.2 — Bäckerei viermal.</strong> Alle vier müssen <span class="math inline">Z = 448</span> (ganzzahlig) bzw. <span class="math inline">450</span> (kontinuierlich) liefern. Denken Sie an die Prozesstrennung, falls <code>ortools</code> und <code>highspy</code> kollidieren.</p>
|
||||
<p><strong>3.3 — <a href="anhang-glossar.md#gloss:csr-format" class="glossar-link">CSR-Format</a>.</strong> <code>values = [3, 1, 2, 5, 4, 6]</code>, <code>indices = [0, 3, 2, 0, 1, 3]</code>, <code>starts = [0, 2, 3]</code>. CSR speichert 6 Werte + 6 Indizes + 3 Startpositionen = 15 Zahlen; die volle Matrix hätte <span class="math inline">3\times4 = 12</span>. <strong>Bei dieser winzigen, dicht besetzten Matrix lohnt CSR nicht</strong> — der Vorteil entsteht erst bei großer, dünn besetzter Struktur (z. B. 1000×1000 mit 0,5 % Besetzung: 15 000 statt 1 000 000 Zahlen).</p>
|
||||
<p><strong>3.4 — Konvexitätsprüfung.</strong> <span class="math inline">\min x^3</span> wirft <code>DCPError: Problem does not follow DCP rules</code>, weil <span class="math inline">x^3</span> auf <span class="math inline">[-2,2]</span> weder konvex noch konkav ist. <span class="math inline">\min x^2</span> läuft und liefert <span class="math inline">x=0</span>. Der Unterschied: CVXPY akzeptiert nur Ausdrücke, deren Konvexität es <strong>beweisen</strong> kann — dafür garantiert es das globale Optimum.</p>
|
||||
|
|
@ -644,8 +644,8 @@
|
|||
<p>Beachten Sie, dass Werk 3 seine günstigste Verbindung (L4 zu 5) voll ausschöpft und W2 ausschließlich L1 beliefert (9), obwohl L4 mit 7 billiger wäre — dort ist der Bedarf bereits von W3 gedeckt. (c) Die Lösung ist ganzzahlig, obwohl nicht gefordert — die Transportmatrix ist <strong>total unimodular</strong>, alle Ecken sind ganzzahlig.</p>
|
||||
<p><strong>8.4 — Zuordnung mit Verboten.</strong> Kosten auf einen sehr hohen Wert setzen (<code>kosten[2][2] = 1e6</code>) oder mit <code>np.inf</code> arbeiten (bei <code>linear_sum_assignment</code> erlaubt). Die Lösung weicht auf die zweitbeste Zuordnung für Carla aus; die Gesamtkosten steigen um die Differenz.</p>
|
||||
<p><strong>8.5 — Engpass finden.</strong> Die Dualwerte der Kapazitätsschranken (<code>res.upper.marginals</code> bei <code>linprog</code>) zeigen es direkt; alternativ jede Kapazität einzeln um 1 erhöhen und neu rechnen. Im Beispiel ist die Kante <code>Werk_A → Umschlag</code> der Engpass (voll ausgelastet, günstigster Weg).</p>
|
||||
<p><strong>8.6 — <a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP</a> variieren.</strong> (a) Mit 3 Fahrzeugen werden die Touren länger, die Gesamtfahrzeit steigt leicht, die Auslastung deutlich. (b) Unlösbar, sobald <span class="math inline">\text{Kapazität} \times \text{Fahrzeuge} < \text{Gesamtbedarf}</span> (hier: bei 3 Fahrzeugen à 10 sind 30 < 37 → unlösbar) <strong>oder</strong> wenn Zeitfenster nicht mehr eingehalten werden können. (c) 1 s liefert meist eine brauchbare, 30 s eine spürbar bessere Lösung — die <a href="anhang-glossar.md#gloss:metaheuristik" class="glossar-link">Metaheuristik</a> verbessert kontinuierlich. (d) Doppelte Servicezeit kann Zeitfenster verletzen → möglicherweise unlösbar.</p>
|
||||
<p><strong>8.7 — <a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP</a> mit MTZ.</strong> Erwartetes Ergebnis: Bei 8 Städten löst das MILP in Sekunden. Ab etwa 12–15 Städten wird die schwache MTZ-Relaxation zum Problem, und die Laufzeit steigt stark — während <a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a> weiterhin in Sekundenbruchteilen sehr gute Touren liefert.</p>
|
||||
<p><strong>8.6 — <a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP (Vehicle Routing Problem)</a> variieren.</strong> (a) Mit 3 Fahrzeugen werden die Touren länger, die Gesamtfahrzeit steigt leicht, die Auslastung deutlich. (b) Unlösbar, sobald <span class="math inline">\text{Kapazität} \times \text{Fahrzeuge} < \text{Gesamtbedarf}</span> (hier: bei 3 Fahrzeugen à 10 sind 30 < 37 → unlösbar) <strong>oder</strong> wenn Zeitfenster nicht mehr eingehalten werden können. (c) 1 s liefert meist eine brauchbare, 30 s eine spürbar bessere Lösung — die <a href="anhang-glossar.md#gloss:metaheuristik" class="glossar-link">Metaheuristik</a> verbessert kontinuierlich. (d) Doppelte Servicezeit kann Zeitfenster verletzen → möglicherweise unlösbar.</p>
|
||||
<p><strong>8.7 — <a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP (Traveling Salesperson Problem)</a> mit MTZ.</strong> Erwartetes Ergebnis: Bei 8 Städten löst das MILP in Sekunden. Ab etwa 12–15 Städten wird die schwache MTZ-Relaxation zum Problem, und die Laufzeit steigt stark — während <a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a> weiterhin in Sekundenbruchteilen sehr gute Touren liefert.</p>
|
||||
<h3 id="finde-den-denkfehler-die-vergessene-dimension">Finde den Denkfehler — Die vergessene Dimension</h3>
|
||||
<ol type="a">
|
||||
<li><strong>Was die Fahrzeuge tun.</strong> Fahrzeuge 1, 2 und 3 fahren <strong>gar nicht</strong> — sie stehen mit null Stopps im Depot. Fahrzeug 4 bedient alle 16 Kunden und lädt dabei <strong>37 Paletten</strong> bei einer Kapazität von 10. Es ist um 270 % überladen. Physikalisch ist dieser Plan nicht ausführbar; im Modell ist er die beste Lösung.</li>
|
||||
|
|
@ -694,7 +694,7 @@
|
|||
<p><strong>Es fehlt die Schranke.</strong></p>
|
||||
<p>Alles, was der Kollege sagt, stimmt. Der Fehler liegt darin, was er <em>nicht</em> sagt: Die Ersparnis wird gegen die <strong>bisherige Praxis</strong> gemessen, nicht gegen das <strong>Mögliche</strong>. Damit beantwortet die Zahl eine andere Frage als die, die das Management stellt.</p>
|
||||
<p><code>Metaheuristik_vs_Exakt.py</code> liefert die fehlende Zahl in der Spalte <em>Schranke</em>: <strong>1 768 Minuten</strong>. Der Abstand der vorgestellten Lösung zum Bestmöglichen beträgt also bis zu 25 %, nicht 0 %. In derselben Nacht, in der 640 Stunden gefeiert werden, liegen möglicherweise weitere 2 000 Stunden ungenutzt herum.</p>
|
||||
<p>Die Konsequenz ist keine Absage an das Projekt — 6,2 % sind echt und werden verdient. Die Konsequenz ist eine ehrliche Fortschreibung: „Wir heben 6,2 % und wissen, dass bis zu einem Viertel noch offen ist. Der nächste Schritt ist <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS</a>.“ Wer die Schranke verschweigt, erklärt das Projekt für abgeschlossen und lässt den größeren Teil liegen.</p>
|
||||
<p>Die Konsequenz ist keine Absage an das Projekt — 6,2 % sind echt und werden verdient. Die Konsequenz ist eine ehrliche Fortschreibung: „Wir heben 6,2 % und wissen, dass bis zu einem Viertel noch offen ist. Der nächste Schritt ist <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS (Large Neighborhood Search)</a>.“ Wer die Schranke verschweigt, erklärt das Projekt für abgeschlossen und lässt den größeren Teil liegen.</p>
|
||||
<blockquote>
|
||||
<p>Dasselbe Muster in anderer Verkleidung: Kapitel Handelsmaschine, <code>Data_Snooping.py</code> — dort fehlt nicht die Schranke, sondern die Zahl der Versuche. Beide Male macht eine weggelassene Kennzahl aus einem korrekten Ergebnis eine irreführende Aussage.</p>
|
||||
</blockquote>
|
||||
|
|
@ -775,7 +775,7 @@
|
|||
<h2 id="sec:loesungen-qp-nlp">A.11 Lösungen zu Kapitel „Quadratische und nichtlineare Optimierung — KKT, Lagrange, Konvexität“</h2>
|
||||
<p><strong>11.1 — Konvexität einordnen.</strong> PSD (alle <span class="math inline">\ge 0</span>) → <strong>konvex</strong>, aber <strong>nicht streng</strong> konvex; die Lösung ist <strong>nicht notwendig eindeutig</strong>. Der Eigenwert 0 bedeutet eine <strong>flache Richtung</strong>: Entlang des zugehörigen Eigenvektors ändert sich der quadratische Term nicht — es gibt eine Rinne statt eines Punktes.</p>
|
||||
<p><strong>11.2 — <a href="anhang-glossar.md#gloss:komplementaerer-schlupf" class="glossar-link">Komplementärer Schlupf</a>.</strong> Ja, verträglich: <span class="math inline">\lambda_i w_i = 0</span> gilt für alle <span class="math inline">i</span> (<span class="math inline">w_2 = 0</span> mit <span class="math inline">\lambda_2 > 0</span>; die anderen mit <span class="math inline">\lambda = 0</span>). <span class="math inline">\lambda_2 = 0{,}03</span> bedeutet: Würde man Titel 2 zwingen, ein kleines positives Gewicht zu tragen, verschlechterte sich der Zielwert um 0,03 je Einheit — die Nichtnegativitätsschranke ist dort <strong>bindend</strong>.</p>
|
||||
<p><strong>11.3 — <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a> von Hand.</strong> <span class="math inline">\mathcal{L} = x_1^2 + x_2^2 + \lambda(4 - x_1 - x_2)</span>. Stationarität: <span class="math inline">2x_1 = \lambda</span>, <span class="math inline">2x_2 = \lambda</span> → <span class="math inline">x_1 = x_2</span>. Bindend (<span class="math inline">\lambda > 0</span>): <span class="math inline">x_1 + x_2 = 4</span> → <span class="math inline">x_1 = x_2 = 2</span>, <span class="math inline">\lambda = 4</span>. Prüfung: <span class="math inline">\lambda = 4 > 0</span> ✓, <span class="math inline">f = 8</span>. <strong>Interpretation:</strong> Würde die Forderung auf <span class="math inline">\ge 4{,}1</span> steigen, stiege <span class="math inline">f</span> um etwa <span class="math inline">4 \cdot 0{,}1 = 0{,}4</span>. Probe: <span class="math inline">2\cdot(2{,}05)^2 = 8{,}405</span> ✓.</p>
|
||||
<p><strong>11.3 — <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a> von Hand.</strong> <span class="math inline">\mathcal{L} = x_1^2 + x_2^2 + \lambda(4 - x_1 - x_2)</span>. Stationarität: <span class="math inline">2x_1 = \lambda</span>, <span class="math inline">2x_2 = \lambda</span> → <span class="math inline">x_1 = x_2</span>. Bindend (<span class="math inline">\lambda > 0</span>): <span class="math inline">x_1 + x_2 = 4</span> → <span class="math inline">x_1 = x_2 = 2</span>, <span class="math inline">\lambda = 4</span>. Prüfung: <span class="math inline">\lambda = 4 > 0</span> ✓, <span class="math inline">f = 8</span>. <strong>Interpretation:</strong> Würde die Forderung auf <span class="math inline">\ge 4{,}1</span> steigen, stiege <span class="math inline">f</span> um etwa <span class="math inline">4 \cdot 0{,}1 = 0{,}4</span>. Probe: <span class="math inline">2\cdot(2{,}05)^2 = 8{,}405</span> ✓.</p>
|
||||
<p><strong>11.4 — Unmögliche Korrelationsmatrix.</strong> Eigenwerte <span class="math inline">\approx (-0{,}62;\ 1{,}0;\ 2{,}62)</span> → <strong>nicht PSD</strong>, also unmöglich. Anschaulich: Wenn A stark <strong>positiv</strong> mit B korreliert und B stark positiv mit C, kann A nicht gleichzeitig stark <strong>negativ</strong> mit C korrelieren — Korrelation ist eingeschränkt transitiv. Formal: <span class="math inline">\rho_{AC} \ge \rho_{AB}\rho_{BC} - \sqrt{(1-\rho_{AB}^2)(1-\rho_{BC}^2)} = 0{,}81 - 0{,}19 = 0{,}62</span>; verlangt waren <span class="math inline">-0{,}9</span>.</p>
|
||||
<p><strong>11.5 — Gewichtung untersuchen.</strong> Erwartetes Muster: Größeres <span class="math inline">\alpha</span> → mehr Rendite, mehr Konzentration im Titel mit höchstem <span class="math inline">\mu</span>. Größeres <span class="math inline">\beta</span> → gleichmäßigere Gewichte, Entropie steigt Richtung <span class="math inline">\ln 4 = 1{,}386</span>. Ab etwa <span class="math inline">\beta \approx 0{,}1</span> dominiert die Entropie und man nähert sich der Gleichgewichtung. <strong>Empfehlung an einen Ausschuss:</strong> Nicht mit <span class="math inline">\beta</span> argumentieren, sondern mit der resultierenden <strong>Maximalposition</strong> — „mit dieser Einstellung liegt keine Position über 40 %“ ist verständlich, „<span class="math inline">\beta = 0{,}015</span>“ nicht.</p>
|
||||
<p><strong>11.6 — Nicht-Konvexität demonstrieren.</strong> Mit der bewusst fehlerhaft konstruierten Matrix finden 20 Startpunkte typischerweise mehrere verschiedene Optima; die „Portfoliovarianz“ <span class="math inline">w^\top\Sigma w</span> kann bei geeigneten Gewichten negativ werden (der zugehörige Eigenvektor liegt allerdings teilweise außerhalb des zulässigen Bereichs <span class="math inline">w \ge 0{,}001</span>, <span class="math inline">\sum w = 1</span> — deshalb fällt der Fehler bei naiver Prüfung nicht auf).</p>
|
||||
|
|
@ -829,7 +829,7 @@
|
|||
<p><strong>12.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>12.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) <a href="anhang-glossar.md#gloss:chance-constraint" class="glossar-link">Chance Constraint</a> — 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>12.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>12.4 — <a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI</a> 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>12.4 — <a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI (Expected Value of Perfect Information)</a> 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>12.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>12.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>12.7 — <a href="anhang-glossar.md#gloss:budgeted-uncertainty" class="glossar-link">Budgeted Uncertainty</a>.</strong></p>
|
||||
|
|
@ -887,7 +887,7 @@ F(11{,}33) = 1 - \frac{(18-11{,}33)^2}{(18-6)(18-10)} = 1 - \frac{44{,}4}{96} =
|
|||
<p><strong>13.1 — Bausteine.</strong> Stufe = Tag 1–5; Zustand = verbleibende Distanz (ggf. plus Erschöpfungsgrad); Aktion = heutige Tagesetappe; Wertfunktion = minimale Restanstrengung. <strong>Nicht</strong> in den Zustand gehören: bereits gelaufene Kilometer (redundant, wenn die Restdistanz bekannt ist) und das Wetter von gestern (ohne Einfluss auf die Zukunft).</p>
|
||||
<p><strong>13.2 — <a href="anhang-glossar.md#gloss:optimalitaetsprinzip" class="glossar-link">Optimalitätsprinzip</a>.</strong> Weil der Wert eines Zustands nur von den <em>künftigen</em> Entscheidungen abhängt, kann man ihn ab dem Ende rekursiv berechnen. Hängen die Kosten zusätzlich von <strong>früheren</strong> Aktionen ab, ist die Markov-Eigenschaft verletzt — die Lösung: die relevante Vergangenheit <strong>in den Zustand aufnehmen</strong> (dann wächst allerdings der <a href="anhang-glossar.md#gloss:zustandsraum" class="glossar-link">Zustandsraum</a>).</p>
|
||||
<p><strong>13.3 — <a href="anhang-glossar.md#gloss:rueckwaertsinduktion" class="glossar-link">Rückwärtsinduktion</a>.</strong> Mit <span class="math inline">C(n) = n^2 + 2n</span> und 5 Einheiten in 3 Perioden ergibt sich als optimaler Pfad <span class="math inline">2 \to 2 \to 1</span> (oder eine Permutation davon) mit Gesamtkosten <span class="math inline">8 + 8 + 3 = 19</span>. Alles auf einmal kostet <span class="math inline">25 + 10 = 35</span>.</p>
|
||||
<p><strong>13.4 — Rucksack als <a href="anhang-glossar.md#gloss:dynamische-programmierung-dp" class="glossar-link">DP</a>.</strong></p>
|
||||
<p><strong>13.4 — Rucksack als <a href="anhang-glossar.md#gloss:dynamische-programmierung-dp" class="glossar-link">DP (Dynamische Programmierung)</a>.</strong></p>
|
||||
<div class="sourceCode" id="cb16"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>V <span class="op">=</span> np.zeros((n <span class="op">+</span> <span class="dv">1</span>, kapazitaet <span class="op">+</span> <span class="dv">1</span>))</span>
|
||||
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> i <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">1</span>, n <span class="op">+</span> <span class="dv">1</span>):</span>
|
||||
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> c <span class="kw">in</span> <span class="bu">range</span>(kapazitaet <span class="op">+</span> <span class="dv">1</span>):</span>
|
||||
|
|
@ -1044,7 +1044,7 @@ F(11{,}33) = 1 - \frac{(18-11{,}33)^2}{(18-6)(18-10)} = 1 - \frac{44{,}4}{96} =
|
|||
<p><strong>16.3 — Die Brücke rückwärts.</strong> Shrinkage hilft, wenn man eine <strong>Kovarianzmatrix</strong> aus wenigen Beobachtungen schätzt. Bei Lieferzeiten tritt genau dasselbe Problem auf, sobald man die <em>Korrelationen zwischen</em> Lieferanten braucht — und die braucht man, sobald Lieferanten gemeinsame Ursachen haben: derselbe Hafen, dasselbe Vorprodukt, dieselbe Region.</p>
|
||||
<p>Bei 40 Lieferanten hat die Kovarianzmatrix 820 zu schätzende Einträge. Wer dafür 36 Monatswerte hat, schätzt 820 Zahlen aus 36 Beobachtungen — dasselbe Missverhältnis wie bei Aktienrenditen, mit denselben Folgen (<code>Kovarianz_Falle.py</code>).</p>
|
||||
<p>Benötigt würden: Lieferzeit-Zeitreihen je Lieferant über denselben Zeitraum, gleich getaktet. Genau daran scheitert es in der Praxis meist — die Daten liegen in Bestellvorgängen, nicht in einer Matrix.</p>
|
||||
<p><strong>16.4 — <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a> mit Ganzzahligkeit.</strong> Man ergänzt Binärvariablen <span class="math inline">y_j</span> je Lieferant und die Kopplung <span class="math inline">w_j \le y_j</span> sowie <span class="math inline">\sum_j y_j \le 3</span>. Da CVXPY gemischt-ganzzahlige Probleme unterstützt, genügt <code>cp.Variable(n, boolean=True)</code>.</p>
|
||||
<p><strong>16.4 — <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a> mit Ganzzahligkeit.</strong> Man ergänzt Binärvariablen <span class="math inline">y_j</span> je Lieferant und die Kopplung <span class="math inline">w_j \le y_j</span> sowie <span class="math inline">\sum_j y_j \le 3</span>. Da CVXPY gemischt-ganzzahlige Probleme unterstützt, genügt <code>cp.Variable(n, boolean=True)</code>.</p>
|
||||
<p>Zu erwarten ist ein <strong>höherer</strong> CVaR: Der zulässige Bereich wird kleiner, und die Feinabstimmung über sechs Lieferanten fällt weg. Der Aufschlag ist der Preis der Vertragswirklichkeit — und genau die Zahl, die man dem Einkauf vorlegt, wenn dort jemand sagt, drei Lieferanten seien genug.</p>
|
||||
<p><strong>16.5 — Die eigene Brücke.</strong> Freie Antwort. Eine gute Bearbeitung nennt das Modell, die Entsprechung und <strong>die Zeile der Grenztabelle, die im Weg steht</strong> — meist ist es die dritte (Teilbarkeit) oder die erste (gemessen gegen geschätzt). Wenn keine im Weg steht, ist die Übertragung wahrscheinlich zu oberflächlich geprüft.</p>
|
||||
<h3 id="denkfehler-loesung-bruecke">Finde den Denkfehler — „Das ist doch dasselbe Problem“</h3>
|
||||
|
|
@ -1151,7 +1151,7 @@ u_{k,\tau} \le 1 - b_{k,t} \qquad \text{für } \tau = t, \dots, t + M_k - 1
|
|||
<ol type="1">
|
||||
<li>Log-Renditen sind Differenzen von Logarithmen — die addieren sich über die Zeit. Diskrete Renditen sind lineare Anteile am Kapital — die addieren sich über gewichtete Positionen.</li>
|
||||
<li>Die Optimierung sucht die Richtungen kleinster geschätzter Varianz — genau jene, deren Eigenwerte am stärksten nach unten verzerrt sind. Sie optimiert dadurch in das Schätzrauschen hinein.</li>
|
||||
<li>Der Rang von <span class="math inline">\mathbf{X}^\top\mathbf{X}</span> ist höchstens <span class="math inline">T < N</span> — die Matrix ist nicht invertierbar, das <a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV</a>-Problem hat unendlich viele Lösungen.</li>
|
||||
<li>Der Rang von <span class="math inline">\mathbf{X}^\top\mathbf{X}</span> ist höchstens <span class="math inline">T < N</span> — die Matrix ist nicht invertierbar, das <a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV (Global Minimum Variance Portfolio)</a>-Problem hat unendlich viele Lösungen.</li>
|
||||
<li>Stichprobenmatrix (unverzerrt, verrauscht) mit strukturiertem Ziel (verzerrt, stabil). <span class="math inline">\delta</span> wird analytisch so bestimmt, dass der erwartete quadratische Fehler minimal wird.</li>
|
||||
<li>Skalierte Einheitsmatrix (sklearn) und Konstant-Korrelations-Ziel (LW 2003).</li>
|
||||
</ol>
|
||||
|
|
@ -1250,7 +1250,7 @@ T \ge \left(\frac{2\sigma}{\mu}\right)^2 = \left(\frac{2 \cdot 0{,}012}{0{,}0004
|
|||
</ol>
|
||||
<hr />
|
||||
<h2 id="sec:loesungen-cvar">A.20 Lösungen zu Kapitel „Tail-Risiko, CVaR und Transaktionskosten“</h2>
|
||||
<p><strong>20.1 — <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a> und CVaR von Hand.</strong> Sortierte Verluste: <span class="math inline">-2{,}0; -1{,}2; -0{,}8; -0{,}4; 0{,}3; 0{,}6; 1{,}1; 2{,}1; 5{,}4; 8{,}9</span>. Das 80 %-Quantil ist der 8. Wert: <span class="math inline">\text{VaR}_{80\%} = 2{,}1</span>. $_{80%} = $ Mittel der schlechtesten 20 % <span class="math inline">= (5{,}4+8{,}9)/2 = \mathbf{7{,}15}</span>.</p>
|
||||
<p><strong>20.1 — <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a> und CVaR von Hand.</strong> Sortierte Verluste: <span class="math inline">-2{,}0; -1{,}2; -0{,}8; -0{,}4; 0{,}3; 0{,}6; 1{,}1; 2{,}1; 5{,}4; 8{,}9</span>. Das 80 %-Quantil ist der 8. Wert: <span class="math inline">\text{VaR}_{80\%} = 2{,}1</span>. $_{80%} = $ Mittel der schlechtesten 20 % <span class="math inline">= (5{,}4+8{,}9)/2 = \mathbf{7{,}15}</span>.</p>
|
||||
<p><strong>20.2 — <a href="anhang-glossar.md#gloss:subadditivitaet" class="glossar-link">Subadditivität</a>.</strong> Ein Risikomaß sollte Diversifikation nie bestrafen: Das Risiko eines zusammengelegten Portfolios darf nicht größer sein als die Summe der Einzelrisiken. Wird das verletzt, hätte eine Bank einen Anreiz, Portfolios künstlich aufzuspalten, um Eigenkapitalanforderungen zu senken — ökonomisch unsinnig.</p>
|
||||
<p><strong>20.3 — Rockafellar-Uryasev nachvollziehen.</strong> (a) Schlechtestes Drittel von <span class="math inline">(1,4,9)</span> ist <span class="math inline">\{9\}</span> → CVaR <span class="math inline">= 9</span>. (b) Mit <span class="math inline">\frac{1}{S(1-\alpha)} = \frac{1}{3\cdot(1/3)} = 1</span>: <span class="math inline">\gamma=0</span>: <span class="math inline">0 + (1+4+9) = 14</span>. <span class="math inline">\gamma=1</span>: <span class="math inline">1 + (0+3+8) = 12</span>. <span class="math inline">\gamma=4</span>: <span class="math inline">4 + (0+0+5) = \mathbf{9}</span>. <span class="math inline">\gamma=5</span>: <span class="math inline">5+4 = 9</span>. <span class="math inline">\gamma=9</span>: <span class="math inline">9+0 = 9</span>. (c) Minimum ab <span class="math inline">\gamma = 4</span> bei <strong>9</strong> — identisch mit (a) ✓. (Das Minimum wird auf einem ganzen Intervall angenommen, weil die Funktion stückweise linear ist — genau der Grund, warum der CVaR nicht <em>streng</em> konvex ist.)</p>
|
||||
<p><strong>20.4 — Einheiten prüfen.</strong> In einem Modell, das annualisierte Rendite gegen täglichen CVaR verrechnet, wirkt <span class="math inline">1{,}5</span> effektiv als <span class="math inline">1{,}5/252 \approx 0{,}006</span> auf Tagesbasis — der Risikoterm ist also um Faktor 252 zu leicht gewichtet. Um dieselbe Wirkung wie <code>RISIKOAVERSION = 1.5</code> im konsistenten Tagesmodell zu erzielen, hätte man dort <code>lambda_risk = 1.5 * 252 = 378</code> setzen müssen.</p>
|
||||
|
|
@ -1486,7 +1486,7 @@ T \ge \left(\frac{2\sigma}{\mu}\right)^2 = \left(\frac{2 \cdot 0{,}012}{0{,}0004
|
|||
<li>„Grün” heißt nur, dass kein Test fehlgeschlagen ist — das gilt auch für eine Suite aus lauter <code>assert True</code>. „Prüft etwas” heißt, dass die Tests bei einem eingebauten Fehler rot würden; genau das misst der Mutationstest.</li>
|
||||
<li>Weil sonst nicht erkennbar ist, welche Hälfte die Zeit kostet. Im Kapitel gehen bei OR-Tools 78 % in den Aufbau — wer nur die Gesamtzeit sieht, wechselt den Solver und ändert damit fast nichts.</li>
|
||||
<li>Weil die Rechnung Sekunden bis Minuten dauert. Eine synchrone Antwort läuft in den Timeout des Reverse Proxy und blockiert währenddessen einen Arbeiter. <code>202</code> heißt „angenommen, noch nicht fertig” — genau die richtige Aussage.</li>
|
||||
<li>Ein Threadpool genügt, wenn der Solver den <a href="anhang-glossar.md#gloss:gil-global-interpreter-lock" class="glossar-link">GIL</a> freigibt — das tun die C++-Bibliotheken (OR-Tools, HiGHS) während <code>Solve()</code>, im Kapitel mit Faktor 3,5 bei vier Threads gemessen. Eine in reinem Python geschriebene Heuristik hält den GIL; für sie braucht es Prozesse.</li>
|
||||
<li>Ein Threadpool genügt, wenn der Solver den <a href="anhang-glossar.md#gloss:gil-global-interpreter-lock" class="glossar-link">GIL (Global Interpreter Lock)</a> freigibt — das tun die C++-Bibliotheken (OR-Tools, HiGHS) während <code>Solve()</code>, im Kapitel mit Faktor 3,5 bei vier Threads gemessen. Eine in reinem Python geschriebene Heuristik hält den GIL; für sie braucht es Prozesse.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
|
||||
|
|
|
|||
6
OR_HTML_04/anhang-modellierungsmuster.html
generated
6
OR_HTML_04/anhang-modellierungsmuster.html
generated
|
|
@ -412,7 +412,7 @@
|
|||
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a> modell.Add(<span class="bu">sum</span>(KOSTEN[i] <span class="op">*</span> x[i] <span class="cf">for</span> i <span class="kw">in</span> massnahmen</span>
|
||||
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> TOPF[i] <span class="op">==</span> topf) <span class="op"><=</span> grenze)</span></code></pre></div>
|
||||
<blockquote>
|
||||
<p>💡 <strong>Der <a href="anhang-glossar.md#gloss:schattenpreis" class="glossar-link">Schattenpreis</a> des Budgets ist die Zahl, nach der die Geschäftsführung fragt:</strong> „Was bringt der nächste Euro?“ Bei einem <strong><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a></strong> ist er direkt ablesbar. Bei <strong>Ganzzahligkeit gibt es ihn nicht</strong> — die Dualwerte der <a href="anhang-glossar.md#gloss:relaxation" class="glossar-link">Relaxation</a> sind keine gültige Antwort. Rechnen Sie stattdessen mit erhöhtem Budget neu und vergleichen Sie die Zielwerte (<a href="lp.html#sec:lp-entartung">Abschnitt 5.9</a>).</p>
|
||||
<p>💡 <strong>Der <a href="anhang-glossar.md#gloss:schattenpreis" class="glossar-link">Schattenpreis</a> des Budgets ist die Zahl, nach der die Geschäftsführung fragt:</strong> „Was bringt der nächste Euro?“ Bei einem <strong><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a></strong> ist er direkt ablesbar. Bei <strong>Ganzzahligkeit gibt es ihn nicht</strong> — die Dualwerte der <a href="anhang-glossar.md#gloss:relaxation" class="glossar-link">Relaxation</a> sind keine gültige Antwort. Rechnen Sie stattdessen mit erhöhtem Budget neu und vergleichen Sie die Zielwerte (<a href="lp.html#sec:lp-entartung">Abschnitt 5.9</a>).</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>⚠️ <strong>Die LP-Relaxation verspricht zu viel.</strong> Sie darf die letzte Maßnahme anteilig kaufen und liefert deshalb eine Schranke, die spürbar über dem tatsächlich Erreichbaren liegen kann. Wer sie als Prognose berichtet, verspricht Geld, das nicht kommt.</p>
|
||||
|
|
@ -426,7 +426,7 @@
|
|||
<h3 id="b14-nichtüberlappung">B14 — Nichtüberlappung</h3>
|
||||
<p><strong>Regel.</strong> „Eine Maschine bearbeitet nur einen Job gleichzeitig.“</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>modell.AddNoOverlap([intervall_1, intervall_2, ...])</span></code></pre></div>
|
||||
<p>In <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> bräuchte man je Paar eine Disjunktion (B4) — bei <span class="math inline">k</span> Jobs sind das <span class="math inline">\binom{k}{2}</span> Konstruktionen. <strong>Nehmen Sie hier <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a>.</strong></p>
|
||||
<p>In <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> bräuchte man je Paar eine Disjunktion (B4) — bei <span class="math inline">k</span> Jobs sind das <span class="math inline">\binom{k}{2}</span> Konstruktionen. <strong>Nehmen Sie hier <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a>.</strong></p>
|
||||
<h3 id="b15-kumulative-ressource">B15 — Kumulative Ressource</h3>
|
||||
<p><strong>Regel.</strong> „Zu keinem Zeitpunkt dürfen mehr als 3 Arbeiten gleichzeitig laufen“ bzw. „die Stromlast darf 500 kW nie übersteigen“.</p>
|
||||
<div class="sourceCode" id="cb10"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>modell.AddCumulative(intervalle, bedarfe, kapazitaet)</span></code></pre></div>
|
||||
|
|
@ -494,7 +494,7 @@
|
|||
</blockquote>
|
||||
<h3 id="b24-subtour-eliminierung">B24 — Subtour-Eliminierung</h3>
|
||||
<p><strong>MTZ (einfach, aber schwach):</strong> <span class="math display">u_i - u_j + C x_{ij} \le C - d_j \qquad \forall i\ne j</span></p>
|
||||
<p><strong>Besser in der Praxis:</strong> <code>AddCircuit</code> in <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> oder die <a href="anhang-glossar.md#gloss:routing-bibliothek" class="glossar-link">Routing-Bibliothek</a> von <a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a>.</p>
|
||||
<p><strong>Besser in der Praxis:</strong> <code>AddCircuit</code> in <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> oder die <a href="anhang-glossar.md#gloss:routing-bibliothek" class="glossar-link">Routing-Bibliothek</a> von <a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a>.</p>
|
||||
<hr />
|
||||
<h2 id="ein-wort-zur-auswahl">Ein Wort zur Auswahl</h2>
|
||||
<p>Wenn mehrere Muster passen, entscheiden Sie nach dieser Reihenfolge:</p>
|
||||
|
|
|
|||
8
OR_HTML_04/anhang-spickzettel.html
generated
8
OR_HTML_04/anhang-spickzettel.html
generated
|
|
@ -105,7 +105,7 @@
|
|||
</blockquote>
|
||||
<p><strong>Alle Schnipsel lösen dasselbe Problem</strong> — das Produktionsprogramm aus <a href="oekosystem.html#sec:oekosystem-schnellstart">Abschnitt 3.1</a> mit dem bekannten Optimum <strong>530</strong> und den Schattenpreisen <strong>12</strong> und <strong>1</strong>:</p>
|
||||
<p><span class="math display">\max\; 10x_1 + 15x_2 + 25x_3 \quad\text{u.d.N.}\quad x_1 + x_2 + 2x_3 \le 40,\;\; 2x_1 + 3x_2 + x_3 \le 50,\;\; x \ge 0</span></p>
|
||||
<p>Damit ist jeder Schnipsel selbstprüfend: Kommt bei Ihnen etwas anderes als 530 heraus, liegt es an der Übertragung, nicht am Modell. (Die Ausnahme ist <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> — ein rein stetiges <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> ist dort das falsche Werkzeug; die Seite zeigt stattdessen die <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a>-eigenen Bausteine.)</p>
|
||||
<p>Damit ist jeder Schnipsel selbstprüfend: Kommt bei Ihnen etwas anderes als 530 heraus, liegt es an der Übertragung, nicht am Modell. (Die Ausnahme ist <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> — ein rein stetiges <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> ist dort das falsche Werkzeug; die Seite zeigt stattdessen die <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a>-eigenen Bausteine.)</p>
|
||||
<blockquote>
|
||||
<p><strong>Was dieser Anhang <em>nicht</em> ist.</strong> Kein Vergleich und keine Empfehlung. Welche Bibliothek für welche Aufgabe taugt, steht in <a href="oekosystem.html#sec:oekosystem-wann-lohnt-sich-welche-ebene">Abschnitt 3.6</a>; denselben Fall in vier Bibliotheken <em>nebeneinander</em> zeigt <code>Ein_System_Vier_Ansaetze.py</code>, die beiden Modellierungssprachen <code>Modellierungsschichten.py</code>. Hier geht es allein ums Nachschlagen.</p>
|
||||
</blockquote>
|
||||
|
|
@ -210,7 +210,7 @@
|
|||
</ol>
|
||||
<hr />
|
||||
<h2 id="d3-or-tools-pywraplp">D3 — OR-Tools: <code>pywraplp</code></h2>
|
||||
<p><strong>Wofür.</strong> Bequeme algebraische Schreibweise für LP und <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> mit umschaltbarem Backend (<code>GLOP</code>, <code>SCIP</code>, <code>CBC</code>, <code>SAT</code>). <strong>Wofür nicht:</strong> <a href="anhang-glossar.md#gloss:scheduling" class="glossar-link">Scheduling</a> und kombinatorische Bedingungen — dafür ist CP-SAT (D4) da.</p>
|
||||
<p><strong>Wofür.</strong> Bequeme algebraische Schreibweise für LP und <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> mit umschaltbarem Backend (<code>GLOP</code>, <code>SCIP</code>, <code>CBC</code>, <code>SAT</code>). <strong>Wofür nicht:</strong> <a href="anhang-glossar.md#gloss:scheduling" class="glossar-link">Scheduling</a> und kombinatorische Bedingungen — dafür ist CP-SAT (D4) da.</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> ortools.linear_solver <span class="im">import</span> pywraplp</span>
|
||||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="co"># "GLOP" = LP, "SCIP" oder "CBC" = MILP, "SAT" = CP-SAT als MILP-Backend</span></span>
|
||||
|
|
@ -290,7 +290,7 @@
|
|||
</ol>
|
||||
<hr />
|
||||
<h2 id="d5-cvxpy">D5 — CVXPY</h2>
|
||||
<p><strong>Wofür.</strong> Konvexe Probleme: quadratische Ziele, Normen, <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a>, alles mit Regularisierungstermen. <strong>Wofür nicht:</strong> große kombinatorische Modelle — der Aufbau der Ausdrücke wird dann selbst zum Engpass.</p>
|
||||
<p><strong>Wofür.</strong> Konvexe Probleme: quadratische Ziele, Normen, <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a>, alles mit Regularisierungstermen. <strong>Wofür nicht:</strong> große kombinatorische Modelle — der Aufbau der Ausdrücke wird dann selbst zum Engpass.</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> numpy <span class="im">as</span> np</span>
|
||||
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> cvxpy <span class="im">as</span> cp</span>
|
||||
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
|
||||
|
|
@ -319,7 +319,7 @@
|
|||
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"Solverfehler:"</span>, problem.status)</span></code></pre></div>
|
||||
<h3 id="die-drei-häufigsten-stolpersteine-4">Die drei häufigsten Stolpersteine</h3>
|
||||
<ol type="1">
|
||||
<li><strong><a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP</a>-Regeln vor dem Lösen prüfen.</strong> <code>problem.is_dcp()</code> und dann die einzelnen Bedingungen — das nennt die Schuldige, statt einen <code>DCPError</code> ohne Ort zu werfen (<a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a>, C8).</li>
|
||||
<li><strong><a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP (Disciplined Convex Programming)</a>-Regeln vor dem Lösen prüfen.</strong> <code>problem.is_dcp()</code> und dann die einzelnen Bedingungen — das nennt die Schuldige, statt einen <code>DCPError</code> ohne Ort zu werfen (<a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a>, C8).</li>
|
||||
<li><strong><code>OPTIMAL_INACCURATE</code> ist kein Erfolg.</strong> Der Solver hat aufgegeben und meldet das leise. Diesen Fall immer eigens behandeln.</li>
|
||||
<li><strong>Der Aufbau kann teurer sein als das Lösen.</strong> Schleifen über Szenarien durch Vektorausdrücke ersetzen; <code>Parameter</code> statt Neuaufbau, wenn sich nur Zahlen ändern.</li>
|
||||
</ol>
|
||||
|
|
|
|||
2
OR_HTML_04/assets/search-index.js
generated
2
OR_HTML_04/assets/search-index.js
generated
File diff suppressed because one or more lines are too long
98
OR_HTML_04/bilder_04/titelseite.svg
generated
98
OR_HTML_04/bilder_04/titelseite.svg
generated
|
|
@ -2444,7 +2444,7 @@ z
|
|||
</g>
|
||||
</g>
|
||||
<g id="text_14">
|
||||
<!-- Stand: 10. September 2026 v17.38 -->
|
||||
<!-- Stand: 10. September 2026 v17.51 -->
|
||||
<g style="fill: #c7d2fe" transform="translate(71.4528 818.05749) scale(0.12 -0.12)">
|
||||
<defs>
|
||||
<path id="DejaVuSans-31" d="M 794 531
|
||||
|
|
@ -2546,75 +2546,29 @@ L 525 4134
|
|||
L 525 4666
|
||||
z
|
||||
" transform="scale(0.015625)"/>
|
||||
<path id="DejaVuSans-33" d="M 2597 2516
|
||||
Q 3050 2419 3304 2112
|
||||
Q 3559 1806 3559 1356
|
||||
Q 3559 666 3084 287
|
||||
Q 2609 -91 1734 -91
|
||||
Q 1441 -91 1130 -33
|
||||
Q 819 25 488 141
|
||||
L 488 750
|
||||
Q 750 597 1062 519
|
||||
Q 1375 441 1716 441
|
||||
Q 2309 441 2620 675
|
||||
Q 2931 909 2931 1356
|
||||
Q 2931 1769 2642 2001
|
||||
Q 2353 2234 1838 2234
|
||||
L 1294 2234
|
||||
L 1294 2753
|
||||
L 1863 2753
|
||||
Q 2328 2753 2575 2939
|
||||
Q 2822 3125 2822 3475
|
||||
Q 2822 3834 2567 4026
|
||||
Q 2313 4219 1838 4219
|
||||
Q 1578 4219 1281 4162
|
||||
Q 984 4106 628 3988
|
||||
L 628 4550
|
||||
Q 988 4650 1302 4700
|
||||
Q 1616 4750 1894 4750
|
||||
Q 2613 4750 3031 4423
|
||||
Q 3450 4097 3450 3541
|
||||
Q 3450 3153 3228 2886
|
||||
Q 3006 2619 2597 2516
|
||||
z
|
||||
" transform="scale(0.015625)"/>
|
||||
<path id="DejaVuSans-38" d="M 2034 2216
|
||||
Q 1584 2216 1326 1975
|
||||
Q 1069 1734 1069 1313
|
||||
Q 1069 891 1326 650
|
||||
Q 1584 409 2034 409
|
||||
Q 2484 409 2743 651
|
||||
Q 3003 894 3003 1313
|
||||
Q 3003 1734 2745 1975
|
||||
Q 2488 2216 2034 2216
|
||||
z
|
||||
M 1403 2484
|
||||
Q 997 2584 770 2862
|
||||
Q 544 3141 544 3541
|
||||
Q 544 4100 942 4425
|
||||
Q 1341 4750 2034 4750
|
||||
Q 2731 4750 3128 4425
|
||||
Q 3525 4100 3525 3541
|
||||
Q 3525 3141 3298 2862
|
||||
Q 3072 2584 2669 2484
|
||||
Q 3125 2378 3379 2068
|
||||
Q 3634 1759 3634 1313
|
||||
Q 3634 634 3220 271
|
||||
Q 2806 -91 2034 -91
|
||||
Q 1263 -91 848 271
|
||||
Q 434 634 434 1313
|
||||
Q 434 1759 690 2068
|
||||
Q 947 2378 1403 2484
|
||||
z
|
||||
M 1172 3481
|
||||
Q 1172 3119 1398 2916
|
||||
Q 1625 2713 2034 2713
|
||||
Q 2441 2713 2670 2916
|
||||
Q 2900 3119 2900 3481
|
||||
Q 2900 3844 2670 4047
|
||||
Q 2441 4250 2034 4250
|
||||
Q 1625 4250 1398 4047
|
||||
Q 1172 3844 1172 3481
|
||||
<path id="DejaVuSans-35" d="M 691 4666
|
||||
L 3169 4666
|
||||
L 3169 4134
|
||||
L 1269 4134
|
||||
L 1269 2991
|
||||
Q 1406 3038 1543 3061
|
||||
Q 1681 3084 1819 3084
|
||||
Q 2600 3084 3056 2656
|
||||
Q 3513 2228 3513 1497
|
||||
Q 3513 744 3044 326
|
||||
Q 2575 -91 1722 -91
|
||||
Q 1428 -91 1123 -41
|
||||
Q 819 9 494 109
|
||||
L 494 744
|
||||
Q 775 591 1075 516
|
||||
Q 1375 441 1709 441
|
||||
Q 2250 441 2565 725
|
||||
Q 2881 1009 2881 1497
|
||||
Q 2881 1984 2565 2268
|
||||
Q 2250 2553 1709 2553
|
||||
Q 1456 2553 1204 2497
|
||||
Q 953 2441 691 2322
|
||||
L 691 4666
|
||||
z
|
||||
" transform="scale(0.015625)"/>
|
||||
</defs>
|
||||
|
|
@ -2649,8 +2603,8 @@ z
|
|||
<use xlink:href="#DejaVuSans-31" transform="translate(1508.886719 0)"/>
|
||||
<use xlink:href="#DejaVuSans-37" transform="translate(1572.509766 0)"/>
|
||||
<use xlink:href="#DejaVuSans-2e" transform="translate(1636.132812 0)"/>
|
||||
<use xlink:href="#DejaVuSans-33" transform="translate(1667.919922 0)"/>
|
||||
<use xlink:href="#DejaVuSans-38" transform="translate(1731.542969 0)"/>
|
||||
<use xlink:href="#DejaVuSans-35" transform="translate(1667.919922 0)"/>
|
||||
<use xlink:href="#DejaVuSans-31" transform="translate(1731.542969 0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_15">
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 88 KiB |
10
OR_HTML_04/bruecke.html
generated
10
OR_HTML_04/bruecke.html
generated
|
|
@ -121,7 +121,7 @@
|
|||
<blockquote>
|
||||
<p><strong>📌 Kapitel auf einen Blick</strong></p>
|
||||
<p><strong>Worum geht es?</strong> Um den Nachweis, dass die Verfahren aus Teil II und III unverändert in der Finanzwelt funktionieren — und um die drei Stellen, an denen die Analogie endet.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> (Allokation als <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>), <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a> (Szenarien) und <a href="praxisfallen.html#sec:praxisfallen-or-kern">Abschnitt 22.6</a> (<code>or_kern.py</code>).</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> (Allokation als <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>), <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a> (Szenarien) und <a href="praxisfallen.html#sec:praxisfallen-or-kern">Abschnitt 22.6</a> (<code>or_kern.py</code>).</p>
|
||||
<p><strong>Danach können Sie:</strong> ein betriebswirtschaftliches Modell in die andere Domäne übersetzen, ohne den Modellcode anzufassen; Schattenpreise in beiden Welten lesen; und benennen, welche Annahmen dabei <strong>nicht</strong> mitwandern.</p>
|
||||
<p><strong>Zeitbedarf:</strong> ca. 2,5 Stunden.</p>
|
||||
<p><strong>Programme:</strong><br />
|
||||
|
|
@ -206,7 +206,7 @@
|
|||
<ol type="1">
|
||||
<li>… ein Allokationsproblem aus der einen Domäne in die andere übersetzen, indem Sie die Daten austauschen statt des Codes.</li>
|
||||
<li>… den Schattenpreis in beiden Welten deuten — als Wert einer Ressource und als Preis des Risikos.</li>
|
||||
<li>… erklären, warum die <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a>-Formulierung aus <a href="cvar.html#kap-cvar">Kapitel 20</a> auf Lieferverzüge genauso passt wie auf Kursverluste.</li>
|
||||
<li>… erklären, warum die <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a>-Formulierung aus <a href="cvar.html#kap-cvar">Kapitel 20</a> auf Lieferverzüge genauso passt wie auf Kursverluste.</li>
|
||||
<li>… die drei Stellen benennen, an denen die Analogie <strong>nicht</strong> trägt — und begründen, warum das Übertragen von Methoden dort gefährlich wird.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
|
|
@ -681,7 +681,7 @@ u_s \ge \ell_s^\top w - \gamma, \quad u_s \ge 0
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td><span class="math inline">\gamma</span></td>
|
||||
<td>der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a>: „so schlimm wird es an 95 % der Tage höchstens”</td>
|
||||
<td>der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a>: „so schlimm wird es an 95 % der Tage höchstens”</td>
|
||||
<td>„so viele Tage Verzug höchstens bei 95 % der Bestellungen”</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
@ -733,8 +733,8 @@ u_s \ge \ell_s^\top w - \gamma, \quad u_s \ge 0
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td><strong>Ob Teilbarkeit erlaubt ist</strong></td>
|
||||
<td>37,4 % eines Lieferanten gibt es nicht: Verträge, Mindestabnahmen, Rüstzeiten → <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a></td>
|
||||
<td>37,4 % eines Fonds sind ein normaler Auftrag → LP/<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a> genügt</td>
|
||||
<td>37,4 % eines Lieferanten gibt es nicht: Verträge, Mindestabnahmen, Rüstzeiten → <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a></td>
|
||||
<td>37,4 % eines Fonds sind ein normaler Auftrag → LP/<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a> genügt</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
6
OR_HTML_04/cpsat.html
generated
6
OR_HTML_04/cpsat.html
generated
|
|
@ -151,7 +151,7 @@ Do -> Bux
|
|||
Fr -> Abel</code></pre>
|
||||
</blockquote>
|
||||
</div>
|
||||
<p><strong>Elf Zeilen Modell, und der Plan steht.</strong> Beachten Sie besonders die Zeile <code>m.AddExactlyOne(...)</code>. Sie sagt wörtlich, was gemeint ist: <em>genau eine</em> Person je Tag. In <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> hätte man dafür eine Gleichung <span class="math inline">\sum_p x_{p,d} = 1</span> aufgestellt — machbar, aber schon eine Übersetzungsleistung. Bei Regeln wie „diese beiden Dienste nicht direkt hintereinander“ oder „höchstens eine Nachtschicht pro Woche“ wächst dieser Übersetzungsaufwand rasch; in <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> bleibt er eine Zeile.</p>
|
||||
<p><strong>Elf Zeilen Modell, und der Plan steht.</strong> Beachten Sie besonders die Zeile <code>m.AddExactlyOne(...)</code>. Sie sagt wörtlich, was gemeint ist: <em>genau eine</em> Person je Tag. In <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> hätte man dafür eine Gleichung <span class="math inline">\sum_p x_{p,d} = 1</span> aufgestellt — machbar, aber schon eine Übersetzungsleistung. Bei Regeln wie „diese beiden Dienste nicht direkt hintereinander“ oder „höchstens eine Nachtschicht pro Woche“ wächst dieser Übersetzungsaufwand rasch; in <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> bleibt er eine Zeile.</p>
|
||||
<p><strong>Und jetzt sehen Sie sich das Ergebnis genau an.</strong> <em>Cor bekommt keinen einzigen Dienst.</em> Dane arbeitet Montag <strong>und</strong> Dienstag hintereinander. Ist das ein Fehler?</p>
|
||||
<p>Nein — und das ist die wichtigste Lektion dieses Kapitels. Der Plan erfüllt <strong>jede</strong> Regel, die wir aufgeschrieben haben. Wir haben nur nie nach Fairness gefragt, und wir haben nie gesagt, dass Dienste nicht aufeinanderfolgen sollen. Ein Solver liefert exakt das Bestellte — nicht das Gemeinte.</p>
|
||||
<blockquote>
|
||||
|
|
@ -172,7 +172,7 @@ Fr -> Abel</code></pre>
|
|||
</ol>
|
||||
<hr />
|
||||
<h2 id="sec:cpsat-ein-anderes-denkmodell">7.3 Ein anderes Denkmodell</h2>
|
||||
<p>Während <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> und MILP auf algebraischen Gleichungen und Simplex-Matrizen beruhen, kommt <strong>Constraint Programming (CP)</strong> aus der künstlichen Intelligenz:</p>
|
||||
<p>Während <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> und MILP auf algebraischen Gleichungen und Simplex-Matrizen beruhen, kommt <strong>Constraint Programming (CP)</strong> aus der künstlichen Intelligenz:</p>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 33%" />
|
||||
|
|
@ -365,7 +365,7 @@ Fr -> Abel</code></pre>
|
|||
<tr class="odd">
|
||||
<td><code>AddCircuit(arcs)</code></td>
|
||||
<td>Die gewählten Kanten bilden <strong>einen</strong> Rundweg</td>
|
||||
<td><a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP</a>-artige Reihenfolgeprobleme</td>
|
||||
<td><a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP (Traveling Salesperson Problem)</a>-artige Reihenfolgeprobleme</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><code>.OnlyEnforceIf(bool)</code></td>
|
||||
|
|
|
|||
6
OR_HTML_04/cvar.html
generated
6
OR_HTML_04/cvar.html
generated
|
|
@ -104,8 +104,8 @@
|
|||
<blockquote>
|
||||
<p><strong>📌 Kapitel auf einen Blick</strong></p>
|
||||
<p><strong>Worum geht es?</strong> Um zwei Schwächen des Markowitz-Modells: Es unterschätzt Extremverluste und ignoriert die Kosten des Umschichtens. Beide lassen sich mit konvexen Mitteln beheben.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="markowitz.html#kap-markowitz">Kapitel 19</a>, <a href="lp.html#kap-lp">Kapitel 5</a> (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>-Formulierungen).</p>
|
||||
<p><strong>Danach können Sie:</strong> <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a> und <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a> unterscheiden, den CVaR nach Rockafellar/Uryasev als lineares Programm formulieren, Turnover über die <span class="math inline">L_1</span>-Norm bestrafen — und begründen, warum VaR-Kennzahlen nicht über Einheiten addiert werden dürfen.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="markowitz.html#kap-markowitz">Kapitel 19</a>, <a href="lp.html#kap-lp">Kapitel 5</a> (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>-Formulierungen).</p>
|
||||
<p><strong>Danach können Sie:</strong> <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a> und <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a> unterscheiden, den CVaR nach Rockafellar/Uryasev als lineares Programm formulieren, Turnover über die <span class="math inline">L_1</span>-Norm bestrafen — und begründen, warum VaR-Kennzahlen nicht über Einheiten addiert werden dürfen.</p>
|
||||
<p><strong>Zeitbedarf:</strong> ca. 5 Stunden.</p>
|
||||
<p><strong>Programme:</strong><br />
|
||||
<code>VaR_CVaR_Demo.py</code><br />
|
||||
|
|
@ -684,7 +684,7 @@ CVaR: Portfolio 101.33 vs. Summe 159.24 -> subadditiv (kohaerent)
|
|||
<p>Im Vergleichsmodell <code>optimiere_varianz()</code> steht die Standardabweichung als</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>L <span class="op">=</span> np.linalg.cholesky(sigma <span class="op">+</span> <span class="fl">1e-12</span> <span class="op">*</span> np.eye(N))</span>
|
||||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>risiko <span class="op">=</span> cp.norm2(L.T <span class="op">@</span> w) <span class="co"># = sqrt(w' sigma w)</span></span></code></pre></div>
|
||||
<p>und <strong>nicht</strong> als das Naheliegende, <code>cp.sqrt(cp.quad_form(w, sigma))</code>. Der naheliegende Ausdruck ist nicht <a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP</a> und wird von CVXPY mit einem <code>DCPError</code> abgelehnt: <code>cp.sqrt</code> ist konkav und verlangt deshalb ein <strong>konkaves</strong> Argument, <code>quad_form</code> ist aber konvex. Die Regel wird verletzt, obwohl die Funktion als ganze mathematisch völlig harmlos ist — <span class="math inline">\sqrt{w^\top \Sigma w}</span> ist konvex, DCP kann es nur nicht <em>sehen</em>.</p>
|
||||
<p>und <strong>nicht</strong> als das Naheliegende, <code>cp.sqrt(cp.quad_form(w, sigma))</code>. Der naheliegende Ausdruck ist nicht <a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP (Disciplined Convex Programming)</a> und wird von CVXPY mit einem <code>DCPError</code> abgelehnt: <code>cp.sqrt</code> ist konkav und verlangt deshalb ein <strong>konkaves</strong> Argument, <code>quad_form</code> ist aber konvex. Die Regel wird verletzt, obwohl die Funktion als ganze mathematisch völlig harmlos ist — <span class="math inline">\sqrt{w^\top \Sigma w}</span> ist konvex, DCP kann es nur nicht <em>sehen</em>.</p>
|
||||
<p>Wichtig ist die Fehlerdiagnose dahinter, weil sie leicht in die Irre geht: <code>cp.psd_wrap(sigma)</code> sieht nach der Lösung aus und ist keine. Es unterdrückt die <strong>numerische</strong> Beanstandung, dass <span class="math inline">\Sigma</span> nicht als positiv semidefinit erkannt wird — gegen die <strong>strukturelle</strong> Regelverletzung im Aufbau hilft es nicht.</p>
|
||||
<p>Der Ausweg ist immer derselbe: Zerlegen Sie <span class="math inline">\Sigma = LL^\top</span> (Cholesky). Dann ist <span class="math inline">w^\top \Sigma w = \lVert L^\top w\rVert_2^2</span>, und die Standardabweichung wird zur 2-Norm eines <strong>affinen</strong> Ausdrucks — konvex, regelkonform und für den Solver sogar die bessere Formulierung, weil sie direkt ein Kegelproblem ist. Der winzige Diagonalzuschlag <span class="math inline">10^{-12}</span> fängt den Fall ab, dass <span class="math inline">\Sigma</span> numerisch nur halbdefinit ist (mehr Titel als Handelstage, duplizierte Spalten). Die vollständige Fehlertabelle steht in <a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a>.</p>
|
||||
</blockquote>
|
||||
|
|
|
|||
4
OR_HTML_04/dekomposition.html
generated
4
OR_HTML_04/dekomposition.html
generated
|
|
@ -160,7 +160,7 @@
|
|||
<ol type="1">
|
||||
<li>… erklären, warum das naheliegende Zuordnungsmodell an <strong>Symmetrie</strong> scheitert.</li>
|
||||
<li>… ein Problem in <strong>Master</strong> und <strong>Pricing-Teilproblem</strong> zerlegen.</li>
|
||||
<li>… die Schleife schreiben: Master-<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> lösen, Dualwerte auslesen, Teilproblem lösen, Spalte hinzufügen.</li>
|
||||
<li>… die Schleife schreiben: Master-<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> lösen, Dualwerte auslesen, Teilproblem lösen, Spalte hinzufügen.</li>
|
||||
<li>… das Abbruchkriterium über die <strong>reduzierten Kosten</strong> begründen.</li>
|
||||
<li>… an einer Kennzahl der Instanz abschätzen, ob sich das Verfahren lohnt.</li>
|
||||
</ol>
|
||||
|
|
@ -811,7 +811,7 @@ Mutterrolle 5,600 mm, 13 bestellte Breiten, 219 Zuschnitte.
|
|||
<hr />
|
||||
<h2 id="sec:dekomposition-selbsttest">10.10 Selbsttest</h2>
|
||||
<ol type="1">
|
||||
<li>Erklären Sie Symmetrie in einem <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> an einem Beispiel aus Ihrem Arbeitsumfeld.</li>
|
||||
<li>Erklären Sie Symmetrie in einem <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> an einem Beispiel aus Ihrem Arbeitsumfeld.</li>
|
||||
<li>Was ist beim Zuschnitt eine „Spalte”, und was steht darin?</li>
|
||||
<li>Woher kommen die Preise, mit denen das Teilproblem rechnet?</li>
|
||||
<li>Warum ist das Verfahren exakt, obwohl es fast alle Muster nie ansieht?</li>
|
||||
|
|
|
|||
4
OR_HTML_04/dynamische-programmierung.html
generated
4
OR_HTML_04/dynamische-programmierung.html
generated
|
|
@ -234,7 +234,7 @@ Restkosten je Ort: {'Ziel': 0, 'Ost': 5, 'West': 8, '
|
|||
<li>… Zustand, Stufe, Aktion und Wertfunktion für ein gegebenes Problem benennen.</li>
|
||||
<li>… eine Rückwärtsinduktion von Hand für ein kleines Problem durchführen.</li>
|
||||
<li>… das Almgren-Chriss-Ausführungsproblem lösen und die Lösung interpretieren.</li>
|
||||
<li>… einschätzen, wann <a href="anhang-glossar.md#gloss:dynamische-programmierung-dp" class="glossar-link">DP</a> funktioniert und wann der „<a href="anhang-glossar.md#gloss:fluch-der-dimensionalitaet" class="glossar-link">Fluch der Dimensionalität</a>“ zuschlägt.</li>
|
||||
<li>… einschätzen, wann <a href="anhang-glossar.md#gloss:dynamische-programmierung-dp" class="glossar-link">DP (Dynamische Programmierung)</a> funktioniert und wann der „<a href="anhang-glossar.md#gloss:fluch-der-dimensionalitaet" class="glossar-link">Fluch der Dimensionalität</a>“ zuschlägt.</li>
|
||||
<li>… die Wertfunktion als <strong>Nachschlagetabelle</strong> lesen: Sie liefert keine Planfolge, sondern eine Regel, die auch bei Abweichungen gilt.</li>
|
||||
<li>… einen <a href="anhang-glossar.md#gloss:zustandsraum" class="glossar-link">Zustandsraum</a> auf Vollständigkeit prüfen und erkennen, wann eine Kostenart Vorgeschichte erfordert.</li>
|
||||
</ol>
|
||||
|
|
@ -885,7 +885,7 @@ Abweichung DP zur analytischen Loesung: 5.788 % (Diskretisierung: 1000 Stueck)
|
|||
<p><strong>Aufgabe 13.1 ⭐ — Bausteine benennen.</strong> Ein Wanderer plant eine 5-Tages-Tour und muss täglich entscheiden, wie weit er läuft. Bestimmen Sie Stufe, Zustand, Aktion und Wertfunktion. Was gehört <strong>nicht</strong> in den Zustand?</p>
|
||||
<p><strong>Aufgabe 13.2 ⭐ — Optimalitätsprinzip anwenden.</strong> Warum folgt aus dem Optimalitätsprinzip, dass man rückwärts rechnen darf? Was würde schiefgehen, wenn die Kosten einer Periode auch von <strong>früheren</strong> Aktionen abhängen (und nicht nur vom aktuellen Zustand)?</p>
|
||||
<p><strong>Aufgabe 13.3 ⭐⭐ — Rückwärtsinduktion von Hand.</strong> 5 Einheiten in 3 Perioden, Kosten <span class="math inline">C(n) = n^2 + 2n</span>. Erstellen Sie die vollständige Wertfunktionstabelle und bestimmen Sie den optimalen Pfad. Prüfen Sie mit <code>Bellman_Minimalbeispiel.py</code> (angepasst).</p>
|
||||
<p><strong>Aufgabe 13.4 ⭐⭐ — <a href="anhang-glossar.md#gloss:rucksackproblem" class="glossar-link">Rucksackproblem</a> als DP.</strong> Lösen Sie das Rucksackproblem aus <a href="milp.html#kap-milp">Kapitel 6</a> mit dynamischer Programmierung statt <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a>. (Zustand: verbleibende Kapazität; Stufe: betrachteter Gegenstand.) Vergleichen Sie Laufzeit und Ergebnis mit dem MILP-<a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a>.</p>
|
||||
<p><strong>Aufgabe 13.4 ⭐⭐ — <a href="anhang-glossar.md#gloss:rucksackproblem" class="glossar-link">Rucksackproblem</a> als DP.</strong> Lösen Sie das Rucksackproblem aus <a href="milp.html#kap-milp">Kapitel 6</a> mit dynamischer Programmierung statt <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a>. (Zustand: verbleibende Kapazität; Stufe: betrachteter Gegenstand.) Vergleichen Sie Laufzeit und Ergebnis mit dem MILP-<a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a>.</p>
|
||||
<p><strong>Aufgabe 13.5 ⭐⭐⭐ — Risikoaversion kalibrieren.</strong> Untersuchen Sie mit <code>Mehrperiodige_Order_Execution.py</code>: (a) Bei welchem <span class="math inline">\lambda</span> verkauft das Modell in der ersten Periode mehr als 50 %? (b) Stellen Sie den Zusammenhang zwischen <span class="math inline">\lambda</span> und den erwarteten Gesamtkosten dar. (c) Ein Händler sagt: „Ich will höchstens 20 % Marktauswirkungskosten und den Rest an Risiko.“ Welches <span class="math inline">\lambda</span> setzen Sie?</p>
|
||||
<p><strong>Aufgabe 13.6 ⭐⭐⭐ — Zustandsraum erweitern.</strong> Erweitern Sie das Ausführungsmodell um einen zweiten Zustand: die aktuelle <strong>Orderbuchtiefe</strong> (3 Stufen: dünn/normal/tief), die mit gegebenen Übergangswahrscheinlichkeiten wechselt und <span class="math inline">\eta</span> um Faktor 2 / 1 / 0,5 skaliert. Wie ändert sich die Strategie? Wie stark wächst die Rechenzeit?</p>
|
||||
<hr />
|
||||
|
|
|
|||
6
OR_HTML_04/einfuehrung.html
generated
6
OR_HTML_04/einfuehrung.html
generated
|
|
@ -552,13 +552,13 @@ Der Solver löst dieselbe Instanz in Sekundenbruchteilen.
|
|||
<td>Kontinuierlich</td>
|
||||
<td><span class="math inline">x \in \mathbb{R}</span></td>
|
||||
<td>Investitionsbetrag in Euro, Fördermenge in Litern</td>
|
||||
<td><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> — leicht</td>
|
||||
<td><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> — leicht</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Ganzzahlig</td>
|
||||
<td><span class="math inline">x \in \mathbb{Z}</span></td>
|
||||
<td>Anzahl produzierter Maschinen, Anzahl Mitarbeiter</td>
|
||||
<td><a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> — schwer</td>
|
||||
<td><a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> — schwer</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Binär</td>
|
||||
|
|
@ -1352,7 +1352,7 @@ Ergebnis geschrieben nach: produktionsmix_ergebnis.xlsx</code></pre>
|
|||
<p><strong>Aufgabe 1.2 ⭐ — Hart oder weich?</strong> Entscheiden Sie für jede Bedingung eines Klinik-Dienstplans, ob sie hart oder weich modelliert werden sollte, und begründen Sie: (a) Gesetzliche Ruhezeit von 11 Stunden zwischen zwei Diensten. (b) Frau Meier möchte freitags nicht arbeiten. (c) In jeder Nachtschicht muss mindestens eine examinierte Fachkraft anwesend sein. (d) Die Dienste sollen gleichmäßig über das Team verteilt sein. (e) Niemand arbeitet mehr als 10 Tage am Stück.</p>
|
||||
<p><strong>Aufgabe 1.3 ⭐⭐ — Kombinatorik selbst rechnen.</strong> Ein Speditionsdisponent muss 12 Aufträge auf einen einzigen Lkw in eine Reihenfolge bringen. (a) Wie viele Reihenfolgen gibt es? (b) Der Rechner prüft 5 Millionen Reihenfolgen pro Sekunde. Wie lange dauert das vollständige Durchprobieren? (c) Wie lange dauert es bei 13 Aufträgen? Um welchen Faktor ist das mehr? (d) Wie viele Aufträge könnte man in einer Stunde noch vollständig durchprobieren?</p>
|
||||
<p><strong>Aufgabe 1.4 ⭐⭐ — Modell lesen.</strong> Gegeben sei das Modell <span class="math display">\max\ 3x_1 + 5x_2 \quad \text{u. d. N.} \quad x_1 \le 4,\ \ 2x_2 \le 12,\ \ 3x_1 + 2x_2 \le 18,\ \ x_1, x_2 \ge 0.</span> (a) Benennen Sie die vier Bausteine. (b) Ist <span class="math inline">(2, 6)</span> zulässig? Ist <span class="math inline">(4, 3)</span> zulässig? Berechnen Sie jeweils <span class="math inline">Z</span>. (c) Finden Sie durch Probieren die beste ganzzahlige Lösung.</p>
|
||||
<p><strong>Aufgabe 1.5 ⭐⭐⭐ — Die Bäckerei programmieren.</strong> Setzen Sie das Bäckerei-Problem der Handrechnung <em>Zerlegen Sie dieses Problem</em> mit <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> um. Geben Sie die optimale Produktionsmenge, den Deckungsbeitrag und die Auslastung von Mehl und Ofen aus. Prüfen Sie Ihr Ergebnis mit <code>assert</code>-Anweisungen.</p>
|
||||
<p><strong>Aufgabe 1.5 ⭐⭐⭐ — Die Bäckerei programmieren.</strong> Setzen Sie das Bäckerei-Problem der Handrechnung <em>Zerlegen Sie dieses Problem</em> mit <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> um. Geben Sie die optimale Produktionsmenge, den Deckungsbeitrag und die Auslastung von Mehl und Ofen aus. Prüfen Sie Ihr Ergebnis mit <code>assert</code>-Anweisungen.</p>
|
||||
<p><strong>Aufgabe 1.6 ⭐⭐⭐ — Sensitivität durch Ausprobieren.</strong> Erweitern Sie <code>Bot_Allokation.py</code> so, dass es das Modell in einer Schleife für RAM-Kapazitäten von 54 bis 72 GB (in Schritten von 2) löst und eine Tabelle <code>RAM | x_A | x_B | Gewinn | Gewinnzuwachs pro zusätzlichem GB</code> ausgibt. (a) Ab welcher RAM-Menge steigt der Gewinn nicht mehr? Warum? (b) Was sagt Ihnen der „Gewinnzuwachs pro GB“ intuitiv? (Der Begriff dafür — <em>Schattenpreis</em> — folgt in <a href="lp.html#kap-lp">Kapitel 5</a>.)</p>
|
||||
<p><strong>Aufgabe 1.7 ⭐⭐⭐ — Eigenes Problem zerlegen.</strong> Wählen Sie ein Entscheidungsproblem aus Ihrem eigenen Alltag oder Beruf (Beispiele: Wochenplan für Sportkurse, Sitzordnung bei einer Feier, Aufteilung eines Budgets auf Projekte, Reihenfolge von Hausarbeiten). Füllen Sie die Vorlage aus <a href="#sec:einfuehrung-die-vier-universellen-bausteine-jedes-or">Abschnitt 1.6</a> vollständig aus. Notieren Sie außerdem: Woher kämen die Daten? Wer müsste das Ergebnis akzeptieren? — Heben Sie diese Notiz auf; sie ist der Ausgangspunkt für Ihr eigenes Projekt in der <a href="projektwerkstatt.html">Projektwerkstatt</a>.</p>
|
||||
<hr />
|
||||
|
|
|
|||
2
OR_HTML_04/finanzdaten.html
generated
2
OR_HTML_04/finanzdaten.html
generated
|
|
@ -713,7 +713,7 @@ prices.columns: ['AAPL', 'AMZN', 'CVX', 'GS', &
|
|||
<p><strong>Aufgabe 18.2 ⭐ — Mittelwertfalle.</strong> Ein Fonds meldet Jahresrenditen von <span class="math inline">+60\,\%</span>, <span class="math inline">-40\,\%</span>, <span class="math inline">+60\,\%</span>, <span class="math inline">-40\,\%</span>. (a) Wie hoch ist das arithmetische Mittel? (b) Wie viel Kapital hat ein Anleger nach 4 Jahren aus 10 000 €? (c) Welche jährliche Rendite entspricht dem tatsächlich?</p>
|
||||
<p><strong>Aufgabe 18.3 ⭐⭐ — Konditionszahl verstehen.</strong> Erzeugen Sie eine Kovarianzmatrix für <span class="math inline">N = 30</span> Titel aus <span class="math inline">T = 40</span>, <span class="math inline">T = 100</span> und <span class="math inline">T = 1000</span> simulierten Beobachtungen. Berechnen Sie jeweils kleinsten Eigenwert und Konditionszahl. Ab welchem <span class="math inline">T</span> wird die Matrix brauchbar?</p>
|
||||
<p><strong>Aufgabe 18.4 ⭐⭐ — Spaltenreihenfolge prüfen.</strong> Laden Sie fünf Ticker in einer bewusst unsortierten Reihenfolge. Zeigen Sie, dass <code>raw["Close"].columns</code> abweicht, und dass <code>raw["Close"][tickers]</code> das behebt. Was passiert, wenn ein Ticker nicht existiert?</p>
|
||||
<p><strong>Aufgabe 18.5 ⭐⭐⭐ — Beide Shrinkage-Ziele vergleichen.</strong> Implementieren Sie das Konstant-Korrelations-Ziel vollständig (inklusive eigener Berechnung von <span class="math inline">\delta</span> nach Ledoit/Wolf 2003 oder per Kreuzvalidierung). Vergleichen Sie mit <code>sklearn</code> anhand: (a) der Konditionszahl, (b) der Out-of-Sample-Volatilität eines <a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV</a>-Portfolios (nach dem Muster von <code>Schaetzrauschen_Demo.py</code>), (c) der Stabilität der Gewichte über rollierende Fenster.</p>
|
||||
<p><strong>Aufgabe 18.5 ⭐⭐⭐ — Beide Shrinkage-Ziele vergleichen.</strong> Implementieren Sie das Konstant-Korrelations-Ziel vollständig (inklusive eigener Berechnung von <span class="math inline">\delta</span> nach Ledoit/Wolf 2003 oder per Kreuzvalidierung). Vergleichen Sie mit <code>sklearn</code> anhand: (a) der Konditionszahl, (b) der Out-of-Sample-Volatilität eines <a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV (Global Minimum Variance Portfolio)</a>-Portfolios (nach dem Muster von <code>Schaetzrauschen_Demo.py</code>), (c) der Stabilität der Gewichte über rollierende Fenster.</p>
|
||||
<p><strong>Aufgabe 18.6 ⭐⭐⭐ — Error-Maximizer selbst messen.</strong> Erweitern Sie <code>Schaetzrauschen_Demo.py</code> um eine dritte Variante: die <strong>Gleichgewichtung</strong> (<span class="math inline">w_i = 1/N</span>), die überhaupt keine Schätzung benötigt. (a) Ab welchem <span class="math inline">T/N</span> schlägt die Stichproben-Optimierung die Gleichgewichtung? (b) Ab welchem <span class="math inline">T/N</span> schlägt Ledoit-Wolf sie? (c) Was folgt daraus für die Praxis?</p>
|
||||
<hr />
|
||||
<h2 id="sec:finanzdaten-denkfehler">18.8 Finde den Denkfehler</h2>
|
||||
|
|
|
|||
6
OR_HTML_04/fundament.html
generated
6
OR_HTML_04/fundament.html
generated
|
|
@ -436,7 +436,7 @@ f(\theta\mathbf{x} + (1-\theta)\mathbf{y}) \le \theta f(\mathbf{x}) + (1-\theta)
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>Lineares Programm (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>)</td>
|
||||
<td>Lineares Programm (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>)</td>
|
||||
<td><strong>ja</strong></td>
|
||||
<td>Globales Optimum, Sekunden bis Minuten selbst bei <span class="math inline">10^6</span> Variablen</td>
|
||||
</tr>
|
||||
|
|
@ -446,7 +446,7 @@ f(\theta\mathbf{x} + (1-\theta)\mathbf{y}) \le \theta f(\mathbf{x}) + (1-\theta)
|
|||
<td>Globales Optimum, effizient (<a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a>, <a href="markowitz.html#kap-markowitz">Kapitel 19</a>)</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Ganzzahlige Variablen (<a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a>)</td>
|
||||
<td>Ganzzahlige Variablen (<a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a>)</td>
|
||||
<td><strong>nein</strong></td>
|
||||
<td>Der zulässige Bereich ist ein Punktgitter, keine zusammenhängende Menge — <a href="anhang-glossar.md#gloss:np-schwer" class="glossar-link">NP-schwer</a> (<a href="milp.html#kap-milp">Kapitel 6</a>)</td>
|
||||
</tr>
|
||||
|
|
@ -456,7 +456,7 @@ f(\theta\mathbf{x} + (1-\theta)\mathbf{y}) \le \theta f(\mathbf{x}) + (1-\theta)
|
|||
<td>Nur lokale Optima; eine ungültige <a href="anhang-glossar.md#gloss:kovarianzmatrix" class="glossar-link">Kovarianzmatrix</a> ist ein typischer Auslöser (siehe <a href="qp-nlp.html#sec:qp-nlp-nichtlineare-optimierung-mit-scipy-optimize-minimize">Abschnitt 11.5</a>)</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Allgemeines <a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP</a> mit beliebigen Funktionen</td>
|
||||
<td>Allgemeines <a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP (Nichtlineare Programmierung)</a> mit beliebigen Funktionen</td>
|
||||
<td>meist <strong>nein</strong></td>
|
||||
<td><code>scipy.optimize</code> liefert nur ein lokales Optimum, abhängig vom Startpunkt</td>
|
||||
</tr>
|
||||
|
|
|
|||
273
OR_HTML_04/gesamtdokument.html
generated
273
OR_HTML_04/gesamtdokument.html
generated
File diff suppressed because it is too large
Load diff
10
OR_HTML_04/graphen.html
generated
10
OR_HTML_04/graphen.html
generated
|
|
@ -225,7 +225,7 @@ Gesamtfahrzeit: 118 min</code></pre>
|
|||
<li>… den <strong>Flusserhaltungssatz</strong> aufstellen und seine Bedeutung erklären.</li>
|
||||
<li>… begründen, warum Zuordnungsprobleme <strong>ohne</strong> Ganzzahligkeitsbedingung ganzzahlig lösbar sind (totale Unimodularität).</li>
|
||||
<li>… ein Vehicle Routing Problem mit Kapazitäten und Zeitfenstern mit <a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a> lösen.</li>
|
||||
<li>… einschätzen, wann ein spezialisierter Algorithmus einem allgemeinen <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> überlegen ist.</li>
|
||||
<li>… einschätzen, wann ein spezialisierter Algorithmus einem allgemeinen <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> überlegen ist.</li>
|
||||
<li>… begründen, warum eine gierige Zuordnung systematisch schlechter ist als eine gemeinsame Optimierung.</li>
|
||||
<li>… einen Tourenplan gegen die Wirklichkeit prüfen — unabhängig von den Bausteinen, aus denen das Modell gebaut wurde.</li>
|
||||
</ol>
|
||||
|
|
@ -424,7 +424,7 @@ Umschlag -> Kunde_2 5.0 10 3.00 15.00
|
|||
<blockquote>
|
||||
<p><strong>Satz.</strong> Die Extrempunkte der Menge aller doppelt-stochastischen Matrizen (alle Zeilensummen <span class="math inline">= 1</span>, alle Spaltensummen <span class="math inline">= 1</span>, <span class="math inline">x_{ij} \ge 0</span>) sind <strong>genau</strong> die Permutationsmatrizen (alle <span class="math inline">x_{ij} \in \{0,1\}</span>).</p>
|
||||
</blockquote>
|
||||
<p><strong>Warum das praktisch enorm wichtig ist:</strong> Nach dem Fundamentalsatz aus <a href="fundament.html#kap-fundament">Kapitel 2</a> liegt das <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>-Optimum in einer Ecke. Die Ecken sind hier laut Satz automatisch 0/1-wertig. Also gilt:</p>
|
||||
<p><strong>Warum das praktisch enorm wichtig ist:</strong> Nach dem Fundamentalsatz aus <a href="fundament.html#kap-fundament">Kapitel 2</a> liegt das <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>-Optimum in einer Ecke. Die Ecken sind hier laut Satz automatisch 0/1-wertig. Also gilt:</p>
|
||||
<blockquote>
|
||||
<p><strong>🎯 Merksatz</strong> Beim Zuordnungsproblem müssen Sie die Ganzzahligkeit <strong>nicht</strong> fordern — ein gewöhnlicher LP-Solver liefert von selbst eine 0/1-Lösung. Sie sparen sich damit die NP-Schwere von Branch-and-Bound vollständig.</p>
|
||||
</blockquote>
|
||||
|
|
@ -574,7 +574,7 @@ Umschlag -> Kunde_2 5.0 10 3.00 15.00
|
|||
</blockquote>
|
||||
<hr />
|
||||
<h2 id="sec:graphen-das-vehicle-routing-problem-mit-zeitfenstern">8.5 Das Vehicle Routing Problem mit Zeitfenstern</h2>
|
||||
<p>Das <strong>Traveling Salesperson Problem (<a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP</a>)</strong>, deutsch <em>Problem des Handlungsreisenden</em>, fragt nach der kürzesten Rundreise durch <span class="math inline">N</span> Städte. Das <strong>Capacitated Vehicle Routing Problem with Time Windows (<a href="anhang-glossar.md#gloss:cvrptw" class="glossar-link">CVRPTW</a>)</strong> erweitert es auf eine <strong>Flotte</strong> mit Kapazitätsgrenzen und Kundenzeitfenstern <span class="math inline">[e_i, l_i]</span>.</p>
|
||||
<p>Das <strong>Traveling Salesperson Problem (<a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP (Traveling Salesperson Problem)</a>)</strong>, deutsch <em>Problem des Handlungsreisenden</em>, fragt nach der kürzesten Rundreise durch <span class="math inline">N</span> Städte. Das <strong>Capacitated Vehicle Routing Problem with Time Windows (<a href="anhang-glossar.md#gloss:cvrptw" class="glossar-link">CVRPTW</a>)</strong> erweitert es auf eine <strong>Flotte</strong> mit Kapazitätsgrenzen und Kundenzeitfenstern <span class="math inline">[e_i, l_i]</span>.</p>
|
||||
<figure>
|
||||
<img src="bilder_04/kap_graphen_vrp_touren.svg" alt="Abb. 8.2: Die Lösung der Instanz aus VRP_Flotten_Routing.py: 16 Kunden, vier Fahrzeuge, 619 km. Beachten Sie, dass sich die Touren kreuzen. Bei einem reinen Tourenproblem wäre das ein sicheres Zeichen für eine verbesserbare Lösung — hier ist es keines: Die Zeitfenster erzwingen die Reihenfolge, und wer die Kreuzungen auflöst, kommt zu spät. Erzeugt von bilder_04/erzeuge_vrp_touren.py." />
|
||||
<figcaption aria-hidden="true">Abb. 8.2: Die Lösung der Instanz aus <code>VRP_Flotten_Routing.py</code>: 16 Kunden, vier Fahrzeuge, 619 km. <strong>Beachten Sie, dass sich die Touren kreuzen.</strong> Bei einem reinen Tourenproblem wäre das ein sicheres Zeichen für eine verbesserbare Lösung — hier ist es keines: Die Zeitfenster erzwingen die Reihenfolge, und wer die Kreuzungen auflöst, kommt zu spät. Erzeugt von <code>bilder_04/erzeuge_vrp_touren.py</code>.</figcaption>
|
||||
|
|
@ -766,7 +766,7 @@ u_i - u_j + C \cdot x_{ij} \le C - d_j \qquad \forall i \ne j
|
|||
<span id="cb6-164"><a href="#cb6-164" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
|
||||
<span id="cb6-165"><a href="#cb6-165" aria-hidden="true" tabindex="-1"></a> loese_cvrptw()</span></code></pre></div>
|
||||
<blockquote>
|
||||
<p><strong>⚠️ Typische Fehler beim <a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP</a></strong></p>
|
||||
<p><strong>⚠️ Typische Fehler beim <a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP (Vehicle Routing Problem)</a></strong></p>
|
||||
<ul>
|
||||
<li><strong><code>Min(CumulVar)</code> mit „Ankunftszeit“ verwechseln.</strong> Der Solver liefert ein <em>Intervall</em> möglicher Zeiten. <code>Min()</code> ist die früheste, <code>Max()</code> die späteste zulässige Zeit — die tatsächliche Fahrt kann irgendwo dazwischen starten.</li>
|
||||
<li><strong>Servicezeit im Depot mitzählen.</strong> Beim Start am Depot fällt keine Servicezeit an, sonst verschiebt sich der ganze Plan.</li>
|
||||
|
|
@ -1059,7 +1059,7 @@ plausibel aussieht.
|
|||
<li><strong>Totale Unimodularität ist zerbrechlich.</strong> Eine einzige zusätzliche Bedingung, die nicht ins Schema passt — Kardinalität, Fixkosten, Mindestmenge —, zerstört sie. Prüfen Sie das, bevor Sie sich auf die Struktur verlassen.</li>
|
||||
<li><strong>Der beste erste Zug ist selten Teil der besten Gesamtlösung.</strong> Gierige Regeln kosten schon bei vier Zuordnungen 8 %.</li>
|
||||
</ul>
|
||||
<p><strong>Ausblick.</strong> <a href="qp-nlp.html#teil-nichtlinear">Teil III</a> verlässt die lineare Welt. <a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a> führt quadratische Zielfunktionen und die <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a>-Bedingungen ein — das mathematische Fundament der Portfoliooptimierung.</p>
|
||||
<p><strong>Ausblick.</strong> <a href="qp-nlp.html#teil-nichtlinear">Teil III</a> verlässt die lineare Welt. <a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a> führt quadratische Zielfunktionen und die <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a>-Bedingungen ein — das mathematische Fundament der Portfoliooptimierung.</p>
|
||||
|
||||
</article>
|
||||
<button type="button" class="fortschritt-knopf" data-kapitel="graphen.html"><svg class="icon" aria-hidden="true"><use href="#icon-check"></use></svg> <span>Als gelesen markieren</span></button>
|
||||
|
|
|
|||
2
OR_HTML_04/index.html
generated
2
OR_HTML_04/index.html
generated
|
|
@ -115,7 +115,7 @@
|
|||
<p class="hero-anwendungen">Mit Python planen, optimieren und entscheiden: von Personal, Schichten und Logistik über Energie, Ressourcen und Netzwerke bis zur Portfoliooptimierung an den Finanzmärkten.</p>
|
||||
<p class="hero-autor">Autor / Herausgeber: Dieter Schlüter<br>
|
||||
<dieter(dot)schlueter(atsign)linix(dot)de><br>
|
||||
Stand: 10. September 2026 v17.39</p>
|
||||
Stand: 10. September 2026 v17.52</p>
|
||||
</div>
|
||||
</section>
|
||||
<section class="einstieg">
|
||||
|
|
|
|||
4
OR_HTML_04/lp.html
generated
4
OR_HTML_04/lp.html
generated
|
|
@ -107,7 +107,7 @@
|
|||
<figcaption aria-hidden="true">Entscheidungsdiagramm: Welches Werkzeug passt zu meinem Problem? (Teil II)</figcaption>
|
||||
</figure>
|
||||
<blockquote>
|
||||
<p><strong>🎯 Merksatz zum Diagramm</strong> Die erste Frage ist die wichtigste — und sie lautet <strong>nicht</strong> „welcher <a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a> ist der schnellste?“, sondern „welche <strong>Struktur</strong> hat mein Problem?“. Ein <a href="anhang-glossar.md#gloss:zuordnungsproblem" class="glossar-link">Zuordnungsproblem</a> braucht keinen <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a>-Solver, sondern eine Zeile <code>linear_sum_assignment</code>. Ein Dienstplan gehört nicht in ein <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>, sondern zu <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a>. Wer die Struktur erkennt, hat die halbe Laufzeit gespart, bevor die erste Zeile Code geschrieben ist.</p>
|
||||
<p><strong>🎯 Merksatz zum Diagramm</strong> Die erste Frage ist die wichtigste — und sie lautet <strong>nicht</strong> „welcher <a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a> ist der schnellste?“, sondern „welche <strong>Struktur</strong> hat mein Problem?“. Ein <a href="anhang-glossar.md#gloss:zuordnungsproblem" class="glossar-link">Zuordnungsproblem</a> braucht keinen <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a>-Solver, sondern eine Zeile <code>linear_sum_assignment</code>. Ein Dienstplan gehört nicht in ein <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>, sondern zu <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a>. Wer die Struktur erkennt, hat die halbe Laufzeit gespart, bevor die erste Zeile Code geschrieben ist.</p>
|
||||
</blockquote>
|
||||
<p>Fällt Ihr Problem durch das Diagramm hindurch — nichtlineare <a href="anhang-glossar.md#gloss:zielfunktion" class="glossar-link">Zielfunktion</a>, unsichere Daten, Entscheidungen über mehrere Zeitstufen —, dann ist <a href="qp-nlp.html#teil-nichtlinear">Teil III</a> der richtige Ort. Dort steht ein zweites Diagramm für genau diese Fälle.</p>
|
||||
<hr />
|
||||
|
|
@ -1190,7 +1190,7 @@ Pruefung: komplementaerer Schlupf fuer alle Ressourcen erfuellt.
|
|||
<tr class="odd">
|
||||
<td><strong>Primale Zulässigkeit</strong></td>
|
||||
<td>Wie weit darf <span class="math inline">\mathbf{A}\mathbf{x}</span> die Schranke <span class="math inline">\mathbf{b}</span> überschreiten?</td>
|
||||
<td><span class="math inline">10^{-7}</span> (HiGHS), <span class="math inline">10^{-6}</span> (<a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a>)</td>
|
||||
<td><span class="math inline">10^{-7}</span> (HiGHS), <span class="math inline">10^{-6}</span> (<a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a>)</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong>Duale Zulässigkeit</strong> (Optimalität)</td>
|
||||
|
|
|
|||
4
OR_HTML_04/markowitz.html
generated
4
OR_HTML_04/markowitz.html
generated
|
|
@ -104,7 +104,7 @@
|
|||
<blockquote>
|
||||
<p><strong>📌 Kapitel auf einen Blick</strong></p>
|
||||
<p><strong>Worum geht es?</strong> Um das Modell, das 1952 die quantitative Finanzwirtschaft begründete — und um die Restriktionen, ohne die es in der Praxis unbrauchbar bleibt.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a> (<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a>, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a>), <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a> (Kovarianz, Shrinkage).</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a> (<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a>, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a>), <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a> (Kovarianz, Shrinkage).</p>
|
||||
<p><strong>Danach können Sie:</strong> Die Effizienzgrenze berechnen, das Maximum-Sharpe-Portfolio über die <a href="anhang-glossar.md#gloss:korn-transformation" class="glossar-link">Korn-Transformation</a> bestimmen, institutionelle Nebenbedingungen einbauen — und beurteilen, wann eine Renditeschätzung das Ergebnis wertlos macht.</p>
|
||||
<p><strong>Zeitbedarf:</strong> ca. 6 Stunden.</p>
|
||||
<p><strong>Programme:</strong><br />
|
||||
|
|
@ -345,7 +345,7 @@ obwohl Formel und Simulation nichts voneinander wissen.</code></pre>
|
|||
<tr class="odd">
|
||||
<td><span class="math inline">0</span></td>
|
||||
<td>Risiko zählt allein</td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV</a></strong> — Global Minimum Variance Portfolio</td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV (Global Minimum Variance Portfolio)</a></strong> — Global Minimum Variance Portfolio</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>mittel</td>
|
||||
|
|
|
|||
4
OR_HTML_04/mehrziel.html
generated
4
OR_HTML_04/mehrziel.html
generated
|
|
@ -640,7 +640,7 @@ dem CO2-Preis, den das Unternehmen ohnehin ansetzt.
|
|||
<p><strong>Was Sie in der Abbildung sehen.</strong> Die beiden Geraden haben dieselbe Steigung, also dasselbe Gewicht <span class="math inline">w</span>. Die untere berührt die Hülle in zwei Ecken — eine von beiden meldet der <a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a> als Optimum. Die obere geht durch einen pareto-optimalen Punkt, der damit für dieses Gewicht chancenlos ist, und zwar nicht knapp: Er liegt eine ganze Stufe darüber. Verschieben Sie die Steigung, verschiebt sich die Berührung von einer Ecke zur nächsten — über den Punkt dazwischen springt sie hinweg. Die waagerechte Linie zeigt den Ausweg, um den es in <a href="#sec:mehrziel-epsilon">Abschnitt 14.7</a> geht: Eine Schranke für den CO₂-Ausstoß statt eines Gewichts findet genau diesen Punkt.</p>
|
||||
<blockquote>
|
||||
<p><strong>⚠️ Der Grund liegt in der Ganzzahligkeit</strong></p>
|
||||
<p>Bei einem reinen <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> ist der zulässige Bereich konvex, und die Pareto-Front liegt vollständig auf ihrer eigenen konvexen Hülle — dort findet die gewichtete Summe alles. Sobald Entscheidungen <strong>ganzzahlig</strong> werden (welcher Träger, welches Lager, welche Schicht), zerfällt der Bereich in einzelne Punkte, und zwischen ihnen entstehen Einbuchtungen.</p>
|
||||
<p>Bei einem reinen <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> ist der zulässige Bereich konvex, und die Pareto-Front liegt vollständig auf ihrer eigenen konvexen Hülle — dort findet die gewichtete Summe alles. Sobald Entscheidungen <strong>ganzzahlig</strong> werden (welcher Träger, welches Lager, welche Schicht), zerfällt der Bereich in einzelne Punkte, und zwischen ihnen entstehen Einbuchtungen.</p>
|
||||
<p>Deshalb betrifft dieses Problem praktisch jedes betriebliche Mehrzielmodell. Wer mit Gewichten arbeitet, verliert nicht ein paar Nachkommastellen, sondern <strong>ganze Alternativen</strong> — im Beispiel 40 % der Front.</p>
|
||||
</blockquote>
|
||||
<h3 id="das-gewicht-ist-keine-feineinstellung">Das Gewicht ist keine Feineinstellung</h3>
|
||||
|
|
@ -786,7 +786,7 @@ e(x) \le \varepsilon
|
|||
<h2 id="sec:mehrziel-selbsttest">14.12 Selbsttest</h2>
|
||||
<ol type="1">
|
||||
<li>Erklären Sie Pareto-Dominanz an einem Beispiel aus Ihrem Arbeitsumfeld.</li>
|
||||
<li>Warum ist „gewichtete Summe” bei einem reinen LP unproblematisch und bei einem <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> nicht?</li>
|
||||
<li>Warum ist „gewichtete Summe” bei einem reinen LP unproblematisch und bei einem <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> nicht?</li>
|
||||
<li>Ein Kollege sagt: „Ich nehme <span class="math inline">w = 0{,}5</span>, das ist neutral.” Was ist daran falsch?</li>
|
||||
<li>Beschreiben Sie das ε-Constraint-Verfahren in drei Sätzen, ohne Formeln.</li>
|
||||
<li>Sie legen einer Geschäftsführung eine Front mit zwölf Punkten vor. Welche Spalte brauchen Sie, damit die Entscheidung fallen kann?</li>
|
||||
|
|
|
|||
4
OR_HTML_04/metaheuristiken.html
generated
4
OR_HTML_04/metaheuristiken.html
generated
|
|
@ -1106,7 +1106,7 @@ nicht wegen seiner Loesung, sondern wegen seiner Schranke.
|
|||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: right;">60</td>
|
||||
<td><strong>Exakt.</strong> <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> beweist das Optimum in 2 Sekunden. Die Metaheuristik liegt 3,8 % daneben — und wüsste es nicht.</td>
|
||||
<td><strong>Exakt.</strong> <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> beweist das Optimum in 2 Sekunden. Die Metaheuristik liegt 3,8 % daneben — und wüsste es nicht.</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: right;">200</td>
|
||||
|
|
@ -1128,7 +1128,7 @@ nicht wegen seiner Loesung, sondern wegen seiner Schranke.
|
|||
<hr />
|
||||
<h2 id="sec:metaheuristiken-lns">9.7 Large Neighborhood Search</h2>
|
||||
<p>Die Tabelle oben endet mit einem Widerspruch. Bei 500 Aufträgen scheitert der exakte Solver an der <strong>Größe</strong>; die Metaheuristik scheitert an der <strong>Kleinheit ihrer Züge</strong> — sie verschiebt jeweils einen einzigen Auftrag und kann eine ganze Passage nicht auf einmal umbauen.</p>
|
||||
<p><strong>Large Neighborhood Search</strong> (<a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS</a>) setzt beide ein, jeden für das, was er kann:</p>
|
||||
<p><strong>Large Neighborhood Search</strong> (<a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS (Large Neighborhood Search)</a>) setzt beide ein, jeden für das, was er kann:</p>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 50%" />
|
||||
|
|
|
|||
6
OR_HTML_04/milp.html
generated
6
OR_HTML_04/milp.html
generated
|
|
@ -104,8 +104,8 @@
|
|||
<blockquote>
|
||||
<p><strong>📌 Kapitel auf einen Blick</strong></p>
|
||||
<p><strong>Worum geht es?</strong> Um Entscheidungen, die nicht teilbar sind: ganze Maschinen, Ja/Nein, „höchstens fünf davon“. Wir zeigen mit einem konkreten Gegenbeispiel, warum Runden <strong>falsch</strong> ist, und lernen die Modellierungstricks, mit denen sich logische Regeln in lineare Ungleichungen übersetzen lassen.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="lp.html#kap-lp">Kapitel 5</a> (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>, <a href="anhang-glossar.md#gloss:relaxation" class="glossar-link">Relaxation</a>, Schranken).</p>
|
||||
<p><strong>Danach können Sie:</strong> Fixkosten, Entweder-Oder, Wenn-Dann und Kardinalitätsgrenzen modellieren, ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> mit <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> oder <a href="anhang-glossar.md#gloss:highs" class="glossar-link">HiGHS</a> lösen, den <a href="anhang-glossar.md#gloss:mip-gap" class="glossar-link">MIP-Gap</a> als Zusage an den Auftraggeber lesen — und ein Ergebnis erkennen, das nur deshalb gut aussieht, weil das Big-M zu groß gewählt war.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="lp.html#kap-lp">Kapitel 5</a> (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>, <a href="anhang-glossar.md#gloss:relaxation" class="glossar-link">Relaxation</a>, Schranken).</p>
|
||||
<p><strong>Danach können Sie:</strong> Fixkosten, Entweder-Oder, Wenn-Dann und Kardinalitätsgrenzen modellieren, ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> mit <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> oder <a href="anhang-glossar.md#gloss:highs" class="glossar-link">HiGHS</a> lösen, den <a href="anhang-glossar.md#gloss:mip-gap" class="glossar-link">MIP-Gap</a> als Zusage an den Auftraggeber lesen — und ein Ergebnis erkennen, das nur deshalb gut aussieht, weil das Big-M zu groß gewählt war.</p>
|
||||
<p><strong>Zeitbedarf:</strong> ca. 6,5 Stunden.</p>
|
||||
<p><strong>Programme:</strong><br />
|
||||
<code>Runden_Gegenbeispiel.py</code><br />
|
||||
|
|
@ -1440,7 +1440,7 @@ Instanz Variante Makespan Zeit Faktor
|
|||
<li><strong><code>if status == OPTIMAL: ... else: return None</code>.</strong> Wirft eine Lösung weg, die 9 % vom Optimum entfernt und damit vollkommen brauchbar ist. Werten Sie den Gap aus, nicht nur den Status.</li>
|
||||
<li><strong>Zeitlimit ohne Gap-Auswertung.</strong> Ein Limit erzwingt ein Ende, sagt aber nichts über die Qualität. Ohne den Gap wissen Sie nicht, ob Sie 0,1 % oder 60 % danebenliegen.</li>
|
||||
<li><strong>Warm-Start als Selbstverständlichkeit.</strong> Messen Sie ihn — auf Ihrer Instanzklasse, gegen den kalten Lauf. In der Hälfte der Fälle bringt er nichts.</li>
|
||||
<li><strong>Einen Hinweis für eine unzulässige Lösung geben.</strong> <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> und HiGHS verwerfen ihn dann stillschweigend. Prüfen Sie Ihre Startlösung vorher auf Zulässigkeit — sonst messen Sie einen Effekt, den es gar nicht gibt.</li>
|
||||
<li><strong>Einen Hinweis für eine unzulässige Lösung geben.</strong> <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> und HiGHS verwerfen ihn dann stillschweigend. Prüfen Sie Ihre Startlösung vorher auf Zulässigkeit — sonst messen Sie einen Effekt, den es gar nicht gibt.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
|
|
|
|||
6
OR_HTML_04/modellierung.html
generated
6
OR_HTML_04/modellierung.html
generated
|
|
@ -927,11 +927,11 @@ Lesart C (weich): loesbar - 66,000 EUR Deckungsbeitrag, 1 Stammauftrag abgelehnt
|
|||
<td>„Besser als das hier geht es höchstens um 2 % — und die liegen unter unserer Datenungenauigkeit.”</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td><a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a></td>
|
||||
<td>„Wenn es schiefgeht, verlieren wir im Mittel so viel.” (Der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a> sagt nur, <strong>ob</strong> es schiefgeht.)</td>
|
||||
<td><a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a></td>
|
||||
<td>„Wenn es schiefgeht, verlieren wir im Mittel so viel.” (Der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a> sagt nur, <strong>ob</strong> es schiefgeht.)</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI</a></td>
|
||||
<td><a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI (Expected Value of Perfect Information)</a></td>
|
||||
<td>„Selbst eine perfekte Prognose wäre uns höchstens so viel wert.”</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
|
|
|
|||
30
OR_HTML_04/notation.html
generated
30
OR_HTML_04/notation.html
generated
|
|
@ -242,7 +242,7 @@
|
|||
<tr class="odd">
|
||||
<td><span class="math inline">\mathbb{R}</span></td>
|
||||
<td>Reelle Zahlen (beliebig teilbar)</td>
|
||||
<td>Variable darf 3,7 sein — <strong><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a></strong>, schnell lösbar</td>
|
||||
<td>Variable darf 3,7 sein — <strong><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a></strong>, schnell lösbar</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><span class="math inline">\mathbb{R}^n</span></td>
|
||||
|
|
@ -252,7 +252,7 @@
|
|||
<tr class="odd">
|
||||
<td><span class="math inline">\mathbb{Z}</span></td>
|
||||
<td>Ganze Zahlen</td>
|
||||
<td>Variable muss 3 oder 4 sein — <strong><a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a></strong>, <a href="anhang-glossar.md#gloss:np-schwer" class="glossar-link">NP-schwer</a></td>
|
||||
<td>Variable muss 3 oder 4 sein — <strong><a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a></strong>, <a href="anhang-glossar.md#gloss:np-schwer" class="glossar-link">NP-schwer</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><span class="math inline">\mathbb{N}_0</span></td>
|
||||
|
|
@ -475,7 +475,7 @@
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td><span class="math inline">\alpha</span></td>
|
||||
<td>Konfidenzniveau bei <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a>/<a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a></td>
|
||||
<td>Konfidenzniveau bei <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a>/<a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a></td>
|
||||
<td><span class="math inline">0{,}95</span> = „schlechteste 5 % der Tage“</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
@ -672,7 +672,7 @@
|
|||
<td><a href="milp.html#kap-milp">Kapitel 6</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a></strong></td>
|
||||
<td>Quadratic Program(ming)</td>
|
||||
<td>Quadratische Optimierung</td>
|
||||
<td><a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a></td>
|
||||
|
|
@ -684,7 +684,7 @@
|
|||
<td><a href="markowitz.html#kap-markowitz">Kapitel 19</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP (Nichtlineare Programmierung)</a></strong></td>
|
||||
<td>Nonlinear Program(ming)</td>
|
||||
<td>Nichtlineare Optimierung</td>
|
||||
<td><a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a></td>
|
||||
|
|
@ -696,13 +696,13 @@
|
|||
<td><a href="oekosystem.html#kap-oekosystem">Kapitel 3</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a></strong></td>
|
||||
<td>Constraint Programming</td>
|
||||
<td>Bedingungsprogrammierung</td>
|
||||
<td><a href="cpsat.html#kap-cpsat">Kapitel 7</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a></strong></td>
|
||||
<td>Boolean <strong>Sat</strong>isfiability Problem</td>
|
||||
<td>Erfüllbarkeitsproblem der Aussagenlogik</td>
|
||||
<td><a href="cpsat.html#kap-cpsat">Kapitel 7</a></td>
|
||||
|
|
@ -720,7 +720,7 @@
|
|||
<td><a href="cpsat.html#kap-cpsat">Kapitel 7</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:dynamische-programmierung-dp" class="glossar-link">DP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:dynamische-programmierung-dp" class="glossar-link">DP (Dynamische Programmierung)</a></strong></td>
|
||||
<td>Dynamic Programming</td>
|
||||
<td>Dynamische Programmierung</td>
|
||||
<td><a href="dynamische-programmierung.html#kap-dynamische-programmierung">Kapitel 13</a></td>
|
||||
|
|
@ -738,7 +738,7 @@
|
|||
<td><a href="milp.html#kap-milp">Kapitel 6</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a></strong></td>
|
||||
<td>Karush–Kuhn–Tucker (Bedingungen)</td>
|
||||
<td>Optimalitätsbedingungen bei Restriktionen</td>
|
||||
<td><a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a></td>
|
||||
|
|
@ -762,7 +762,7 @@
|
|||
<td><a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS (Large Neighborhood Search)</a></strong></td>
|
||||
<td>Large Neighborhood Search</td>
|
||||
<td>Große Nachbarschaftssuche: Teil der Lösung verwerfen, Rest exakt neu bauen</td>
|
||||
<td><a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a></td>
|
||||
|
|
@ -774,7 +774,7 @@
|
|||
<td><a href="dekomposition.html#kap-dekomposition">Kapitel 10</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:iis-irreducible-infeasible-subset" class="glossar-link">IIS</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:iis-irreducible-infeasible-subset" class="glossar-link">IIS (Irreducible Infeasible Subset)</a></strong></td>
|
||||
<td>Irreducible Infeasible Subset</td>
|
||||
<td>Kleinste widersprüchliche Teilmenge von Bedingungen</td>
|
||||
<td><a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a></td>
|
||||
|
|
@ -805,13 +805,13 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP (Traveling Salesperson Problem)</a></strong></td>
|
||||
<td>Traveling Salesperson Problem</td>
|
||||
<td>Problem des Handlungsreisenden</td>
|
||||
<td><a href="graphen.html#kap-graphen">Kapitel 8</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP (Vehicle Routing Problem)</a></strong></td>
|
||||
<td>Vehicle Routing Problem</td>
|
||||
<td>Tourenplanungsproblem</td>
|
||||
<td><a href="graphen.html#kap-graphen">Kapitel 8</a></td>
|
||||
|
|
@ -878,7 +878,7 @@
|
|||
<td><a href="markowitz.html#kap-markowitz">Kapitel 19</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV (Global Minimum Variance Portfolio)</a></strong></td>
|
||||
<td>Global Minimum Variance (Portfolio)</td>
|
||||
<td>Portfolio kleinstmöglicher Varianz</td>
|
||||
<td><a href="markowitz.html#kap-markowitz">Kapitel 19</a></td>
|
||||
|
|
@ -1059,7 +1059,7 @@
|
|||
<td>—</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:gil-global-interpreter-lock" class="glossar-link">GIL</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:gil-global-interpreter-lock" class="glossar-link">GIL (Global Interpreter Lock)</a></strong></td>
|
||||
<td>Global Interpreter Lock</td>
|
||||
<td>Pythons Sperre, die echte Parallelität von Python-Code verhindert — Solverbibliotheken in C++ geben sie frei (<a href="testing.html#kap-testing">Kapitel 23</a>)</td>
|
||||
<td>—</td>
|
||||
|
|
|
|||
16
OR_HTML_04/oekosystem.html
generated
16
OR_HTML_04/oekosystem.html
generated
|
|
@ -119,7 +119,7 @@
|
|||
<h2 id="sec:oekosystem-schnellstart">3.1 In 5 Minuten gelöst</h2>
|
||||
<div class="card card-schnellstart">
|
||||
<blockquote>
|
||||
<p><strong>🚀 In 5 Minuten gelöst: Ein <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> ohne jede Installation</strong></p>
|
||||
<p><strong>🚀 In 5 Minuten gelöst: Ein <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> ohne jede Installation</strong></p>
|
||||
<p>Ein Futtermittelhersteller mischt zwei Rohstoffe zu möglichst geringen Kosten. Jeder Kilogramm Mischung muss mindestens 20 g Protein und 5 g Fett enthalten.</p>
|
||||
<table>
|
||||
<thead>
|
||||
|
|
@ -189,7 +189,7 @@ Weizen 0.750 kg, Soja 0.250 kg -> 0.5350 EUR/kg</code></pre>
|
|||
<p>Im modernen Operations Research schreibt man Optimierungsalgorithmen nicht selbst. Man nutzt eine <strong>zweischichtige Architektur</strong>:</p>
|
||||
<ol type="1">
|
||||
<li><strong>Modellierungsschicht (<em>Frontend</em>, DSL):</strong> Python-Bibliotheken, mit denen Entscheidungsvariablen, Zielfunktion und Nebenbedingungen in mathematiknaher Syntax formuliert werden. Hier arbeiten Sie.</li>
|
||||
<li><strong>Solver-Schicht (<em>Backend</em>, Engine):</strong> Hochoptimierte C++- oder Fortran-Bibliotheken, die das Modell in Matrixstrukturen übersetzen und mit spezialisierten Algorithmen lösen (<a href="anhang-glossar.md#gloss:dual-simplex" class="glossar-link">Dual Simplex</a>, Interior-Point, <a href="anhang-glossar.md#gloss:branch-and-cut" class="glossar-link">Branch-and-Cut</a>, <a href="anhang-glossar.md#gloss:cdcl" class="glossar-link">CDCL</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a>-Suche).</li>
|
||||
<li><strong>Solver-Schicht (<em>Backend</em>, Engine):</strong> Hochoptimierte C++- oder Fortran-Bibliotheken, die das Modell in Matrixstrukturen übersetzen und mit spezialisierten Algorithmen lösen (<a href="anhang-glossar.md#gloss:dual-simplex" class="glossar-link">Dual Simplex</a>, Interior-Point, <a href="anhang-glossar.md#gloss:branch-and-cut" class="glossar-link">Branch-and-Cut</a>, <a href="anhang-glossar.md#gloss:cdcl" class="glossar-link">CDCL</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a>-Suche).</li>
|
||||
</ol>
|
||||
<figure>
|
||||
<img src="bilder_04/kap03_solver_architektur.svg" alt="Abb. 3.1: Modellierungsschicht und Solver-Engines" />
|
||||
|
|
@ -225,19 +225,19 @@ Weizen 0.750 kg, Soja 0.250 kg -> 0.5350 EUR/kg</code></pre>
|
|||
</tr>
|
||||
<tr class="even">
|
||||
<td><code>ortools</code> (Google)</td>
|
||||
<td>Diskrete Planung, Schichten, Vertretungspläne, Routing (<a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP</a>/<a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP</a>), kombinatorische Logik</td>
|
||||
<td>Diskrete Planung, Schichten, Vertretungspläne, Routing (<a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP (Vehicle Routing Problem)</a>/<a href="anhang-glossar.md#gloss:tsp-traveling-salesperson-problem" class="glossar-link">TSP (Traveling Salesperson Problem)</a>), kombinatorische Logik</td>
|
||||
<td>Wenn diskrete Ja/Nein-Entscheidungen, Zeitfenster und Wenn-Dann-Regeln dominieren</td>
|
||||
<td><a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a>, <a href="anhang-glossar.md#gloss:glop" class="glossar-link">GLOP</a>, Routing Engine</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td><code>cvxpy</code></td>
|
||||
<td>Konvexe Optimierung, quadratische Programme, Risikomodelle, Portfolios</td>
|
||||
<td><strong>Erste Wahl für Finanzoptimierung</strong>, Markowitz, <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a>, <span class="math inline">L_1</span>-<a href="anhang-glossar.md#gloss:transaktionskosten" class="glossar-link">Transaktionskosten</a></td>
|
||||
<td><strong>Erste Wahl für Finanzoptimierung</strong>, Markowitz, <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a>, <span class="math inline">L_1</span>-<a href="anhang-glossar.md#gloss:transaktionskosten" class="glossar-link">Transaktionskosten</a></td>
|
||||
<td>Clarabel, OSQP, ECOS, SCS, HiGHS</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><code>highspy</code></td>
|
||||
<td>Direkte Solver-Steuerung für LP/<a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a>, maximale Kontrolle</td>
|
||||
<td>Direkte Solver-Steuerung für LP/<a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a>, maximale Kontrolle</td>
|
||||
<td>Wenn Sie Modelle wiederholt und schnell aufbauen oder Solver-Details steuern müssen</td>
|
||||
<td>HiGHS</td>
|
||||
</tr>
|
||||
|
|
@ -258,7 +258,7 @@ Weizen 0.750 kg, Soja 0.250 kg -> 0.5350 EUR/kg</code></pre>
|
|||
<h3 id="die-entscheidung-in-drei-fragen">Die Entscheidung in drei Fragen</h3>
|
||||
<p>Statt die Tabelle auswendig zu lernen, beantworten Sie drei Fragen:</p>
|
||||
<blockquote>
|
||||
<p><strong>Frage 1: Gibt es Ja/Nein-Entscheidungen oder Reihenfolgen?</strong> → <strong>Ja:</strong> <a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a> (<a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-SAT) bei Zuweisung/<a href="anhang-glossar.md#gloss:scheduling" class="glossar-link">Scheduling</a>, oder MILP über HiGHS bei ökonomischen Fixkostenmodellen. → <strong>Nein:</strong> weiter zu Frage 2.</p>
|
||||
<p><strong>Frage 1: Gibt es Ja/Nein-Entscheidungen oder Reihenfolgen?</strong> → <strong>Ja:</strong> <a href="anhang-glossar.md#gloss:or-tools" class="glossar-link">OR-Tools</a> (<a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-SAT) bei Zuweisung/<a href="anhang-glossar.md#gloss:scheduling" class="glossar-link">Scheduling</a>, oder MILP über HiGHS bei ökonomischen Fixkostenmodellen. → <strong>Nein:</strong> weiter zu Frage 2.</p>
|
||||
<p><strong>Frage 2: Ist die Zielfunktion linear?</strong> → <strong>Ja:</strong> <code>scipy.optimize.linprog</code> (klein) oder <code>highspy</code> (groß, wiederholt). → <strong>Nein, aber konvex</strong> (Quadrate, Normen, <code>log</code>, <code>exp</code> in konvexer Kombination): <strong>CVXPY</strong>. → <strong>Nein und nicht konvex:</strong> <code>scipy.optimize.minimize</code> — im Bewusstsein, dass nur ein lokales Optimum herauskommt.</p>
|
||||
<p><strong>Frage 3: Ist es ein Routing-Problem mit Fahrzeugen, Depots und Zeitfenstern?</strong> → <strong>Ja:</strong> OR-Tools <strong>Routing Library</strong> (nicht CP-SAT von Hand nachbauen).</p>
|
||||
</blockquote>
|
||||
|
|
@ -448,7 +448,7 @@ Weizen 0.750 kg, Soja 0.250 kg -> 0.5350 EUR/kg</code></pre>
|
|||
<blockquote>
|
||||
<p><strong>⚠️ <code>max_tasks_per_child=1</code> ist nicht optional</strong> Ein Pool ohne diese Angabe ist der <strong>Normalfall</strong> — er soll seine Arbeiter ja wiederverwenden. Wer die Isolation über einen Pool herstellt und das vergisst, hat einen Prozesswechsel programmiert, aber keine Isolation gewonnen: Die zweite Aufgabe landet im selben Interpreter wie die erste. Der Absturz kommt dann nicht beim ersten Solver, sondern beim zweiten — und sieht aus wie ein Problem des zweiten.</p>
|
||||
</blockquote>
|
||||
<p>Denselben Aufbau verwenden <code>Solverwechsel_CPSAT_HiGHS.py</code> (<a href="praxisfallen.html#kap-praxisfallen">Kapitel 22</a>) und <code>Benchmark_Skalierung.py</code> (<a href="testing.html#kap-testing">Kapitel 23</a>). Dort wandern zusätzlich <strong>Datenobjekte</strong> über die Prozessgrenze statt Zeichenketten — möglich, weil Domänenmodell und Lösungs-<a href="anhang-glossar.md#gloss:dto-data-transfer-object" class="glossar-link">DTO</a> keinen Solver kennen (<a href="praxisfallen.html#sec:praxisfallen-or-kern">Abschnitt 22.6</a>).</p>
|
||||
<p>Denselben Aufbau verwenden <code>Solverwechsel_CPSAT_HiGHS.py</code> (<a href="praxisfallen.html#kap-praxisfallen">Kapitel 22</a>) und <code>Benchmark_Skalierung.py</code> (<a href="testing.html#kap-testing">Kapitel 23</a>). Dort wandern zusätzlich <strong>Datenobjekte</strong> über die Prozessgrenze statt Zeichenketten — möglich, weil Domänenmodell und Lösungs-<a href="anhang-glossar.md#gloss:dto-data-transfer-object" class="glossar-link">DTO (Data Transfer Object)</a> keinen Solver kennen (<a href="praxisfallen.html#sec:praxisfallen-or-kern">Abschnitt 22.6</a>).</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/usr/bin/env python3</span></span>
|
||||
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="co"># Ein_System_Vier_Ansaetze.py</span></span>
|
||||
|
|
@ -747,7 +747,7 @@ Alle Wege fuehren zum selben, von Hand bestaetigten Optimum.
|
|||
<td>Modellaufbau wird sonst zum Engpass</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Nichtkonvexes <a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP</a></td>
|
||||
<td>Nichtkonvexes <a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP (Nichtlineare Programmierung)</a></td>
|
||||
<td><code>scipy.optimize.minimize</code></td>
|
||||
<td>Bewusst mit mehreren Startpunkten arbeiten</td>
|
||||
</tr>
|
||||
|
|
|
|||
8
OR_HTML_04/praxisfallen.html
generated
8
OR_HTML_04/praxisfallen.html
generated
|
|
@ -199,7 +199,7 @@
|
|||
<li>… die Architektur einer produktionsreifen OR-Plattform skizzieren.</li>
|
||||
<li>… eine <strong>modellunabhängige Abnahmeprüfung</strong> schreiben, die eine Lösung gegen die Anforderungen prüft statt gegen das Modell.</li>
|
||||
<li>… Status, Gap und Zeitausschöpfung protokollieren und begründen, warum eine konstante Laufzeit bei Zeitlimit ein Warnsignal ist.</li>
|
||||
<li>… ein Modell in Domänenschicht, Modellbauer und Lösungs-<a href="anhang-glossar.md#gloss:dto-data-transfer-object" class="glossar-link">DTO</a> trennen — und begründen, warum sich das nicht wegen des Solverwechsels lohnt, sondern wegen der Prüfbarkeit.</li>
|
||||
<li>… ein Modell in Domänenschicht, Modellbauer und Lösungs-<a href="anhang-glossar.md#gloss:dto-data-transfer-object" class="glossar-link">DTO (Data Transfer Object)</a> trennen — und begründen, warum sich das nicht wegen des Solverwechsels lohnt, sondern wegen der Prüfbarkeit.</li>
|
||||
<li>… die Statuswerte verschiedener Solverbibliotheken auf eine gemeinsame Sprache abbilden.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
|
|
@ -453,7 +453,7 @@
|
|||
<h3 id="falle-4-lookahead--und-survivorship-bias">Falle 4 — Lookahead- und Survivorship-Bias</h3>
|
||||
<p>Ausführlich in <a href="handelsmaschine.html#kap-handelsmaschine">Kapitel 21</a> behandelt. Die Kurzfassung: Beide Fehler machen Backtests systematisch zu gut, ohne eine Fehlermeldung zu erzeugen. Der Lookahead-Selbsttest aus <a href="handelsmaschine.html#sec:handelsmaschine-die-engine">Abschnitt 21.5</a> findet den ersten automatisch.</p>
|
||||
<h3 id="falle-5-laufzeitexplosion">Falle 5 — Laufzeitexplosion</h3>
|
||||
<p>Exakte Optimalität kann bei <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> oder <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> Minuten bis Stunden dauern — und die Laufzeit wächst nicht linear mit der Problemgröße.</p>
|
||||
<p>Exakte Optimalität kann bei <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> oder <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a> Minuten bis Stunden dauern — und die Laufzeit wächst nicht linear mit der Problemgröße.</p>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 33%" />
|
||||
|
|
@ -908,7 +908,7 @@ aus.
|
|||
|
||||
==============================================================================</code></pre>
|
||||
<h3 id="drei-befunde-und-keiner-steht-im-solverergebnis">Drei Befunde, und keiner steht im Solverergebnis</h3>
|
||||
<p><strong>Erstens: bindend heißt nicht teuer.</strong> Fünf Bedingungen binden, aber „Lackierbudget Schicht 2“ tut es mit einem Schattenpreis von <strong>0,00 €</strong>. Sie berührt den Plan, ohne ihn zu verteuern — wer sie nachverhandelt, gewinnt nichts. Das ist derselbe Unterschied, den <code>Erklaerbarkeit.py</code> oben an einer einzelnen Zuweisung zeigt, hier im Dualwert eines <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>.</p>
|
||||
<p><strong>Erstens: bindend heißt nicht teuer.</strong> Fünf Bedingungen binden, aber „Lackierbudget Schicht 2“ tut es mit einem Schattenpreis von <strong>0,00 €</strong>. Sie berührt den Plan, ohne ihn zu verteuern — wer sie nachverhandelt, gewinnt nichts. Das ist derselbe Unterschied, den <code>Erklaerbarkeit.py</code> oben an einer einzelnen Zuweisung zeigt, hier im Dualwert eines <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>.</p>
|
||||
<p><strong>Zweitens: Der Schattenpreis ist eine Momentaufnahme.</strong> Er gilt für die <strong>nächste</strong> Einheit. Ein Planer kauft aber keine Einheit, sondern eine Schicht. Für die Lackiererei verspricht die Hochrechnung <span class="math inline">4{,}00 \cdot 30 = 120</span> €; gemessen kommen <strong>60 €</strong>. Der Preis von 4,00 € gilt exakt bis <strong>+15 Stunden</strong>, danach begrenzt etwas anderes — <strong>die zweite Hälfte der Sonderschicht wäre bezahlt und wirkungslos.</strong></p>
|
||||
<p>Und die Ranglisten drehen sich dabei um: Nach Schattenpreis führt der Trägervertrag mit 18,00 € je Stück, nach tatsächlicher Wirkung die Montage-Sonderschicht mit 450 €. Der Schattenpreis sagt, was <strong>eine</strong> Einheit wert ist — nicht, wie viele Einheiten zu haben sind. Für die Frage „welchen Hebel ziehen wir?“ ist das der entscheidende Unterschied.</p>
|
||||
<p><strong>Drittens: Ein Wunsch kann unmöglich statt teuer sein.</strong> Der Vertrieb hätte gern 55 Rahmen statt 47,5. Das Modell antwortet nicht mit einem Preis, sondern mit <code>INFEASIBLE</code> — und drei Bedingungen blockieren den Wunsch <strong>gemeinsam</strong>: Fällt eine davon weg, ist er erfüllbar, keine allein ist „der“ Grund. Genau die Struktur, die <a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a> für den unlösbaren Fall beschreibt, hier auf einen Wunsch angewandt.</p>
|
||||
|
|
@ -1062,7 +1062,7 @@ aus.
|
|||
<tr class="header">
|
||||
<th>Bedeutung</th>
|
||||
<th>pywraplp</th>
|
||||
<th><a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a></th>
|
||||
<th><a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a></th>
|
||||
<th>HiGHS</th>
|
||||
<th><a href="anhang-glossar.md#gloss:scipy" class="glossar-link">SciPy</a></th>
|
||||
<th>CVXPY</th>
|
||||
|
|
|
|||
8
OR_HTML_04/projektwerkstatt.html
generated
8
OR_HTML_04/projektwerkstatt.html
generated
|
|
@ -185,7 +185,7 @@
|
|||
<p><strong>Schwierigkeit:</strong> ⭐⭐⭐ · <strong>Kapitel:</strong> <a href="milp.html#kap-milp">Kapitel 6</a>, <a href="cpsat.html#kap-cpsat">Kapitel 7</a>, <a href="praxisfallen.html#kap-praxisfallen">Kapitel 22</a> · <strong>Zeit:</strong> ca. 20 Stunden</p>
|
||||
</blockquote>
|
||||
<p><strong>Ausgangslage.</strong> 25 Pflegekräfte, drei Schichten täglich, 28-Tage-Zyklus. Es gelten Arbeitszeitgesetz, Tarifvertrag, Qualifikationsmix und individuelle Wünsche.</p>
|
||||
<p><strong>Modellskizze.</strong> * Variablen: <span class="math inline">x_{p,t,s} \in \{0,1\}</span> — Person, Tag, Schicht. * Hart: Mindestbesetzung je Schicht <strong>und</strong> Qualifikationsmix (mindestens eine examinierte Kraft); nach Nachtschicht ≥ 2 freie Tage; höchstens 6 Arbeitstage in Folge; monatliche Sollstunden ± 10 %. * Weich: Wunschfrei, gleichmäßige Wochenendverteilung, ungeteilte Dienste, stabile Schichtfolgen (nicht Früh–Nacht–Früh). * Solver: <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> mit Intervall- und Cumulative-Constraints.</p>
|
||||
<p><strong>Modellskizze.</strong> * Variablen: <span class="math inline">x_{p,t,s} \in \{0,1\}</span> — Person, Tag, Schicht. * Hart: Mindestbesetzung je Schicht <strong>und</strong> Qualifikationsmix (mindestens eine examinierte Kraft); nach Nachtschicht ≥ 2 freie Tage; höchstens 6 Arbeitstage in Folge; monatliche Sollstunden ± 10 %. * Weich: Wunschfrei, gleichmäßige Wochenendverteilung, ungeteilte Dienste, stabile Schichtfolgen (nicht Früh–Nacht–Früh). * Solver: <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> mit Intervall- und Cumulative-Constraints.</p>
|
||||
<p><strong>Abnahmekriterien.</strong> - [ ] Alle gesetzlichen Regeln nachweislich eingehalten (per <code>assert</code> geprüft). - [ ] Wunscherfüllungsquote wird ausgewiesen und ist fair verteilt (<a href="anhang-glossar.md#gloss:gini-koeffizient" class="glossar-link">Gini-Koeffizient</a>). - [ ] Läuft in unter 60 Sekunden. - [ ] Bei Unlösbarkeit: Notfallplan plus benannte Ursache.</p>
|
||||
<p><strong>Stolperfallen.</strong> Der 28-Tage-Zyklus erzeugt viele Variablen (25 × 28 × 3 = 2100) — <a href="anhang-glossar.md#gloss:symmetriebrechung" class="glossar-link">Symmetriebrechung</a> und gute Suchheuristiken werden wichtig. Fairness über einen Monat ist etwas anderes als Fairness über eine Woche.</p>
|
||||
<hr />
|
||||
|
|
@ -231,7 +231,7 @@
|
|||
<p><strong>Schwierigkeit:</strong> ⭐⭐ · <strong>Kapitel:</strong> <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a>, <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a>, <a href="cvar.html#kap-cvar">Kapitel 20</a> · <strong>Zeit:</strong> ca. 12 Stunden</p>
|
||||
</blockquote>
|
||||
<p><strong>Ausgangslage.</strong> Für ein bestehendes Portfolio soll ein monatlicher Risikobericht entstehen.</p>
|
||||
<p><strong>Inhalte des Berichts.</strong> * <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a> und <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a> auf 95 % und 99 %, historisch <strong>und</strong> Monte-Carlo-simuliert. * Risikobeiträge je Position (<em>marginal CVaR</em>): Wer treibt das Risiko? * Stresstests: Was passiert bei −20 % Aktienmarkt, +200 Basispunkten Zins, Korrelationsanstieg auf 0,9? * Historische Szenarien nachspielen (2008, März 2020). * Konzentrationskennzahlen (<a href="anhang-glossar.md#gloss:herfindahl-index" class="glossar-link">Herfindahl-Index</a>, effektive Titelzahl).</p>
|
||||
<p><strong>Inhalte des Berichts.</strong> * <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a> und <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a> auf 95 % und 99 %, historisch <strong>und</strong> Monte-Carlo-simuliert. * Risikobeiträge je Position (<em>marginal CVaR</em>): Wer treibt das Risiko? * Stresstests: Was passiert bei −20 % Aktienmarkt, +200 Basispunkten Zins, Korrelationsanstieg auf 0,9? * Historische Szenarien nachspielen (2008, März 2020). * Konzentrationskennzahlen (<a href="anhang-glossar.md#gloss:herfindahl-index" class="glossar-link">Herfindahl-Index</a>, effektive Titelzahl).</p>
|
||||
<p><strong>Abnahmekriterien.</strong> - [ ] Bericht als PDF, automatisch erzeugt. - [ ] Alle Kennzahlen mit zwei unabhängigen Methoden berechnet und verglichen. - [ ] Klartext-Zusammenfassung: „Im schlechtesten Prozent der Monate verlieren Sie typischerweise X €.“</p>
|
||||
<p><strong>Stolperfallen.</strong> Die <a href="anhang-glossar.md#gloss:wurzel-zeit-regel" class="glossar-link">Wurzel-Zeit-Regel</a> bei CVaR (<a href="cvar.html#kap-cvar">Kapitel 20</a>) — nicht blind anwenden. Korrelationen sind in Krisen andere als im Mittel: Stresstest mit erhöhten Korrelationen rechnen.</p>
|
||||
<hr />
|
||||
|
|
@ -240,7 +240,7 @@
|
|||
<p><strong>Schwierigkeit:</strong> ⭐⭐⭐ · <strong>Kapitel:</strong> <a href="graphen.html#kap-graphen">Kapitel 8</a>, <a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a> · <strong>Zeit:</strong> ca. 18 Stunden</p>
|
||||
</blockquote>
|
||||
<p><strong>Ausgangslage.</strong> P3 hat funktioniert — mit 30 Kunden. Der Auftraggeber kommt mit 400 zurück, und derselbe Code liefert nach zwanzig Minuten noch keine Lösung. Das ist keine Panne, sondern der erwartbare Umschlagpunkt.</p>
|
||||
<p><strong>Modellskizze.</strong> Zwei Verfahren am <strong>selben</strong> Problem, verglichen unter <strong>gleichem Zeitbudget</strong>: * Exakt: <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> oder CP-SAT wie in P3, mit Zeitlimit und protokolliertem Gap. * Heuristisch: Startlösung mit einer Faustregel, dann Verbesserung durch <a href="anhang-glossar.md#gloss:simulated-annealing" class="glossar-link">Simulated Annealing</a> oder Large Neighborhood Search (<a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a>). * Messgröße ist nicht „wer gewinnt”, sondern <strong>ab welcher Instanzgröße</strong> sich das Blatt wendet.</p>
|
||||
<p><strong>Modellskizze.</strong> Zwei Verfahren am <strong>selben</strong> Problem, verglichen unter <strong>gleichem Zeitbudget</strong>: * Exakt: <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> oder CP-SAT wie in P3, mit Zeitlimit und protokolliertem Gap. * Heuristisch: Startlösung mit einer Faustregel, dann Verbesserung durch <a href="anhang-glossar.md#gloss:simulated-annealing" class="glossar-link">Simulated Annealing</a> oder Large Neighborhood Search (<a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a>). * Messgröße ist nicht „wer gewinnt”, sondern <strong>ab welcher Instanzgröße</strong> sich das Blatt wendet.</p>
|
||||
<p><strong>Abnahmekriterien.</strong> - [ ] Eine Tabelle über mindestens vier Instanzgrößen: exakt gegen heuristisch, jeweils Zielwert und Laufzeit. - [ ] Der Umschlagpunkt ist auf ±50 Kunden eingegrenzt und <strong>benannt</strong>. - [ ] Bei kleinen Instanzen wird gegen die bewiesen optimale Lösung geprüft — sonst weiß niemand, wie gut die Heuristik wirklich ist. - [ ] Fester Seed, reproduzierbarer Lauf; das Zugbudget ist fix, nicht die Uhrzeit.</p>
|
||||
<blockquote>
|
||||
<p>⚠️ <strong>Die Falle, in die hier fast jeder tappt:</strong> die Heuristik nur auf großen Instanzen zu testen, wo man das Optimum nicht kennt. Dann sieht jede Lösung gut aus.</p>
|
||||
|
|
@ -307,7 +307,7 @@
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Speiseplan unter Nährwert- und Budgetgrenzen</td>
|
||||
<td><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a></td>
|
||||
<td><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a></td>
|
||||
<td><a href="lp.html#kap-lp">Kapitel 5</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
|
|||
10
OR_HTML_04/qp-nlp.html
generated
10
OR_HTML_04/qp-nlp.html
generated
|
|
@ -118,7 +118,7 @@
|
|||
<p><strong>📌 Kapitel auf einen Blick</strong></p>
|
||||
<p><strong>Worum geht es?</strong> Risiko ist quadratisch. Sobald Varianz ins Spiel kommt, verlässt man die Welt der <a href="anhang-glossar.md#gloss:polyeder" class="glossar-link">Polyeder</a>. Dieses Kapitel liefert das mathematische Fundament für die gesamte Portfoliooptimierung in <a href="bruecke.html#teil-anwendungen">Teil IV</a>.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="fundament.html#kap-fundament">Kapitel 2</a> (Konvexität, Eigenwerte), <a href="lp.html#kap-lp">Kapitel 5</a> (Dualität, Schattenpreise). Gradienten werden in <a href="#sec:qp-nlp-lernziele">Abschnitt 11.2</a> wiederholt.</p>
|
||||
<p><strong>Danach können Sie:</strong> Ein quadratisches Programm aufstellen, die <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a>-Bedingungen anwenden, den Zusammenhang zwischen <a href="anhang-glossar.md#gloss:lagrange-multiplikator" class="glossar-link">Lagrange-Multiplikator</a> und <a href="anhang-glossar.md#gloss:schattenpreis" class="glossar-link">Schattenpreis</a> erklären, eine gültige <a href="anhang-glossar.md#gloss:kovarianzmatrix" class="glossar-link">Kovarianzmatrix</a> konstruieren — und mit nicht-konvexen Problemen umgehen, ohne ein lokales Optimum für das Optimum zu halten.</p>
|
||||
<p><strong>Danach können Sie:</strong> Ein quadratisches Programm aufstellen, die <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a>-Bedingungen anwenden, den Zusammenhang zwischen <a href="anhang-glossar.md#gloss:lagrange-multiplikator" class="glossar-link">Lagrange-Multiplikator</a> und <a href="anhang-glossar.md#gloss:schattenpreis" class="glossar-link">Schattenpreis</a> erklären, eine gültige <a href="anhang-glossar.md#gloss:kovarianzmatrix" class="glossar-link">Kovarianzmatrix</a> konstruieren — und mit nicht-konvexen Problemen umgehen, ohne ein lokales Optimum für das Optimum zu halten.</p>
|
||||
<p><strong>Zeitbedarf:</strong> ca. 6,5 Stunden.</p>
|
||||
<p><strong>Programme:</strong><br />
|
||||
<code>QP_Grundlagen.py</code><br />
|
||||
|
|
@ -217,7 +217,7 @@ Risiko der Mischung: 8.90 %</code></pre>
|
|||
<h2 id="sec:qp-nlp-lernziele">11.2 Lernziele</h2>
|
||||
<p>Nach diesem Kapitel können Sie …</p>
|
||||
<ol type="1">
|
||||
<li>… ein <strong>quadratisches Programm (<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a>)</strong> aufstellen und von einem allgemeinen nichtlinearen Programm abgrenzen.</li>
|
||||
<li>… ein <strong>quadratisches Programm (<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a>)</strong> aufstellen und von einem allgemeinen nichtlinearen Programm abgrenzen.</li>
|
||||
<li>… die <strong>KKT-Bedingungen</strong> herleiten und auf ein Optimierungsproblem anwenden.</li>
|
||||
<li>… den Zusammenhang zwischen <strong>Lagrange-Multiplikator</strong> und <strong>Schattenpreis</strong> erklären.</li>
|
||||
<li>… zwischen <strong>konvex</strong> und <strong>streng konvex</strong> unterscheiden und eine gültige, positiv semidefinite <strong>Kovarianzmatrix</strong> konstruieren.</li>
|
||||
|
|
@ -458,7 +458,7 @@ DCP-konvex (CVXPY-Pruefung)? False
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td><span class="math inline">\lambda_i^*</span> selbst</td>
|
||||
<td>Der <strong>Schattenpreis</strong> von Bedingung <span class="math inline">i</span> — dieselbe Größe wie im <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a> (<a href="lp.html#kap-lp">Kapitel 5</a>), nur für krumme Ränder.</td>
|
||||
<td>Der <strong>Schattenpreis</strong> von Bedingung <span class="math inline">i</span> — dieselbe Größe wie im <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a> (<a href="lp.html#kap-lp">Kapitel 5</a>), nur für krumme Ränder.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -1164,7 +1164,7 @@ Drei Konsequenzen fuer die Praxis:
|
|||
<tbody>
|
||||
<tr class="odd">
|
||||
<td><strong>Ipopt</strong> (über <code>cyipopt</code> oder <a href="anhang-glossar.md#gloss:pyomo" class="glossar-link">Pyomo</a>)</td>
|
||||
<td>lokaler <a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP</a>-Solver</td>
|
||||
<td>lokaler <a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP (Nichtlineare Programmierung)</a>-Solver</td>
|
||||
<td>Innere-Punkte-Verfahren für große, glatte NLPs mit tausenden Variablen — deutlich leistungsfähiger als <code>scipy</code>, aber ebenfalls <strong>nur lokal</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
@ -1234,7 +1234,7 @@ Drei Konsequenzen fuer die Praxis:
|
|||
</ul>
|
||||
<p>Alle drei schwanken mit 20 %. Leerverkäufe sind in seinem Mandat erlaubt, die Gewichte dürfen also negativ werden; sie müssen sich nur zu 100 % summieren.</p>
|
||||
<p>Sein erster Versuch mit CVXPY bricht ab:</p>
|
||||
<pre><code>[DCPError](anhang-glossar.md#gloss:dcperror){.glossar-link}: Problem does not follow [DCP](anhang-glossar.md#gloss:dcp-disciplined-convex-programming){.glossar-link} rules.
|
||||
<pre><code>[DCPError](anhang-glossar.md#gloss:dcperror){.glossar-link}: Problem does not follow [DCP (Disciplined Convex Programming)](anhang-glossar.md#gloss:dcp-disciplined-convex-programming){.glossar-link} rules.
|
||||
The objective is not DCP. Its following subexpressions are not: QuadForm(...)</code></pre>
|
||||
<p>Er hält das für eine Einschränkung der Bibliothek und weicht auf <code>scipy</code> aus:</p>
|
||||
<div class="sourceCode" id="cb13"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> numpy <span class="im">as</span> np</span>
|
||||
|
|
|
|||
4
OR_HTML_04/supplychain.html
generated
4
OR_HTML_04/supplychain.html
generated
|
|
@ -152,7 +152,7 @@ Umschlagpunkt: 3.9 Stunden</code></pre>
|
|||
<p><strong>Und jetzt der Punkt.</strong> Bis knapp vier Stunden ist die <em>fünfmal teurere</em> Gasturbine die günstigere Wahl. Erst danach hat der Kernblock seine Anfahrkosten wieder eingespielt.</p>
|
||||
<p>Die Merit-Order — Kraftwerke nach Grenzkosten sortieren und von unten auffüllen — ist damit nur für einen <strong>einzelnen</strong> Zeitpunkt richtig. Sobald ein Tag geplant wird, hängt jede Stunde an allen anderen: Ein Block, der um 8 Uhr angefahren wird, muss bis mindestens 16 Uhr laufen, und diese Entscheidung fällt am Vorabend.</p>
|
||||
<blockquote>
|
||||
<p><strong>🎯 Merksatz</strong> Anfahrkosten und Mindestlaufzeiten machen aus 24 unabhängigen Stundenentscheidungen <strong>ein</strong> Problem. Genau deshalb ist die Kraftwerkseinsatzplanung ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> und keine Sortierung.</p>
|
||||
<p><strong>🎯 Merksatz</strong> Anfahrkosten und Mindestlaufzeiten machen aus 24 unabhängigen Stundenentscheidungen <strong>ein</strong> Problem. Genau deshalb ist die Kraftwerkseinsatzplanung ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> und keine Sortierung.</p>
|
||||
</blockquote>
|
||||
<p><strong>Warum funktioniert das?</strong> Der Umschlagpunkt ist eine einfache Rechnung: Die Anfahrkostendifferenz (38 500 €) geteilt durch die Grenzkostendifferenz je Stunde (83 €/MWh × 120 MW = 9 960 €/h) ergibt 3,9 Stunden. Bei zwei Kraftwerken kann man das im Kopf ausrechnen — bei fünf Blöcken und 24 Stunden nicht mehr.</p>
|
||||
<hr />
|
||||
|
|
@ -162,7 +162,7 @@ Umschlagpunkt: 3.9 Stunden</code></pre>
|
|||
<li>… ein Unit-Commitment-Modell mit Anfahrkosten und Mindestlaufzeiten aufstellen.</li>
|
||||
<li>… erklären, warum eine <strong>binäre erste Stufe</strong> das zweistufige Modell aus <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a> verschärft.</li>
|
||||
<li>… zeigen, dass eine Planung auf den Erwartungswert nicht nur ungenau, sondern <strong>systematisch zu knapp</strong> ist.</li>
|
||||
<li>… eine <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a>-Schranke auf eine physikalische Größe (nicht gedeckte Energie) legen.</li>
|
||||
<li>… eine <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a>-Schranke auf eine physikalische Größe (nicht gedeckte Energie) legen.</li>
|
||||
<li>… begründen, wann eine Risikoschranke etwas ändert — und wann sie überflüssig ist.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
|
|
|
|||
4
OR_HTML_04/synthese-anwendungen.html
generated
4
OR_HTML_04/synthese-anwendungen.html
generated
|
|
@ -175,8 +175,8 @@
|
|||
<td><a href="supplychain.html#kap-supplychain">Kapitel 17</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>„Der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a> sagt, wie riskant es ist.”</td>
|
||||
<td>VaR <strong>1,86 %</strong>, <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a> <strong>2,99 %</strong> — und der schlechteste Tag der Stichprobe (<strong>−23,0 %</strong>) ändert am VaR <strong>nichts</strong></td>
|
||||
<td>„Der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a> sagt, wie riskant es ist.”</td>
|
||||
<td>VaR <strong>1,86 %</strong>, <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a> <strong>2,99 %</strong> — und der schlechteste Tag der Stichprobe (<strong>−23,0 %</strong>) ändert am VaR <strong>nichts</strong></td>
|
||||
<td><a href="cvar.html#kap-cvar">Kapitel 20</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
|
|||
8
OR_HTML_04/synthese-kernverfahren.html
generated
8
OR_HTML_04/synthese-kernverfahren.html
generated
|
|
@ -121,14 +121,14 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a></strong></td>
|
||||
<td>teilbare Mengen, lineare Zusammenhänge</td>
|
||||
<td>beweisbares Optimum <strong>plus Schattenpreise</strong></td>
|
||||
<td>sobald etwas ganzzahlig sein muss</td>
|
||||
<td><a href="lp.html#kap-lp">Kapitel 5</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong><a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a></strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a></strong></td>
|
||||
<td>Ja/Nein-Entscheidungen, Fixkosten, Logik</td>
|
||||
<td>beweisbares Optimum, Gap als Fortschrittsmaß</td>
|
||||
<td>Laufzeit wächst mit der Zahl der Binärvariablen</td>
|
||||
|
|
@ -182,12 +182,12 @@
|
|||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>„Der exakte Solver ist immer besser.”</td>
|
||||
<td>Bei 500 Aufträgen liefert <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> eine Lösung, die <strong>5,2 % schlechter</strong> ist als die Faustregel eines Meisters</td>
|
||||
<td>Bei 500 Aufträgen liefert <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> eine Lösung, die <strong>5,2 % schlechter</strong> ist als die Faustregel eines Meisters</td>
|
||||
<td><a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>„Metaheuristiken sind ungenau.”</td>
|
||||
<td>Faustregel 2 497 → Annealing 2 343 → Annealing plus <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS</a> <strong>2 289</strong> Minuten <a href="anhang-glossar.md#gloss:ruestzeit" class="glossar-link">Rüstzeit</a>; untere Schranke 1 768</td>
|
||||
<td>Faustregel 2 497 → Annealing 2 343 → Annealing plus <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS (Large Neighborhood Search)</a> <strong>2 289</strong> Minuten <a href="anhang-glossar.md#gloss:ruestzeit" class="glossar-link">Rüstzeit</a>; untere Schranke 1 768</td>
|
||||
<td><a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
|
|
|
|||
2
OR_HTML_04/synthese-nichtlinear.html
generated
2
OR_HTML_04/synthese-nichtlinear.html
generated
|
|
@ -121,7 +121,7 @@
|
|||
<tr class="odd">
|
||||
<td><strong>Linearität</strong></td>
|
||||
<td>Risiko wächst quadratisch, Kosten degressiv, Sättigung</td>
|
||||
<td><a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a>, konvexe Optimierung, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a></td>
|
||||
<td><a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a>, konvexe Optimierung, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a></td>
|
||||
<td><a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
|
|||
8
OR_HTML_04/testing.html
generated
8
OR_HTML_04/testing.html
generated
|
|
@ -145,7 +145,7 @@
|
|||
AssertionError: Plan [31. 48.] braucht [141. 234.], verfuegbar sind [140. 232.]</code></pre>
|
||||
</blockquote>
|
||||
</div>
|
||||
<p><strong>Und jetzt der Punkt.</strong> Der Solver hat richtig gerechnet: 30,67 Tische und 48 Stühle sind das Optimum des <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>. Das Runden hat den Plan kaputt gemacht — 31 Tische brauchen eine Montagestunde mehr, als es gibt. Ohne die drei Zeilen wäre dieser Plan in die Fertigung gegangen, und dort hätte am Monatsende eine Stunde gefehlt, die niemand einer Zeile Python zugeordnet hätte.</p>
|
||||
<p><strong>Und jetzt der Punkt.</strong> Der Solver hat richtig gerechnet: 30,67 Tische und 48 Stühle sind das Optimum des <a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>. Das Runden hat den Plan kaputt gemacht — 31 Tische brauchen eine Montagestunde mehr, als es gibt. Ohne die drei Zeilen wäre dieser Plan in die Fertigung gegangen, und dort hätte am Monatsende eine Stunde gefehlt, die niemand einer Zeile Python zugeordnet hätte.</p>
|
||||
<p>Bemerkenswert ist, <strong>was</strong> der Test prüft. Er prüft nicht, ob 30,67 das Optimum ist — das könnte er gar nicht, dafür bräuchte er einen zweiten Solver. Er prüft die Eigenschaft, die jede brauchbare Lösung haben muss: <em>Sie hält die Kapazität ein.</em> Diese Verschiebung — <strong>von der Frage nach dem richtigen Wert zur Frage nach den notwendigen Eigenschaften</strong> — ist der Schlüssel zum ganzen Kapitel.</p>
|
||||
<blockquote>
|
||||
<p><strong>🎯 Merksatz</strong> Ein Optimierungsmodell lässt sich fast nie gegen den richtigen Wert testen. Gegen seine Eigenschaften lässt es sich immer testen.</p>
|
||||
|
|
@ -1131,7 +1131,7 @@ NICHT ablesen darf man:
|
|||
<p>Die zweite unbequeme Zahl steht ganz rechts: <strong><a href="anhang-glossar.md#gloss:cvxpy" class="glossar-link">CVXPY</a> braucht rund 240 MB</strong>, unabhängig von der Problemgröße — das ist der Preis seiner Modellierungsschicht. Auf einem Rechner mit knappem Speicher entscheidet diese Spalte und nicht die Laufzeit darüber, was überhaupt läuft.</p>
|
||||
<blockquote>
|
||||
<p><strong>⚠️ Was diese Tabelle nicht sagt</strong></p>
|
||||
<p>Sie sagt <strong>nicht</strong> „ortools ist langsamer als scipy”. Gemessen wurde <em>ein</em> Problemtyp in <em>einer</em> Formulierung auf <em>einer</em> Maschine. Ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> statt eines LP, eine andere Modellierung desselben Problems oder ein anderer Rechner können die Reihenfolge umdrehen — und bei MILPs tun sie es regelmäßig.</p>
|
||||
<p>Sie sagt <strong>nicht</strong> „ortools ist langsamer als scipy”. Gemessen wurde <em>ein</em> Problemtyp in <em>einer</em> Formulierung auf <em>einer</em> Maschine. Ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> statt eines LP, eine andere Modellierung desselben Problems oder ein anderer Rechner können die Reihenfolge umdrehen — und bei MILPs tun sie es regelmäßig.</p>
|
||||
<p>Übertragbar ist der <strong>Trend</strong>, nicht der Absolutwert: dass der Aufbauanteil mit der Größe wächst, dass CVXPY einen konstanten Speichersockel hat. Der Zweck des Programms ist, dass Sie es auf Ihrer Maschine mit Ihrem Problem laufen lassen.</p>
|
||||
</blockquote>
|
||||
<hr />
|
||||
|
|
@ -1561,11 +1561,11 @@ Das zugehoerige Dockerfile ist kurz genug, um es ganz zu zeigen:
|
|||
<blockquote>
|
||||
<p><strong>💻 Code-Durchgang: drei Entscheidungen</strong></p>
|
||||
<p><strong>1. Das Domänenmodell ist das API-Schema.</strong> Der <a href="anhang-glossar.md#gloss:parameter" class="glossar-link">Parameter</a> heißt <code>problem: Produktionsproblem</code> — mehr steht nicht da. FastAPI validiert die Anfrage damit gegen dieselben Pydantic-Regeln wie der Excel-Import aus <a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> und antwortet bei Unsinn mit <code>422</code>, <strong>bevor</strong> ein Solver startet. Die drei abgewiesenen Anfragen im Selbsttest sind genau die drei Fälle, die <code>or_kern.py</code> schon beim Einlesen abfängt.</p>
|
||||
<p><strong>2. Die Antwort enthält Status und Gap, nicht nur Zahlen.</strong> Ein Aufrufer, der nur die Mengen bekommt, kann nicht unterscheiden, ob er ein bewiesenes Optimum oder einen Zeitlimit-Abbruch in der Hand hält. Das <code>Loesung</code>-Objekt geht deshalb vollständig durch die Schnittstelle — dasselbe <a href="anhang-glossar.md#gloss:dto-data-transfer-object" class="glossar-link">DTO</a>, das in <a href="praxisfallen.html#sec:praxisfallen-solverwechsel">Abschnitt 22.7</a> schon eine Prozessgrenze überlebt hat.</p>
|
||||
<p><strong>2. Die Antwort enthält Status und Gap, nicht nur Zahlen.</strong> Ein Aufrufer, der nur die Mengen bekommt, kann nicht unterscheiden, ob er ein bewiesenes Optimum oder einen Zeitlimit-Abbruch in der Hand hält. Das <code>Loesung</code>-Objekt geht deshalb vollständig durch die Schnittstelle — dasselbe <a href="anhang-glossar.md#gloss:dto-data-transfer-object" class="glossar-link">DTO (Data Transfer Object)</a>, das in <a href="praxisfallen.html#sec:praxisfallen-solverwechsel">Abschnitt 22.7</a> schon eine Prozessgrenze überlebt hat.</p>
|
||||
<p><strong>3. Die Abnahmeprüfung läuft auch hier.</strong> <code>pruefe_loesung()</code> steht im Arbeiter, nicht nur im Skript. Ein Dienst ohne sie liefert Fehler schneller aus, als ein Mensch sie finden könnte.</p>
|
||||
</blockquote>
|
||||
<h3 id="threads-oder-prozesse-eine-messung-keine-meinung">Threads oder Prozesse? Eine Messung, keine Meinung</h3>
|
||||
<p>Punkt 6 des Selbsttests misst, ob vier Solverläufe in Threads sich überlappen. Das Ergebnis ist ein Faktor von rund 3,5 bei vier Threads: <strong>OR-Tools rechnet in C++ und gibt den <a href="anhang-glossar.md#gloss:gil-global-interpreter-lock" class="glossar-link">GIL</a> während <code>Solve()</code> frei.</strong> Ein Threadpool genügt also, es braucht keine eigenen Prozesse.</p>
|
||||
<p>Punkt 6 des Selbsttests misst, ob vier Solverläufe in Threads sich überlappen. Das Ergebnis ist ein Faktor von rund 3,5 bei vier Threads: <strong>OR-Tools rechnet in C++ und gibt den <a href="anhang-glossar.md#gloss:gil-global-interpreter-lock" class="glossar-link">GIL (Global Interpreter Lock)</a> während <code>Solve()</code> frei.</strong> Ein Threadpool genügt also, es braucht keine eigenen Prozesse.</p>
|
||||
<p>Das gilt aber nicht allgemein. Eine in reinem Python geschriebene Heuristik (<a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a>) hält den GIL die ganze Zeit — für sie braucht derselbe Dienst einen <code>ProcessPoolExecutor</code>. Die Entscheidung gehört gemessen, nicht angenommen.</p>
|
||||
<blockquote>
|
||||
<p><strong>⚠️ Der erste Entwurf dieser Messung war falsch</strong></p>
|
||||
|
|
|
|||
6
OR_HTML_04/unsicherheit.html
generated
6
OR_HTML_04/unsicherheit.html
generated
|
|
@ -719,7 +719,7 @@ den Mittelwert (225), weil Unterdeckung (120 EUR)
|
|||
deutlich teurer ist als Leerlauf (5 EUR).
|
||||
==================================================================================</code></pre>
|
||||
<p><strong>Lesen Sie die Vergleichstabelle von unten nach oben.</strong> Die beiden extremen Haltungen sind die teuersten: Wer den Worst Case abdeckt (500 Einheiten), zahlt 5 000 € zu viel für Kapazität, die in 80 % der Fälle brachliegt. Wer optimistisch plant (100), zahlt 2 625 € Strafe für ständige Notzukäufe. Die naive Mittelwertplanung liegt dazwischen — aber eben auch nicht optimal.</p>
|
||||
<p>Der <strong><a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI</a> von 7 375 €</strong> ist bemerkenswert hoch: 45 % der Gesamtkosten entstehen allein daraus, dass man die Zukunft nicht kennt. In so einem Fall lohnt sich Investition in bessere Prognosen tatsächlich — anders als in dem Beispiel aus der Aufgabe <em>EVPI interpretieren</em> (<a href="#sec:unsicherheit-uebungsaufgaben">Abschnitt 12.8</a>).</p>
|
||||
<p>Der <strong><a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI (Expected Value of Perfect Information)</a> von 7 375 €</strong> ist bemerkenswert hoch: 45 % der Gesamtkosten entstehen allein daraus, dass man die Zukunft nicht kennt. In so einem Fall lohnt sich Investition in bessere Prognosen tatsächlich — anders als in dem Beispiel aus der Aufgabe <em>EVPI interpretieren</em> (<a href="#sec:unsicherheit-uebungsaufgaben">Abschnitt 12.8</a>).</p>
|
||||
<blockquote>
|
||||
<p><strong>💡 Was ist der EVPI?</strong> Der <strong>Expected Value of Perfect Information</strong> beziffert, wie viel eine perfekte Prognose wert wäre: die Differenz zwischen den Kosten unter Unsicherheit und den Kosten bei vollständigem Wissen. Er ist eine <strong>Obergrenze für jedes Prognoseprojekt</strong>. Wenn der EVPI bei 12 000 € pro Jahr liegt, lohnt sich keine Prognosesoftware für 50 000 € — selbst wenn sie perfekt wäre. Diese Zahl bewahrt Projekte vor teuren Fehlinvestitionen.</p>
|
||||
</blockquote>
|
||||
|
|
@ -876,7 +876,7 @@ z_{1-\alpha} = \Phi^{-1}(1-\alpha)
|
|||
z_s &\in \{0,1\}
|
||||
\end{aligned}
|
||||
</span></p>
|
||||
<p>Aus dem Kegelproblem wird ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP</a> mit <span class="math inline">S</span> Binärvariablen. Für <span class="math inline">M</span> gilt, was <a href="milp.html#kap-milp">Kapitel 6</a> über die Big-M-Falle sagt: <strong>so klein wie möglich</strong>. Hier ist <span class="math inline">M = b</span> die kleinste gültige Schranke, denn <span class="math inline">\mathbf{a}_s^\top\mathbf{x} \ge 0</span> — größer kann eine Verletzung gar nicht ausfallen.</p>
|
||||
<p>Aus dem Kegelproblem wird ein <a href="anhang-glossar.md#gloss:gemischt-ganzzahlige-optimierung-milp" class="glossar-link">MILP (Gemischt-ganzzahlige Optimierung)</a> mit <span class="math inline">S</span> Binärvariablen. Für <span class="math inline">M</span> gilt, was <a href="milp.html#kap-milp">Kapitel 6</a> über die Big-M-Falle sagt: <strong>so klein wie möglich</strong>. Hier ist <span class="math inline">M = b</span> die kleinste gültige Schranke, denn <span class="math inline">\mathbf{a}_s^\top\mathbf{x} \ge 0</span> — größer kann eine Verletzung gar nicht ausfallen.</p>
|
||||
<h3 id="der-fall-ein-kraftwerkspark-mit-500-mw-zusage">Der Fall: ein Kraftwerkspark mit 500 MW Zusage</h3>
|
||||
<div class="sourceCode" id="cb10"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/usr/bin/env python3</span></span>
|
||||
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
|
|
@ -1191,7 +1191,7 @@ Szenarien, 95 % 43,760,709 350 0 0 350 100.00 % 94.84 %
|
|||
<p><strong>Aufgabe 12.2 ⭐ — Ansatz wählen.</strong> 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?</p>
|
||||
<p><strong>Aufgabe 12.3 ⭐⭐ — Zweistufiges Modell rechnen.</strong> Wiederholen Sie die Handrechnung <em>Warum der Mittelwert in die Irre führt</em> mit geänderten Kosten: Spot 60 € statt 120 €. (a) Wie ändert sich die optimale Kapazität? (b) Erklären Sie die Richtung der Änderung. (c) Bei welchem Spot-Preis wäre die Mittelwert-Planung optimal?</p>
|
||||
<p><strong>Aufgabe 12.4 ⭐⭐ — EVPI interpretieren.</strong> Ihr Modell liefert EVPI = 8 400 € pro Jahr. Ein Anbieter verlangt 15 000 € jährlich für eine Prognoselösung, die „80 % Treffsicherheit“ verspricht. Wie argumentieren Sie?</p>
|
||||
<p><strong>Aufgabe 12.5 ⭐⭐⭐ — Monte-Carlo erweitern.</strong> Erweitern Sie <code>Monte_Carlo.py</code>: (a) Fügen Sie ein Servicelevel-Kriterium hinzu: „Die Unterdeckung darf höchstens in 5 % der Fälle auftreten.“ Welche Kapazität ist dafür nötig, und was kostet sie zusätzlich? (b) Berechnen Sie den <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a> der Kosten (Mittelwert der schlechtesten 5 %). (c) Zeichnen Sie ein Histogramm der Kosten für drei Kapazitäten.</p>
|
||||
<p><strong>Aufgabe 12.5 ⭐⭐⭐ — Monte-Carlo erweitern.</strong> Erweitern Sie <code>Monte_Carlo.py</code>: (a) Fügen Sie ein Servicelevel-Kriterium hinzu: „Die Unterdeckung darf höchstens in 5 % der Fälle auftreten.“ Welche Kapazität ist dafür nötig, und was kostet sie zusätzlich? (b) Berechnen Sie den <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a> der Kosten (Mittelwert der schlechtesten 5 %). (c) Zeichnen Sie ein Histogramm der Kosten für drei Kapazitäten.</p>
|
||||
<p><strong>Aufgabe 12.6 ⭐⭐ — Den Preis der Zusage selbst bestimmen.</strong> <code>Chance_Constraints.py</code> 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 <strong>szenariobasierte</strong> Modell meldet dann bei 95 % <code>infeasible</code>, das <strong>analytische</strong> dagegen <code>optimal</code>. 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.</p>
|
||||
<p><strong>Aufgabe 12.7 ⭐⭐⭐ — Budgeted Uncertainty.</strong> Erweitern Sie <code>Robuste_Optimierung.py</code> um den Ansatz von Bertsimas/Sim: Höchstens <span class="math inline">\Gamma</span> Titel nehmen gleichzeitig ihren Worst Case an. Variieren Sie <span class="math inline">\Gamma \in \{0, 1, 2, 3, 4\}</span> und stellen Sie den Verlauf von Ertrag und Absicherung dar. (Hinweis: Bei <span class="math inline">\Gamma</span> ganzzahlig genügt es, die <span class="math inline">\Gamma</span> größten <span class="math inline">\delta_i w_i</span> abzuziehen — das lässt sich in CVXPY mit <code>cp.sum_largest</code> formulieren.)</p>
|
||||
<hr />
|
||||
|
|
|
|||
20
OR_HTML_04/vorwort.html
generated
20
OR_HTML_04/vorwort.html
generated
|
|
@ -110,7 +110,7 @@
|
|||
<p>Mit Python planen, optimieren und entscheiden: von <strong>Personal, Schichten und Logistik</strong> über <strong>Energie, Ressourcen und Netzwerke</strong> bis zur <strong>Portfoliooptimierung an den Finanzmärkten</strong>.</p>
|
||||
<p>Autor / Herausgeber: Dieter Schlüter</p>
|
||||
<p><dieter(dot)schlueter(atsign)linix(dot)de></p>
|
||||
<p>Stand: 10. September 2026 v17.39</p>
|
||||
<p>Stand: 10. September 2026 v17.52</p>
|
||||
<hr />
|
||||
<h1 class="unnumbered" id="über-den-kurs">Über den Kurs</h1>
|
||||
<h2 class="unnumbered" id="vorwort">Vorwort</h2>
|
||||
|
|
@ -369,7 +369,7 @@ Alles bereit — Sie können mit dem ersten Kapitel beginnen.</code></pre>
|
|||
<p><strong>Ihr Weg.</strong> Zuerst Pfad E (2–4 Stunden): <a href="einfuehrung.html#sec:einfuehrung-historischer-kontext-und-evolution">Abschnitt 1.5</a> und <a href="anhang-modellierungsmuster.html#anhang-modellierungsmuster">Anhang B</a>. Wenn Sie danach wissen wollen, was in Ihrem Betrieb geht, Pfad B und Projekt <strong>P1</strong> oder <strong>P2</strong>.</p>
|
||||
<p><strong>Woran es scheitert.</strong> Nicht am Modell, sondern an der Einführung — das ist der meistgenannte Befund in <a href="praxisfallen.html#kap-praxisfallen">Kapitel 22</a>. Und an einer Verwechslung, die dieses Buch Ihnen nicht abnehmen kann: Ein Bericht erklärt das <strong>Modell</strong>, nicht die <strong>Wirklichkeit</strong>. Ist ein Deckungsbeitrag falsch geschätzt, ist er überzeugend <strong>und</strong> falsch. Fragen Sie deshalb jedes Mal, worauf eine Zahl beruht.</p>
|
||||
<blockquote>
|
||||
<p><strong>Eine Erwartung, die dieses Buch enttäuscht:</strong> Es nennt keine ROI-Kennzahl und keine Amortisationsdauer. Beide hängen an Ihrem Betrieb, und jede Zahl hier wäre erfunden. Was es stattdessen liefert, ist das Werkzeug, Ihre eigene auszurechnen: den <strong><a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI</a></strong> in <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a> (was eine perfekte Prognose überhaupt wert wäre — eine Obergrenze für jedes Prognoseprojekt) und die Kostenzurechnung aus <a href="praxisfallen.html#sec:praxisfallen-attribution">Abschnitt 22.4</a>.</p>
|
||||
<p><strong>Eine Erwartung, die dieses Buch enttäuscht:</strong> Es nennt keine ROI-Kennzahl und keine Amortisationsdauer. Beide hängen an Ihrem Betrieb, und jede Zahl hier wäre erfunden. Was es stattdessen liefert, ist das Werkzeug, Ihre eigene auszurechnen: den <strong><a href="anhang-glossar.md#gloss:evpi-expected-value-of-perfect-information" class="glossar-link">EVPI (Expected Value of Perfect Information)</a></strong> in <a href="unsicherheit.html#kap-unsicherheit">Kapitel 12</a> (was eine perfekte Prognose überhaupt wert wäre — eine Obergrenze für jedes Prognoseprojekt) und die Kostenzurechnung aus <a href="praxisfallen.html#sec:praxisfallen-attribution">Abschnitt 22.4</a>.</p>
|
||||
</blockquote>
|
||||
<h3 class="unnumbered" id="für-ingenieure-und-produktionsplaner-die-physik-des-systems">Für Ingenieure und Produktionsplaner — die Physik des Systems</h3>
|
||||
<blockquote>
|
||||
|
|
@ -377,7 +377,7 @@ Alles bereit — Sie können mit dem ersten Kapitel beginnen.</code></pre>
|
|||
</blockquote>
|
||||
<ul>
|
||||
<li><strong>Der Engpass lässt sich benennen und bepreisen.</strong> <a href="praxisfallen.html#sec:praxisfallen-attribution">Abschnitt 22.4</a> rechnet für jede Kapazität aus, was die nächste Stunde wert ist — und wie weit dieser Wert trägt. Im Beispiel gilt der <a href="anhang-glossar.md#gloss:schattenpreis" class="glossar-link">Schattenpreis</a> der Lackiererei exakt bis <strong>+15 Stunden</strong>; eine ganze Sonderschicht von 30 Stunden bringt deshalb 60 € statt der rechnerischen 120 €. <strong>Die zweite Hälfte wäre bezahlt und wirkungslos.</strong></li>
|
||||
<li><strong>Rüstzeiten, Reihenfolgen, Taktzeiten sind der Kern, nicht die Ausnahme.</strong> <a href="cpsat.html#kap-cpsat">Kapitel 7</a> modelliert Maschinenbelegung mit Intervallvariablen, <a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a> zeigt am selben Fall das Gesamtbild: Faustregel 2 497 Minuten <a href="anhang-glossar.md#gloss:ruestzeit" class="glossar-link">Rüstzeit</a>, <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> allein 2 628, <a href="anhang-glossar.md#gloss:simulated-annealing" class="glossar-link">Simulated Annealing</a> 2 343, Annealing plus <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS</a> <strong>2 289</strong> — und die untere Schranke bei 1 768, damit sichtbar bleibt, wie viel Luft noch da ist.</li>
|
||||
<li><strong>Rüstzeiten, Reihenfolgen, Taktzeiten sind der Kern, nicht die Ausnahme.</strong> <a href="cpsat.html#kap-cpsat">Kapitel 7</a> modelliert Maschinenbelegung mit Intervallvariablen, <a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a> zeigt am selben Fall das Gesamtbild: Faustregel 2 497 Minuten <a href="anhang-glossar.md#gloss:ruestzeit" class="glossar-link">Rüstzeit</a>, <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP (Constraint Programming)</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT (Boolean Satisfiability)</a> allein 2 628, <a href="anhang-glossar.md#gloss:simulated-annealing" class="glossar-link">Simulated Annealing</a> 2 343, Annealing plus <a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS (Large Neighborhood Search)</a> <strong>2 289</strong> — und die untere Schranke bei 1 768, damit sichtbar bleibt, wie viel Luft noch da ist.</li>
|
||||
<li><strong>Wenn der Solver zu lange braucht, gibt es Zahlen statt Ratschläge.</strong> <a href="cpsat.html#sec:cpsat-parallele-suche">Abschnitt 7.7</a> misst, was mehrere Suchstränge bringen (hier Faktor 12,3) — und ab wo mehr Arbeiter wieder schaden.</li>
|
||||
</ul>
|
||||
<p><strong>Ihr Weg.</strong> Pfad B bis <a href="cpsat.html#kap-cpsat">Kapitel 7</a>, dann Projekt <strong>P5</strong> (Produktionsplanung mit Rüstkosten). Wenn Ihre echten Instanzen den Solver stehen lassen: <a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a> und Projekt <strong>P9</strong>.</p>
|
||||
|
|
@ -388,7 +388,7 @@ Alles bereit — Sie können mit dem ersten Kapitel beginnen.</code></pre>
|
|||
</blockquote>
|
||||
<ul>
|
||||
<li><strong>Der Grund dafür steht in <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a>, nicht in <a href="markowitz.html#kap-markowitz">Kapitel 19</a>.</strong> Eine aus kurzen Zeitreihen geschätzte <a href="anhang-glossar.md#gloss:kovarianzmatrix" class="glossar-link">Kovarianzmatrix</a> ist schlecht konditioniert; der Optimierer setzt dann auf Schätzrauschen. Shrinkage nach Ledoit-Wolf ist das Gegenmittel; ihre Wirkung wird an <strong>Eigenwertspektrum und <a href="anhang-glossar.md#gloss:konditionszahl" class="glossar-link">Konditionszahl</a></strong> gemessen, nicht behauptet.</li>
|
||||
<li><strong>Der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR</a> verschweigt genau das, worauf es ankommt.</strong> In der Stichprobe aus <a href="cvar.html#kap-cvar">Kapitel 20</a> sagt der VaR: „an 95 % der Tage höchstens <strong>1,86 %</strong> Verlust“. Der <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR</a> sagt: „und wenn doch, dann im Mittel <strong>2,99 %</strong>“. Der schlechteste Tag der Stichprobe liegt bei <strong>−23,0 %</strong> — am VaR ändert dieser eine Tag <strong>nichts</strong>, am CVaR sehr wohl. Deshalb ist der CVaR die Größe, die man optimiert.</li>
|
||||
<li><strong>Der <a href="anhang-glossar.md#gloss:value-at-risk-var" class="glossar-link">VaR (Value at Risk)</a> verschweigt genau das, worauf es ankommt.</strong> In der Stichprobe aus <a href="cvar.html#kap-cvar">Kapitel 20</a> sagt der VaR: „an 95 % der Tage höchstens <strong>1,86 %</strong> Verlust“. Der <a href="anhang-glossar.md#gloss:conditional-value-at-risk-cvar" class="glossar-link">CVaR (Conditional Value at Risk)</a> sagt: „und wenn doch, dann im Mittel <strong>2,99 %</strong>“. Der schlechteste Tag der Stichprobe liegt bei <strong>−23,0 %</strong> — am VaR ändert dieser eine Tag <strong>nichts</strong>, am CVaR sehr wohl. Deshalb ist der CVaR die Größe, die man optimiert.</li>
|
||||
<li><strong><a href="anhang-glossar.md#gloss:transaktionskosten" class="glossar-link">Transaktionskosten</a> und <a href="anhang-glossar.md#gloss:rebalancing" class="glossar-link">Rebalancing</a> sind Teil des Modells, nicht ein Abzug danach.</strong> <a href="cvar.html#kap-cvar">Kapitel 20</a> nimmt sie in die <a href="anhang-glossar.md#gloss:zielfunktion" class="glossar-link">Zielfunktion</a>, <a href="handelsmaschine.html#kap-handelsmaschine">Kapitel 21</a> setzt den <a href="anhang-glossar.md#gloss:backtest" class="glossar-link">Backtest</a> daneben — samt der Fallen, die einen guten Backtest wertlos machen.</li>
|
||||
</ul>
|
||||
<p><strong>Ihr Weg.</strong> Pfad D, und zwar <strong>mit</strong> <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a>. Danach Projekt <strong>P6</strong> (Portfolio-Rebalancer) oder <strong>P7</strong> (Risikoreport mit CVaR und Stresstests).</p>
|
||||
|
|
@ -410,13 +410,13 @@ Alles bereit — Sie können mit dem ersten Kapitel beginnen.</code></pre>
|
|||
<h3 class="unnumbered" id="pfad-a-vollständiger-lehrgang-100140-stunden">Pfad A — Vollständiger Lehrgang (100–140 Stunden)</h3>
|
||||
<p><a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> bis <a href="testing.html#kap-testing">Kapitel 23</a> in Reihenfolge, danach ein Projekt aus der Projektwerkstatt. Empfohlen, wenn Sie OR systematisch lernen wollen. Rechnen Sie mit 4–6 Stunden je Kapitel inklusive Übungen.</p>
|
||||
<h3 class="unnumbered" id="pfad-b-planung-disposition-personaleinsatz-ca.-25-stunden">Pfad B — Planung, Disposition, Personaleinsatz (ca. 25 Stunden)</h3>
|
||||
<p><a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> (Bausteine) → <a href="fundament.html#kap-fundament">Kapitel 2</a> (bis <a href="fundament.html#sec:fundament-konvexitaet-die-grenze-zwischen-leicht-und">Abschnitt 2.5</a>) → <a href="modellierung.html#kap-modellierung">Kapitel 4</a> (vom Wunsch zum Modell) → <a href="lp.html#kap-lp">Kapitel 5</a> (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP</a>, Schattenpreise) → <a href="milp.html#kap-milp">Kapitel 6</a> (Ja/Nein-Entscheidungen) → <a href="cpsat.html#kap-cpsat">Kapitel 7</a> (CP-SAT, Scheduling) → Projekt <strong>P1</strong> (Vertretungsplaner) oder <strong>P2</strong> (Schichtplanung). Das ist der kürzeste Weg zu einem einsetzbaren Dienstplan-Optimierer.</p>
|
||||
<p><a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> (Bausteine) → <a href="fundament.html#kap-fundament">Kapitel 2</a> (bis <a href="fundament.html#sec:fundament-konvexitaet-die-grenze-zwischen-leicht-und">Abschnitt 2.5</a>) → <a href="modellierung.html#kap-modellierung">Kapitel 4</a> (vom Wunsch zum Modell) → <a href="lp.html#kap-lp">Kapitel 5</a> (<a href="anhang-glossar.md#gloss:lineare-programmierung-lp" class="glossar-link">LP (Lineare Programmierung)</a>, Schattenpreise) → <a href="milp.html#kap-milp">Kapitel 6</a> (Ja/Nein-Entscheidungen) → <a href="cpsat.html#kap-cpsat">Kapitel 7</a> (CP-SAT, Scheduling) → Projekt <strong>P1</strong> (Vertretungsplaner) oder <strong>P2</strong> (Schichtplanung). Das ist der kürzeste Weg zu einem einsetzbaren Dienstplan-Optimierer.</p>
|
||||
<p><em>Wenn der Solver bei Ihrer echten Instanz stehen bleibt:</em> <a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a> und Projekt <strong>P9</strong>.</p>
|
||||
<h3 class="unnumbered" id="pfad-c-logistik-und-tourenplanung-ca.-25-stunden">Pfad C — Logistik und Tourenplanung (ca. 25 Stunden)</h3>
|
||||
<p><a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> → <a href="fundament.html#kap-fundament">Kapitel 2</a> (bis <a href="fundament.html#sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder">Abschnitt 2.4</a>) → <a href="lp.html#kap-lp">Kapitel 5</a> → <a href="milp.html#kap-milp">Kapitel 6</a> → <a href="graphen.html#kap-graphen">Kapitel 8</a> (<a href="anhang-glossar.md#gloss:graphen" class="glossar-link">Graphen</a>, <a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP</a>) → Projekt <strong>P3</strong> (Liefertouren) oder <strong>P4</strong> (Lagernetzwerk).</p>
|
||||
<p><a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> → <a href="fundament.html#kap-fundament">Kapitel 2</a> (bis <a href="fundament.html#sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder">Abschnitt 2.4</a>) → <a href="lp.html#kap-lp">Kapitel 5</a> → <a href="milp.html#kap-milp">Kapitel 6</a> → <a href="graphen.html#kap-graphen">Kapitel 8</a> (<a href="anhang-glossar.md#gloss:graphen" class="glossar-link">Graphen</a>, <a href="anhang-glossar.md#gloss:vehicle-routing-problem-vrp" class="glossar-link">VRP (Vehicle Routing Problem)</a>) → Projekt <strong>P3</strong> (Liefertouren) oder <strong>P4</strong> (Lagernetzwerk).</p>
|
||||
<p><em>Wenn die Instanzen zu groß werden:</em> <a href="metaheuristiken.html#kap-metaheuristiken">Kapitel 9</a> (gute Lösung in fester Zeit) und <a href="dekomposition.html#kap-dekomposition">Kapitel 10</a> (das Modell umbauen statt die Lösung raten) — dazu Projekt <strong>P9</strong>, das beide Wege am selben Problem vergleicht.</p>
|
||||
<h3 class="unnumbered" id="pfad-d-quantitative-finance-ca.-30-stunden">Pfad D — Quantitative Finance (ca. 30 Stunden)</h3>
|
||||
<p><a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> → <a href="fundament.html#kap-fundament">Kapitel 2</a> → <a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a> (<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP</a>, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT</a>) → <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a> (Daten, Shrinkage) → <a href="markowitz.html#kap-markowitz">Kapitel 19</a> (Markowitz) → <a href="cvar.html#kap-cvar">Kapitel 20</a> (CVaR) → <a href="handelsmaschine.html#kap-handelsmaschine">Kapitel 21</a> (Backtest) → Projekt <strong>P6</strong> (Portfolio-Rebalancer) oder <strong>P7</strong> (Risikoreport). <strong>Wichtig:</strong> Überspringen Sie <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a> nicht. Wer direkt bei Markowitz einsteigt, optimiert Schätzrauschen und wundert sich über absurde Gewichte.</p>
|
||||
<p><a href="einfuehrung.html#kap-einfuehrung">Kapitel 1</a> → <a href="fundament.html#kap-fundament">Kapitel 2</a> → <a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a> (<a href="anhang-glossar.md#gloss:quadratische-programmierung-qp" class="glossar-link">QP (Quadratische Programmierung)</a>, <a href="anhang-glossar.md#gloss:karush-kuhn-tucker-bedingungen-kkt" class="glossar-link">KKT (Karush-Kuhn-Tucker-Bedingungen)</a>) → <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a> (Daten, Shrinkage) → <a href="markowitz.html#kap-markowitz">Kapitel 19</a> (Markowitz) → <a href="cvar.html#kap-cvar">Kapitel 20</a> (CVaR) → <a href="handelsmaschine.html#kap-handelsmaschine">Kapitel 21</a> (Backtest) → Projekt <strong>P6</strong> (Portfolio-Rebalancer) oder <strong>P7</strong> (Risikoreport). <strong>Wichtig:</strong> Überspringen Sie <a href="finanzdaten.html#kap-finanzdaten">Kapitel 18</a> nicht. Wer direkt bei Markowitz einsteigt, optimiert Schätzrauschen und wundert sich über absurde Gewichte.</p>
|
||||
<h3 class="unnumbered" id="pfad-e-ich-habe-morgen-ein-konkretes-problem-24-stunden">Pfad E — Ich habe morgen ein konkretes Problem (2–4 Stunden)</h3>
|
||||
<p>Lesen Sie <a href="einfuehrung.html#sec:einfuehrung-historischer-kontext-und-evolution">Abschnitt 1.5</a> (die vier Bausteine) und <a href="modellierung.html#sec:modellierung-glossar">Abschnitt 4.6</a> (welcher Satz welcher Baustein ist), dann <a href="anhang-modellierungsmuster.html#anhang-modellierungsmuster">Anhang B</a> (<a href="anhang-modellierungsmuster.html">Modellierungsmuster</a>) und suchen Sie dort das Muster, das zu Ihrem Problem passt. Von jedem Muster führt ein Verweis in das zuständige Kapitel. Wie die gewählte Bibliothek es schreibt, steht in <a href="anhang-spickzettel.html#anhang-spickzettel">Anhang D</a> (<a href="anhang-spickzettel.html">Spickzettel</a>); wenn etwas nicht läuft, in <a href="anhang-fehlerdiagnose.html#anhang-fehlerdiagnose">Anhang C</a> (<a href="anhang-fehlerdiagnose.html">Fehlerdiagnose</a>).</p>
|
||||
<h3 class="unnumbered" id="pfad-f-vom-prototyp-in-den-betrieb-ca.-15-stunden">Pfad F — Vom Prototyp in den Betrieb (ca. 15 Stunden)</h3>
|
||||
|
|
@ -631,7 +631,7 @@ Alles bereit — Sie können mit dem ersten Kapitel beginnen.</code></pre>
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td><code>QP_Grundlagen.py</code></td>
|
||||
<td><a href="anhang-glossar.md#gloss:konvexitaet" class="glossar-link">Konvexität</a>, <a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP</a>-Check</td>
|
||||
<td><a href="anhang-glossar.md#gloss:konvexitaet" class="glossar-link">Konvexität</a>, <a href="anhang-glossar.md#gloss:dcp-disciplined-convex-programming" class="glossar-link">DCP (Disciplined Convex Programming)</a>-Check</td>
|
||||
<td><a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
@ -641,7 +641,7 @@ Alles bereit — Sie können mit dem ersten Kapitel beginnen.</code></pre>
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td><code>Entropie_Maximierte_Allokation.py</code></td>
|
||||
<td><a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP</a> mit Entropie</td>
|
||||
<td><a href="anhang-glossar.md#gloss:nichtlineare-programmierung-nlp" class="glossar-link">NLP (Nichtlineare Programmierung)</a> mit Entropie</td>
|
||||
<td><a href="qp-nlp.html#kap-qp-nlp">Kapitel 11</a></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
|
|
@ -726,7 +726,7 @@ Alles bereit — Sie können mit dem ersten Kapitel beginnen.</code></pre>
|
|||
</tr>
|
||||
<tr class="even">
|
||||
<td><code>Markowitz_CVXPY.py</code></td>
|
||||
<td><a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV</a>, Max Sharpe, Frontier</td>
|
||||
<td><a href="anhang-glossar.md#gloss:global-minimum-variance-portfolio-gmv" class="glossar-link">GMV (Global Minimum Variance Portfolio)</a>, Max Sharpe, Frontier</td>
|
||||
<td><a href="markowitz.html#kap-markowitz">Kapitel 19</a></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
|
|
|
|||
271
Operations_Research_mit_Python_Version_04.md
generated
271
Operations_Research_mit_Python_Version_04.md
generated
|
|
@ -26,7 +26,7 @@ Autor / Herausgeber: Dieter Schlüter
|
|||
|
||||
<dieter(dot)schlueter(atsign)linix(dot)de>
|
||||
|
||||
Stand: 10. September 2026 v17.38
|
||||
Stand: 10. September 2026 v17.50
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -300,14 +300,14 @@ Suchen Sie sich einen aus. Sie können auch alle vier überspringen; nötig sind
|
|||
|
||||
**Woran es scheitert.** Nicht am Modell, sondern an der Einführung — das ist der meistgenannte Befund in [Kapitel 22](#kap-praxisfallen). Und an einer Verwechslung, die dieses Buch Ihnen nicht abnehmen kann: Ein Bericht erklärt das **Modell**, nicht die **Wirklichkeit**. Ist ein Deckungsbeitrag falsch geschätzt, ist er überzeugend **und** falsch. Fragen Sie deshalb jedes Mal, worauf eine Zahl beruht.
|
||||
|
||||
> **Eine Erwartung, die dieses Buch enttäuscht:** Es nennt keine ROI-Kennzahl und keine Amortisationsdauer. Beide hängen an Ihrem Betrieb, und jede Zahl hier wäre erfunden. Was es stattdessen liefert, ist das Werkzeug, Ihre eigene auszurechnen: den **[EVPI](#gloss:evpi-expected-value-of-perfect-information){.glossar-link}** in [Kapitel 12](#kap-unsicherheit) (was eine perfekte Prognose überhaupt wert wäre — eine Obergrenze für jedes Prognoseprojekt) und die Kostenzurechnung aus [Abschnitt 22.4](#sec:praxisfallen-attribution).
|
||||
> **Eine Erwartung, die dieses Buch enttäuscht:** Es nennt keine ROI-Kennzahl und keine Amortisationsdauer. Beide hängen an Ihrem Betrieb, und jede Zahl hier wäre erfunden. Was es stattdessen liefert, ist das Werkzeug, Ihre eigene auszurechnen: den **[EVPI (Expected Value of Perfect Information)](#gloss:evpi-expected-value-of-perfect-information){.glossar-link}** in [Kapitel 12](#kap-unsicherheit) (was eine perfekte Prognose überhaupt wert wäre — eine Obergrenze für jedes Prognoseprojekt) und die Kostenzurechnung aus [Abschnitt 22.4](#sec:praxisfallen-attribution).
|
||||
|
||||
### Für Ingenieure und Produktionsplaner — die Physik des Systems {-}
|
||||
|
||||
> *„Der Engpass wandert. Kaum ist eine Maschine entlastet, steht die nächste — und niemand kann mir vorher sagen, welche.“*
|
||||
|
||||
* **Der Engpass lässt sich benennen und bepreisen.** [Abschnitt 22.4](#sec:praxisfallen-attribution) rechnet für jede Kapazität aus, was die nächste Stunde wert ist — und wie weit dieser Wert trägt. Im Beispiel gilt der [Schattenpreis](#gloss:schattenpreis){.glossar-link}`\index{Schattenpreis}`{=latex} der Lackiererei exakt bis **+15 Stunden**; eine ganze Sonderschicht von 30 Stunden bringt deshalb 60 € statt der rechnerischen 120 €. **Die zweite Hälfte wäre bezahlt und wirkungslos.**
|
||||
* **Rüstzeiten, Reihenfolgen, Taktzeiten sind der Kern, nicht die Ausnahme.** [Kapitel 7](#kap-cpsat) modelliert Maschinenbelegung mit Intervallvariablen, [Kapitel 9](#kap-metaheuristiken) zeigt am selben Fall das Gesamtbild: Faustregel 2 497 Minuten [Rüstzeit](#gloss:ruestzeit){.glossar-link}`\index{Rüstzeit}`{=latex}, [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} allein 2 628, [Simulated Annealing](#gloss:simulated-annealing){.glossar-link}`\index{Simulated Annealing}`{=latex} 2 343, Annealing plus [LNS](#gloss:large-neighborhood-search-lns){.glossar-link} **2 289** — und die untere Schranke bei 1 768, damit sichtbar bleibt, wie viel Luft noch da ist.
|
||||
* **Rüstzeiten, Reihenfolgen, Taktzeiten sind der Kern, nicht die Ausnahme.** [Kapitel 7](#kap-cpsat) modelliert Maschinenbelegung mit Intervallvariablen, [Kapitel 9](#kap-metaheuristiken) zeigt am selben Fall das Gesamtbild: Faustregel 2 497 Minuten [Rüstzeit](#gloss:ruestzeit){.glossar-link}`\index{Rüstzeit}`{=latex}, [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} allein 2 628, [Simulated Annealing](#gloss:simulated-annealing){.glossar-link}`\index{Simulated Annealing}`{=latex} 2 343, Annealing plus [LNS (Large Neighborhood Search)](#gloss:large-neighborhood-search-lns){.glossar-link} **2 289** — und die untere Schranke bei 1 768, damit sichtbar bleibt, wie viel Luft noch da ist.
|
||||
* **Wenn der Solver zu lange braucht, gibt es Zahlen statt Ratschläge.** [Abschnitt 7.7](#sec:cpsat-parallele-suche) misst, was mehrere Suchstränge bringen (hier Faktor 12,3) — und ab wo mehr Arbeiter wieder schaden.
|
||||
|
||||
**Ihr Weg.** Pfad B bis [Kapitel 7](#kap-cpsat), dann Projekt **P5** (Produktionsplanung mit Rüstkosten). Wenn Ihre echten Instanzen den Solver stehen lassen: [Kapitel 9](#kap-metaheuristiken) und Projekt **P9**.
|
||||
|
|
@ -319,7 +319,7 @@ Suchen Sie sich einen aus. Sie können auch alle vier überspringen; nötig sind
|
|||
> *„Die Optimierung liefert mir Gewichte, die kein Mensch halten würde: 60 % in einem Titel, null in fünf anderen. Und im nächsten Quartal sieht sie völlig anders aus.“*
|
||||
|
||||
* **Der Grund dafür steht in [Kapitel 18](#kap-finanzdaten), nicht in [Kapitel 19](#kap-markowitz).** Eine aus kurzen Zeitreihen geschätzte [Kovarianzmatrix](#gloss:kovarianzmatrix){.glossar-link}`\index{Kovarianzmatrix}`{=latex} ist schlecht konditioniert; der Optimierer setzt dann auf Schätzrauschen. Shrinkage nach Ledoit-Wolf ist das Gegenmittel; ihre Wirkung wird an **Eigenwertspektrum und [Konditionszahl](#gloss:konditionszahl){.glossar-link}**`\index{Konditionszahl}`{=latex} gemessen, nicht behauptet.
|
||||
* **Der [VaR](#gloss:value-at-risk-var){.glossar-link} verschweigt genau das, worauf es ankommt.** In der Stichprobe aus [Kapitel 20](#kap-cvar) sagt der VaR: „an 95 % der Tage höchstens **1,86 %** Verlust“. Der [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} sagt: „und wenn doch, dann im Mittel **2,99 %**“. Der schlechteste Tag der Stichprobe liegt bei **−23,0 %** — am VaR ändert dieser eine Tag **nichts**, am CVaR sehr wohl. Deshalb ist der CVaR die Größe, die man optimiert.
|
||||
* **Der [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link} verschweigt genau das, worauf es ankommt.** In der Stichprobe aus [Kapitel 20](#kap-cvar) sagt der VaR: „an 95 % der Tage höchstens **1,86 %** Verlust“. Der [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} sagt: „und wenn doch, dann im Mittel **2,99 %**“. Der schlechteste Tag der Stichprobe liegt bei **−23,0 %** — am VaR ändert dieser eine Tag **nichts**, am CVaR sehr wohl. Deshalb ist der CVaR die Größe, die man optimiert.
|
||||
* **[Transaktionskosten](#gloss:transaktionskosten){.glossar-link}`\index{Transaktionskosten}`{=latex} und [Rebalancing](#gloss:rebalancing){.glossar-link} sind Teil des Modells, nicht ein Abzug danach.** [Kapitel 20](#kap-cvar) nimmt sie in die [Zielfunktion](#gloss:zielfunktion){.glossar-link}`\index{Zielfunktion}`{=latex}, [Kapitel 21](#kap-handelsmaschine) setzt den [Backtest](#gloss:backtest){.glossar-link} daneben — samt der Fallen, die einen guten Backtest wertlos machen.
|
||||
|
||||
**Ihr Weg.** Pfad D, und zwar **mit** [Kapitel 18](#kap-finanzdaten). Danach Projekt **P6** (Portfolio-Rebalancer) oder **P7** (Risikoreport mit CVaR und Stresstests).
|
||||
|
|
@ -350,19 +350,19 @@ Sie müssen nicht alles lesen, um etwas Nützliches bauen zu können.
|
|||
|
||||
### Pfad B — Planung, Disposition, Personaleinsatz (ca. 25 Stunden) {-}
|
||||
|
||||
[Kapitel 1](#kap-einfuehrung) (Bausteine) → [Kapitel 2](#kap-fundament) (bis [Abschnitt 2.5](#sec:fundament-konvexitaet-die-grenze-zwischen-leicht-und)) → [Kapitel 4](#kap-modellierung) (vom Wunsch zum Modell) → [Kapitel 5](#kap-lp) ([LP](#gloss:lineare-programmierung-lp){.glossar-link}, Schattenpreise) → [Kapitel 6](#kap-milp) (Ja/Nein-Entscheidungen) → [Kapitel 7](#kap-cpsat) (CP-SAT, Scheduling) → Projekt **P1** (Vertretungsplaner) oder **P2** (Schichtplanung). Das ist der kürzeste Weg zu einem einsetzbaren Dienstplan-Optimierer.
|
||||
[Kapitel 1](#kap-einfuehrung) (Bausteine) → [Kapitel 2](#kap-fundament) (bis [Abschnitt 2.5](#sec:fundament-konvexitaet-die-grenze-zwischen-leicht-und)) → [Kapitel 4](#kap-modellierung) (vom Wunsch zum Modell) → [Kapitel 5](#kap-lp) ([LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}, Schattenpreise) → [Kapitel 6](#kap-milp) (Ja/Nein-Entscheidungen) → [Kapitel 7](#kap-cpsat) (CP-SAT, Scheduling) → Projekt **P1** (Vertretungsplaner) oder **P2** (Schichtplanung). Das ist der kürzeste Weg zu einem einsetzbaren Dienstplan-Optimierer.
|
||||
|
||||
*Wenn der Solver bei Ihrer echten Instanz stehen bleibt:* [Kapitel 9](#kap-metaheuristiken) und Projekt **P9**.
|
||||
|
||||
### Pfad C — Logistik und Tourenplanung (ca. 25 Stunden) {-}
|
||||
|
||||
[Kapitel 1](#kap-einfuehrung) → [Kapitel 2](#kap-fundament) (bis [Abschnitt 2.4](#sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder)) → [Kapitel 5](#kap-lp) → [Kapitel 6](#kap-milp) → [Kapitel 8](#kap-graphen) ([Graphen](#gloss:graphen){.glossar-link}, [VRP](#gloss:vehicle-routing-problem-vrp){.glossar-link}) → Projekt **P3** (Liefertouren) oder **P4** (Lagernetzwerk).
|
||||
[Kapitel 1](#kap-einfuehrung) → [Kapitel 2](#kap-fundament) (bis [Abschnitt 2.4](#sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder)) → [Kapitel 5](#kap-lp) → [Kapitel 6](#kap-milp) → [Kapitel 8](#kap-graphen) ([Graphen](#gloss:graphen){.glossar-link}, [VRP (Vehicle Routing Problem)](#gloss:vehicle-routing-problem-vrp){.glossar-link}) → Projekt **P3** (Liefertouren) oder **P4** (Lagernetzwerk).
|
||||
|
||||
*Wenn die Instanzen zu groß werden:* [Kapitel 9](#kap-metaheuristiken) (gute Lösung in fester Zeit) und [Kapitel 10](#kap-dekomposition) (das Modell umbauen statt die Lösung raten) — dazu Projekt **P9**, das beide Wege am selben Problem vergleicht.
|
||||
|
||||
### Pfad D — Quantitative Finance (ca. 30 Stunden) {-}
|
||||
|
||||
[Kapitel 1](#kap-einfuehrung) → [Kapitel 2](#kap-fundament) → [Kapitel 11](#kap-qp-nlp) ([QP](#gloss:quadratische-programmierung-qp){.glossar-link}, [KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}) → [Kapitel 18](#kap-finanzdaten) (Daten, Shrinkage) → [Kapitel 19](#kap-markowitz) (Markowitz) → [Kapitel 20](#kap-cvar) (CVaR) → [Kapitel 21](#kap-handelsmaschine) (Backtest) → Projekt **P6** (Portfolio-Rebalancer) oder **P7** (Risikoreport). **Wichtig:** Überspringen Sie [Kapitel 18](#kap-finanzdaten) nicht. Wer direkt bei Markowitz einsteigt, optimiert Schätzrauschen und wundert sich über absurde Gewichte.
|
||||
[Kapitel 1](#kap-einfuehrung) → [Kapitel 2](#kap-fundament) → [Kapitel 11](#kap-qp-nlp) ([QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link}, [KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}) → [Kapitel 18](#kap-finanzdaten) (Daten, Shrinkage) → [Kapitel 19](#kap-markowitz) (Markowitz) → [Kapitel 20](#kap-cvar) (CVaR) → [Kapitel 21](#kap-handelsmaschine) (Backtest) → Projekt **P6** (Portfolio-Rebalancer) oder **P7** (Risikoreport). **Wichtig:** Überspringen Sie [Kapitel 18](#kap-finanzdaten) nicht. Wer direkt bei Markowitz einsteigt, optimiert Schätzrauschen und wundert sich über absurde Gewichte.
|
||||
|
||||
### Pfad E — Ich habe morgen ein konkretes Problem (2–4 Stunden) {-}
|
||||
|
||||
|
|
@ -420,9 +420,9 @@ Alle Beispielprogramme dieses Buchs im Überblick, sortiert nach Kapitel — pra
|
|||
| `Metaheuristik_vs_Exakt.py` | Der Umschlagpunkt, und die Schranke | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| `Large_Neighborhood_Search.py` | Zerstören und exakt reparieren | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| `Spaltengenerierung.py` | Muster statt Stücke, Master und Pricing | [Kapitel 10](#kap-dekomposition) |
|
||||
| `QP_Grundlagen.py` | [Konvexität](#gloss:konvexitaet){.glossar-link}`\index{Konvexität}`{=latex}, [DCP](#gloss:dcp-disciplined-convex-programming){.glossar-link}-Check | [Kapitel 11](#kap-qp-nlp) |
|
||||
| `QP_Grundlagen.py` | [Konvexität](#gloss:konvexitaet){.glossar-link}`\index{Konvexität}`{=latex}, [DCP (Disciplined Convex Programming)](#gloss:dcp-disciplined-convex-programming){.glossar-link}-Check | [Kapitel 11](#kap-qp-nlp) |
|
||||
| `KKT_Nachweis.py` | KKT numerisch prüfen | [Kapitel 11](#kap-qp-nlp) |
|
||||
| `Entropie_Maximierte_Allokation.py` | [NLP](#gloss:nichtlineare-programmierung-nlp){.glossar-link} mit Entropie | [Kapitel 11](#kap-qp-nlp) |
|
||||
| `Entropie_Maximierte_Allokation.py` | [NLP (Nichtlineare Programmierung)](#gloss:nichtlineare-programmierung-nlp){.glossar-link} mit Entropie | [Kapitel 11](#kap-qp-nlp) |
|
||||
| `Lokale_Optima_Multistart.py` | Lokale Optima, Multistart | [Kapitel 11](#kap-qp-nlp) |
|
||||
| `Fluch_des_Durchschnitts.py` | Optimum ≠ Mittelwert | [Kapitel 12](#kap-unsicherheit) |
|
||||
| `Monte_Carlo.py` | Monte-Carlo-Bewertung | [Kapitel 12](#kap-unsicherheit) |
|
||||
|
|
@ -439,7 +439,7 @@ Alle Beispielprogramme dieses Buchs im Überblick, sortiert nach Kapitel — pra
|
|||
| `Schaetzrauschen_Demo.py` | Error-Maximizer messen | [Kapitel 18](#kap-finanzdaten) |
|
||||
| `Finanzdaten_Ledoit_Wolf.py` | Datenpipeline, Shrinkage | [Kapitel 18](#kap-finanzdaten) |
|
||||
| `Kovarianz_Falle.py` | Singuläre Kovarianz, Error-Maximizer | [Kapitel 18](#kap-finanzdaten) |
|
||||
| `Markowitz_CVXPY.py` | [GMV](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}, Max Sharpe, Frontier | [Kapitel 19](#kap-markowitz) |
|
||||
| `Markowitz_CVXPY.py` | [GMV (Global Minimum Variance Portfolio)](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}, Max Sharpe, Frontier | [Kapitel 19](#kap-markowitz) |
|
||||
| `Diversifikation_Demo.py` | Korrelation und Portfoliorisiko | [Kapitel 19](#kap-markowitz) |
|
||||
| `Renditeschaetzung_Falle.py` | Schätzfehler in erwarteten Renditen | [Kapitel 19](#kap-markowitz) |
|
||||
| `VaR_CVaR_Demo.py` | [Fat Tails](#gloss:fat-tails){.glossar-link}`\index{Fat Tails}`{=latex}, [Subadditivität](#gloss:subadditivitaet){.glossar-link}`\index{Subadditivität}`{=latex} | [Kapitel 20](#kap-cvar) |
|
||||
|
|
@ -528,9 +528,9 @@ Dieses Kapitel ist zum Nachschlagen gedacht, nicht zum Durchlesen. Schlagen Sie
|
|||
|
||||
| Symbol | Bedeutung | Praktische Folge |
|
||||
| --- | --- | --- |
|
||||
| $\mathbb{R}$ | Reelle Zahlen (beliebig teilbar) | Variable darf 3,7 sein — **[LP](#gloss:lineare-programmierung-lp){.glossar-link}**, schnell lösbar |
|
||||
| $\mathbb{R}$ | Reelle Zahlen (beliebig teilbar) | Variable darf 3,7 sein — **[LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}**, schnell lösbar |
|
||||
| $\mathbb{R}^n$ | $n$-Tupel reeller Zahlen | Der Raum, in dem $\mathbf{x}$ lebt |
|
||||
| $\mathbb{Z}$ | Ganze Zahlen | Variable muss 3 oder 4 sein — **[MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}**, [NP-schwer](#gloss:np-schwer){.glossar-link}`\index{NP-schwer}`{=latex} |
|
||||
| $\mathbb{Z}$ | Ganze Zahlen | Variable muss 3 oder 4 sein — **[MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}**, [NP-schwer](#gloss:np-schwer){.glossar-link}`\index{NP-schwer}`{=latex} |
|
||||
| $\mathbb{N}_0$ | Natürliche Zahlen einschließlich 0 | Stückzahlen, nie negativ |
|
||||
| $\{0, 1\}$ | Nur zwei Werte | Ja/Nein-Entscheidung |
|
||||
| $\in$ | „ist Element von“ | $x \in \mathbb{Z}$: „$x$ ist ganzzahlig“ |
|
||||
|
|
@ -578,7 +578,7 @@ Dieses Kapitel ist zum Nachschlagen gedacht, nicht zum Durchlesen. Schlagen Sie
|
|||
| $r_{i,t}$ | **[Logarithmische Rendite](#gloss:logarithmische-rendite){.glossar-link}**`\index{Logarithmische Rendite}`{=latex} (stetige Rendite) | $\ln(P_t/P_{t-1})$ |
|
||||
| $P_{i,t}$ | **Kurs** (bereinigter Schlusskurs) von Titel $i$ | in Währungseinheiten |
|
||||
| $\lambda$ | Risikoaversion / Gewichtung des Risikoterms | Modellparameter, frei wählbar |
|
||||
| $\alpha$ | Konfidenzniveau bei [VaR](#gloss:value-at-risk-var){.glossar-link}/[CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} | $0{,}95$ = „schlechteste 5 % der Tage“ |
|
||||
| $\alpha$ | Konfidenzniveau bei [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link}/[CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} | $0{,}95$ = „schlechteste 5 % der Tage“ |
|
||||
| $\gamma$ | Hilfsvariable, schätzt den VaR ([Kapitel 20](#kap-cvar)); Diskontfaktor ([Kapitel 13](#kap-dynamische-programmierung)) | kontextabhängig |
|
||||
| $\eta$ | „eta“ — Marktimpact-Koeffizient | [Kapitel 13](#kap-dynamische-programmierung), Almgren-Chriss |
|
||||
| $X_t$ | Verbleibender Aktienbestand zum Zeitpunkt $t$ | [Kapitel 13](#kap-dynamische-programmierung) |
|
||||
|
|
@ -623,32 +623,32 @@ Diese Zeichen kommen erst in den Kapiteln vor, die über das klassische LP hinau
|
|||
| **MILP** | Mixed-Integer Linear Program(ming) | Gemischt-ganzzahlige lineare Optimierung | [Kapitel 6](#kap-milp) |
|
||||
| **MIP** | Mixed-Integer Program(ming) | Oberbegriff, meist synonym zu MILP | [Kapitel 6](#kap-milp) |
|
||||
| **IP** | Integer Program(ming) | Rein ganzzahlige Optimierung | [Kapitel 6](#kap-milp) |
|
||||
| **[QP](#gloss:quadratische-programmierung-qp){.glossar-link}** | Quadratic Program(ming) | Quadratische Optimierung | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **[QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link}** | Quadratic Program(ming) | Quadratische Optimierung | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **[MIQP](#gloss:miqp){.glossar-link}** | Mixed-Integer Quadratic Program(ming) | Ganzzahlig-quadratische Optimierung | [Kapitel 19](#kap-markowitz) |
|
||||
| **[NLP](#gloss:nichtlineare-programmierung-nlp){.glossar-link}** | Nonlinear Program(ming) | Nichtlineare Optimierung | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **[NLP (Nichtlineare Programmierung)](#gloss:nichtlineare-programmierung-nlp){.glossar-link}** | Nonlinear Program(ming) | Nichtlineare Optimierung | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **[MINLP](#gloss:minlp){.glossar-link}**`\index{MINLP}`{=latex} | Mixed-Integer Nonlinear Program(ming) | Ganzzahlig-nichtlineare Optimierung | [Kapitel 3](#kap-oekosystem) |
|
||||
| **[CP](#gloss:constraint-programming-cp){.glossar-link}** | Constraint Programming | Bedingungsprogrammierung | [Kapitel 7](#kap-cpsat) |
|
||||
| **[SAT](#gloss:sat-boolean-satisfiability){.glossar-link}** | Boolean **Sat**isfiability Problem | Erfüllbarkeitsproblem der Aussagenlogik | [Kapitel 7](#kap-cpsat) |
|
||||
| **[CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}** | Constraint Programming | Bedingungsprogrammierung | [Kapitel 7](#kap-cpsat) |
|
||||
| **[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link}** | Boolean **Sat**isfiability Problem | Erfüllbarkeitsproblem der Aussagenlogik | [Kapitel 7](#kap-cpsat) |
|
||||
| **[CP-SAT](#gloss:cp-sat){.glossar-link}**`\index{CP-SAT}`{=latex} | Constraint Programming über SAT-Techniken | Solver-Name von Google [OR-Tools](#gloss:or-tools){.glossar-link}`\index{OR-Tools}`{=latex} | [Kapitel 7](#kap-cpsat) |
|
||||
| **[CDCL](#gloss:cdcl){.glossar-link}**`\index{CDCL}`{=latex} | Conflict-Driven Clause Learning | konfliktgetriebenes Klausellernen | [Kapitel 7](#kap-cpsat) |
|
||||
| **[DP](#gloss:dynamische-programmierung-dp){.glossar-link}** | Dynamic Programming | Dynamische Programmierung | [Kapitel 13](#kap-dynamische-programmierung) |
|
||||
| **[DP (Dynamische Programmierung)](#gloss:dynamische-programmierung-dp){.glossar-link}** | Dynamic Programming | Dynamische Programmierung | [Kapitel 13](#kap-dynamische-programmierung) |
|
||||
| **B&B** | Branch and Bound | Verzweigen und Beschränken | [Kapitel 6](#kap-milp) |
|
||||
| **B&C** | Branch and Cut | Verzweigen mit Schnittebenen | [Kapitel 6](#kap-milp) |
|
||||
| **[KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}** | Karush–Kuhn–Tucker (Bedingungen) | Optimalitätsbedingungen bei Restriktionen | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **[KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}** | Karush–Kuhn–Tucker (Bedingungen) | Optimalitätsbedingungen bei Restriktionen | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **[SLSQP](#gloss:slsqp){.glossar-link}**`\index{SLSQP}`{=latex} | Sequential Least Squares Programming | sequentielle quadratische Optimierung | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **RMT** | Random Matrix Theory | [Zufallsmatrizentheorie](#gloss:zufallsmatrizentheorie){.glossar-link}`\index{Zufallsmatrizentheorie}`{=latex} | [Kapitel 18](#kap-finanzdaten) |
|
||||
| **SA** | Simulated Annealing | Simulierte Abkühlung — [Metaheuristik](#gloss:metaheuristik){.glossar-link}`\index{Metaheuristik}`{=latex}, die Verschlechterungen mit fallender Wahrscheinlichkeit zulässt | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| **[LNS](#gloss:large-neighborhood-search-lns){.glossar-link}** | Large Neighborhood Search | Große Nachbarschaftssuche: Teil der Lösung verwerfen, Rest exakt neu bauen | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| **[LNS (Large Neighborhood Search)](#gloss:large-neighborhood-search-lns){.glossar-link}** | Large Neighborhood Search | Große Nachbarschaftssuche: Teil der Lösung verwerfen, Rest exakt neu bauen | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| **CG** | [Column Generation](#gloss:column-generation){.glossar-link}`\index{Column Generation}`{=latex} | Spaltengenerierung — Variablen erst erzeugen, wenn sie sich lohnen | [Kapitel 10](#kap-dekomposition) |
|
||||
| **[IIS](#gloss:iis-irreducible-infeasible-subset){.glossar-link}** | Irreducible Infeasible Subset | Kleinste widersprüchliche Teilmenge von Bedingungen | [Anhang C](#anhang-fehlerdiagnose) |
|
||||
| **[IIS (Irreducible Infeasible Subset)](#gloss:iis-irreducible-infeasible-subset){.glossar-link}** | Irreducible Infeasible Subset | Kleinste widersprüchliche Teilmenge von Bedingungen | [Anhang C](#anhang-fehlerdiagnose) |
|
||||
| **[MSE](#gloss:mse){.glossar-link}** | Mean Squared Error | Mittlerer quadratischer Fehler — das Standardmaß für Prognosegüte | [Kapitel 15](#kap-prognose) |
|
||||
|
||||
### 2.2 Probleme mit Eigennamen
|
||||
|
||||
| Kürzel | Ausgeschrieben | Deutsch | Kapitel |
|
||||
| --- | --- | --- | --- |
|
||||
| **[TSP](#gloss:tsp-traveling-salesperson-problem){.glossar-link}** | Traveling Salesperson Problem | Problem des Handlungsreisenden | [Kapitel 8](#kap-graphen) |
|
||||
| **[VRP](#gloss:vehicle-routing-problem-vrp){.glossar-link}** | Vehicle Routing Problem | Tourenplanungsproblem | [Kapitel 8](#kap-graphen) |
|
||||
| **[TSP (Traveling Salesperson Problem)](#gloss:tsp-traveling-salesperson-problem){.glossar-link}** | Traveling Salesperson Problem | Problem des Handlungsreisenden | [Kapitel 8](#kap-graphen) |
|
||||
| **[VRP (Vehicle Routing Problem)](#gloss:vehicle-routing-problem-vrp){.glossar-link}** | Vehicle Routing Problem | Tourenplanungsproblem | [Kapitel 8](#kap-graphen) |
|
||||
| **CVRP** | **C**apacitated VRP | VRP mit Fahrzeugkapazitäten | [Kapitel 8](#kap-graphen) |
|
||||
| **VRPTW** | VRP with **T**ime **W**indows | VRP mit Zeitfenstern | [Kapitel 8](#kap-graphen) |
|
||||
| **[CVRPTW](#gloss:cvrptw){.glossar-link}**`\index{CVRPTW}`{=latex} | Capacitated VRP with Time Windows | mit Kapazitäten *und* Zeitfenstern | [Kapitel 8](#kap-graphen) |
|
||||
|
|
@ -661,7 +661,7 @@ Diese Zeichen kommen erst in den Kapiteln vor, die über das klassische LP hinau
|
|||
| Kürzel | Ausgeschrieben | Deutsch / Bedeutung | Kapitel |
|
||||
| --- | --- | --- | --- |
|
||||
| **MPT** | Modern Portfolio Theory | Moderne Portfoliotheorie (Markowitz) | [Kapitel 19](#kap-markowitz) |
|
||||
| **[GMV](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}** | Global Minimum Variance (Portfolio) | Portfolio kleinstmöglicher Varianz | [Kapitel 19](#kap-markowitz) |
|
||||
| **[GMV (Global Minimum Variance Portfolio)](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}** | Global Minimum Variance (Portfolio) | Portfolio kleinstmöglicher Varianz | [Kapitel 19](#kap-markowitz) |
|
||||
| **MVO** | Mean-Variance Optimization | Erwartungswert-Varianz-Optimierung | [Kapitel 19](#kap-markowitz) |
|
||||
| **SR** | [Sharpe Ratio](#gloss:sharpe-ratio){.glossar-link}`\index{Sharpe-Ratio}`{=latex} | Überrendite je Einheit Volatilität | [Kapitel 19](#kap-markowitz) |
|
||||
| **VaR** | Value at Risk | Verlustschwelle bei gegebener Wahrscheinlichkeit | [Kapitel 20](#kap-cvar) |
|
||||
|
|
@ -693,7 +693,7 @@ Diese Zeichen kommen erst in den Kapiteln vor, die über das klassische LP hinau
|
|||
| **API** | Application Programming Interface | Programmierschnittstelle | — |
|
||||
| **DSL** | Domain-Specific Language | fachspezifische Sprache (hier: Modellierungssprache) | — |
|
||||
| **CSR** | Compressed Sparse Row | Speicherformat für dünnbesetzte Matrizen | — |
|
||||
| **[GIL](#gloss:gil-global-interpreter-lock){.glossar-link}** | Global Interpreter Lock | Pythons Sperre, die echte Parallelität von Python-Code verhindert — Solverbibliotheken in C++ geben sie frei ([Kapitel 23](#kap-testing)) | — |
|
||||
| **[GIL (Global Interpreter Lock)](#gloss:gil-global-interpreter-lock){.glossar-link}** | Global Interpreter Lock | Pythons Sperre, die echte Parallelität von Python-Code verhindert — Solverbibliotheken in C++ geben sie frei ([Kapitel 23](#kap-testing)) | — |
|
||||
| **JSON** | JavaScript Object Notation | Textformat für strukturierte Daten; Austauschformat des Optimierungsdienstes | — |
|
||||
| **RHS** | Right-Hand Side | rechte Seite einer (Un-)Gleichung, der Vektor $\mathbf{b}$ | — |
|
||||
| **FFI** | Foreign Function Interface | Aufruf von C/C++-Code aus Python | — |
|
||||
|
|
@ -1071,8 +1071,8 @@ Die **Stellschrauben**`\index{Entscheidungsvariable}`{=latex} des Modells: Werte
|
|||
|
||||
| Typ | Notation | Beispiel | Problemklasse |
|
||||
| -------------- | ------------------ | -------------------------------------------------------- | ------------- |
|
||||
| Kontinuierlich | $x \in \mathbb{R}$ | Investitionsbetrag in Euro, Fördermenge in Litern | [LP](#gloss:lineare-programmierung-lp){.glossar-link} — leicht |
|
||||
| Ganzzahlig | $x \in \mathbb{Z}$ | Anzahl produzierter Maschinen, Anzahl Mitarbeiter | [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} — schwer |
|
||||
| Kontinuierlich | $x \in \mathbb{R}$ | Investitionsbetrag in Euro, Fördermenge in Litern | [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} — leicht |
|
||||
| Ganzzahlig | $x \in \mathbb{Z}$ | Anzahl produzierter Maschinen, Anzahl Mitarbeiter | [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} — schwer |
|
||||
| Binär | $x \in \{0, 1\}$ | „Aktie $i$ kaufen: ja/nein“, „Schicht zuweisen: ja/nein“ | MILP — schwer |
|
||||
|
||||
> **Die Leitfrage:** *Worüber darf ich überhaupt entscheiden?* Alles, was feststeht, ist kein Variable, sondern Parameter. Die häufigste Ursache für unbrauchbare Modelle ist eine falsch gewählte Variablendefinition — nicht ein falscher Solver.
|
||||
|
|
@ -1680,7 +1680,7 @@ Ergebnis geschrieben nach: produktionsmix_ergebnis.xlsx
|
|||
|
||||
**Aufgabe 1.4 ⭐⭐ — Modell lesen.** Gegeben sei das Modell $$\max\ 3x_1 + 5x_2 \quad \text{u. d. N.} \quad x_1 \le 4,\ \ 2x_2 \le 12,\ \ 3x_1 + 2x_2 \le 18,\ \ x_1, x_2 \ge 0.$$ (a) Benennen Sie die vier Bausteine. (b) Ist $(2, 6)$ zulässig? Ist $(4, 3)$ zulässig? Berechnen Sie jeweils $Z$. (c) Finden Sie durch Probieren die beste ganzzahlige Lösung.
|
||||
|
||||
**Aufgabe 1.5 ⭐⭐⭐ — Die Bäckerei programmieren.** Setzen Sie das Bäckerei-Problem der Handrechnung *Zerlegen Sie dieses Problem* mit [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} um. Geben Sie die optimale Produktionsmenge, den Deckungsbeitrag und die Auslastung von Mehl und Ofen aus. Prüfen Sie Ihr Ergebnis mit `assert`-Anweisungen.
|
||||
**Aufgabe 1.5 ⭐⭐⭐ — Die Bäckerei programmieren.** Setzen Sie das Bäckerei-Problem der Handrechnung *Zerlegen Sie dieses Problem* mit [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} um. Geben Sie die optimale Produktionsmenge, den Deckungsbeitrag und die Auslastung von Mehl und Ofen aus. Prüfen Sie Ihr Ergebnis mit `assert`-Anweisungen.
|
||||
|
||||
**Aufgabe 1.6 ⭐⭐⭐ — Sensitivität durch Ausprobieren.** Erweitern Sie `Bot_Allokation.py` so, dass es das Modell in einer Schleife für RAM-Kapazitäten von 54 bis 72 GB (in Schritten von 2) löst und eine Tabelle `RAM | x_A | x_B | Gewinn | Gewinnzuwachs pro zusätzlichem GB` ausgibt. (a) Ab welcher RAM-Menge steigt der Gewinn nicht mehr? Warum? (b) Was sagt Ihnen der „Gewinnzuwachs pro GB“ intuitiv? (Der Begriff dafür — *Schattenpreis* — folgt in [Kapitel 5](#kap-lp).)
|
||||
|
||||
|
|
@ -2131,11 +2131,11 @@ $$
|
|||
|
||||
| Problemtyp | Konvex? | Konsequenz |
|
||||
| --- | --- | --- |
|
||||
| Lineares Programm ([LP](#gloss:lineare-programmierung-lp){.glossar-link}) | **ja** | Globales Optimum, Sekunden bis Minuten selbst bei $10^6$ Variablen |
|
||||
| Lineares Programm ([LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}) | **ja** | Globales Optimum, Sekunden bis Minuten selbst bei $10^6$ Variablen |
|
||||
| Quadratisches Programm mit $\mathbf{P} \succeq 0$ | **ja** | Globales Optimum, effizient ([Kapitel 11](#kap-qp-nlp), [Kapitel 19](#kap-markowitz)) |
|
||||
| Ganzzahlige Variablen ([MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}) | **nein** | Der zulässige Bereich ist ein Punktgitter, keine zusammenhängende Menge — [NP-schwer](#gloss:np-schwer){.glossar-link}`\index{NP-schwer}`{=latex} ([Kapitel 6](#kap-milp)) |
|
||||
| Ganzzahlige Variablen ([MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}) | **nein** | Der zulässige Bereich ist ein Punktgitter, keine zusammenhängende Menge — [NP-schwer](#gloss:np-schwer){.glossar-link}`\index{NP-schwer}`{=latex} ([Kapitel 6](#kap-milp)) |
|
||||
| Quadratisches Programm mit indefinitem $\mathbf{P}$ | **nein** | Nur lokale Optima; eine ungültige [Kovarianzmatrix](#gloss:kovarianzmatrix){.glossar-link}`\index{Kovarianzmatrix}`{=latex} ist ein typischer Auslöser (siehe [Abschnitt 11.5](#sec:qp-nlp-nichtlineare-optimierung-mit-scipy-optimize-minimize)) |
|
||||
| Allgemeines [NLP](#gloss:nichtlineare-programmierung-nlp){.glossar-link} mit beliebigen Funktionen | meist **nein** | `scipy.optimize` liefert nur ein lokales Optimum, abhängig vom Startpunkt |
|
||||
| Allgemeines [NLP (Nichtlineare Programmierung)](#gloss:nichtlineare-programmierung-nlp){.glossar-link} mit beliebigen Funktionen | meist **nein** | `scipy.optimize` liefert nur ein lokales Optimum, abhängig vom Startpunkt |
|
||||
|
||||
### Konvexität sichtbar machen
|
||||
|
||||
|
|
@ -2923,7 +2923,7 @@ und runden Sie Solver-Ergebnisse NIE ohne Toleranzpruefung.
|
|||
|
||||
## 3.1 In 5 Minuten gelöst {#sec:oekosystem-schnellstart}
|
||||
|
||||
> **🚀 In 5 Minuten gelöst: Ein [LP](#gloss:lineare-programmierung-lp){.glossar-link} ohne jede Installation**
|
||||
> **🚀 In 5 Minuten gelöst: Ein [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} ohne jede Installation**
|
||||
>
|
||||
> Ein Futtermittelhersteller mischt zwei Rohstoffe zu möglichst geringen Kosten. Jeder Kilogramm Mischung muss mindestens 20 g Protein und 5 g Fett enthalten.
|
||||
>
|
||||
|
|
@ -2987,7 +2987,7 @@ Nach diesem Kapitel können Sie …
|
|||
Im modernen Operations Research schreibt man Optimierungsalgorithmen nicht selbst. Man nutzt eine **zweischichtige Architektur**`\index{Zweischichtige Architektur}`{=latex}:
|
||||
|
||||
1. **Modellierungsschicht (*Frontend*, DSL):** Python-Bibliotheken, mit denen Entscheidungsvariablen, Zielfunktion und Nebenbedingungen in mathematiknaher Syntax formuliert werden. Hier arbeiten Sie.
|
||||
2. **Solver-Schicht (*Backend*, Engine):** Hochoptimierte C++- oder Fortran-Bibliotheken, die das Modell in Matrixstrukturen übersetzen und mit spezialisierten Algorithmen lösen ([Dual Simplex](#gloss:dual-simplex){.glossar-link}`\index{Dual Simplex}`{=latex}, Interior-Point`\index{Interior-Point-Verfahren}`{=latex}, [Branch-and-Cut](#gloss:branch-and-cut){.glossar-link}`\index{Branch-and-Cut}`{=latex}, [CDCL](#gloss:cdcl){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link}-Suche`\index{CDCL}`{=latex}).
|
||||
2. **Solver-Schicht (*Backend*, Engine):** Hochoptimierte C++- oder Fortran-Bibliotheken, die das Modell in Matrixstrukturen übersetzen und mit spezialisierten Algorithmen lösen ([Dual Simplex](#gloss:dual-simplex){.glossar-link}`\index{Dual Simplex}`{=latex}, Interior-Point`\index{Interior-Point-Verfahren}`{=latex}, [Branch-and-Cut](#gloss:branch-and-cut){.glossar-link}`\index{Branch-and-Cut}`{=latex}, [CDCL](#gloss:cdcl){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link}-Suche`\index{CDCL}`{=latex}).
|
||||
|
||||

|
||||
|
||||
|
|
@ -3002,9 +3002,9 @@ Im modernen Operations Research schreibt man Optimierungsalgorithmen nicht selbs
|
|||
| Bibliothek | Stärken & Problemklassen | Wann einsetzen? | Typische Backends |
|
||||
| --- | --- | --- | --- |
|
||||
| `scipy.optimize` | Standard-LPs, kontinuierliche nichtlineare Optimierung, Wurzelsuche | Für elementare LPs und schnelle Prototypen ohne zusätzliche schwere Abhängigkeiten | HiGHS (`highs-ds`, `highs-ipm`) |
|
||||
| `ortools` (Google) | Diskrete Planung, Schichten, Vertretungspläne, Routing ([VRP](#gloss:vehicle-routing-problem-vrp){.glossar-link}/[TSP](#gloss:tsp-traveling-salesperson-problem){.glossar-link}), kombinatorische Logik | Wenn diskrete Ja/Nein-Entscheidungen, Zeitfenster und Wenn-Dann-Regeln dominieren | [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex}, [GLOP](#gloss:glop){.glossar-link}, Routing Engine |
|
||||
| `cvxpy` | Konvexe Optimierung, quadratische Programme, Risikomodelle, Portfolios | **Erste Wahl für Finanzoptimierung**, Markowitz, [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link}, $L_1$-[Transaktionskosten](#gloss:transaktionskosten){.glossar-link}`\index{Transaktionskosten}`{=latex} | Clarabel, OSQP, ECOS, SCS, HiGHS |
|
||||
| `highspy` | Direkte Solver-Steuerung für LP/[MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}, maximale Kontrolle | Wenn Sie Modelle wiederholt und schnell aufbauen oder Solver-Details steuern müssen | HiGHS |
|
||||
| `ortools` (Google) | Diskrete Planung, Schichten, Vertretungspläne, Routing ([VRP (Vehicle Routing Problem)](#gloss:vehicle-routing-problem-vrp){.glossar-link}/[TSP (Traveling Salesperson Problem)](#gloss:tsp-traveling-salesperson-problem){.glossar-link}), kombinatorische Logik | Wenn diskrete Ja/Nein-Entscheidungen, Zeitfenster und Wenn-Dann-Regeln dominieren | [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex}, [GLOP](#gloss:glop){.glossar-link}, Routing Engine |
|
||||
| `cvxpy` | Konvexe Optimierung, quadratische Programme, Risikomodelle, Portfolios | **Erste Wahl für Finanzoptimierung**, Markowitz, [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link}, $L_1$-[Transaktionskosten](#gloss:transaktionskosten){.glossar-link}`\index{Transaktionskosten}`{=latex} | Clarabel, OSQP, ECOS, SCS, HiGHS |
|
||||
| `highspy` | Direkte Solver-Steuerung für LP/[MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}, maximale Kontrolle | Wenn Sie Modelle wiederholt und schnell aufbauen oder Solver-Details steuern müssen | HiGHS |
|
||||
| `Pyomo` | Universelle Modellierungssprache (LP, MILP, [MINLP](#gloss:minlp){.glossar-link}`\index{MINLP}`{=latex}) | Industrielle Großmodelle mit strikter Trennung von Daten und Modell | HiGHS, Gurobi, CPLEX, [SCIP](#gloss:scip){.glossar-link}`\index{SCIP}`{=latex}, IPOPT |
|
||||
| `Linopy` | LP/MILP über beschriftete Arrays (`xarray`) | Modelle mit zehntausenden gleichartigen Nebenbedingungen (Energie, Netze, Zeitreihen) | HiGHS, GLPK, CBC, Gurobi |
|
||||
|
||||
|
|
@ -3012,7 +3012,7 @@ Im modernen Operations Research schreibt man Optimierungsalgorithmen nicht selbs
|
|||
|
||||
Statt die Tabelle auswendig zu lernen, beantworten Sie drei Fragen:
|
||||
|
||||
> **Frage 1: Gibt es Ja/Nein-Entscheidungen oder Reihenfolgen?** → **Ja:** [OR-Tools](#gloss:or-tools){.glossar-link}`\index{OR-Tools}`{=latex} ([CP](#gloss:constraint-programming-cp){.glossar-link}-SAT) bei Zuweisung/[Scheduling](#gloss:scheduling){.glossar-link}, oder MILP über HiGHS bei ökonomischen Fixkostenmodellen. → **Nein:** weiter zu Frage 2.
|
||||
> **Frage 1: Gibt es Ja/Nein-Entscheidungen oder Reihenfolgen?** → **Ja:** [OR-Tools](#gloss:or-tools){.glossar-link}`\index{OR-Tools}`{=latex} ([CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-SAT) bei Zuweisung/[Scheduling](#gloss:scheduling){.glossar-link}, oder MILP über HiGHS bei ökonomischen Fixkostenmodellen. → **Nein:** weiter zu Frage 2.
|
||||
>
|
||||
> **Frage 2: Ist die Zielfunktion linear?** → **Ja:** `scipy.optimize.linprog` (klein) oder `highspy` (groß, wiederholt). → **Nein, aber konvex** (Quadrate, Normen, `log`, `exp` in konvexer Kombination): **CVXPY**. → **Nein und nicht konvex:** `scipy.optimize.minimize` — im Bewusstsein, dass nur ein lokales Optimum herauskommt.
|
||||
>
|
||||
|
|
@ -3170,7 +3170,7 @@ Tragfähig ist stattdessen: **jeder Solver eine gewöhnliche Funktion`\index{Kon
|
|||
|
||||
> **⚠️ `max_tasks_per_child=1` ist nicht optional** Ein Pool ohne diese Angabe ist der **Normalfall** — er soll seine Arbeiter ja wiederverwenden. Wer die Isolation über einen Pool herstellt und das vergisst, hat einen Prozesswechsel programmiert, aber keine Isolation gewonnen: Die zweite Aufgabe landet im selben Interpreter wie die erste. Der Absturz kommt dann nicht beim ersten Solver, sondern beim zweiten — und sieht aus wie ein Problem des zweiten.
|
||||
|
||||
Denselben Aufbau verwenden `Solverwechsel_CPSAT_HiGHS.py` ([Kapitel 22](#kap-praxisfallen)) und `Benchmark_Skalierung.py` ([Kapitel 23](#kap-testing)). Dort wandern zusätzlich **Datenobjekte** über die Prozessgrenze statt Zeichenketten — möglich, weil Domänenmodell und Lösungs-[DTO](#gloss:dto-data-transfer-object){.glossar-link} keinen Solver kennen ([Abschnitt 22.6](#sec:praxisfallen-or-kern)).
|
||||
Denselben Aufbau verwenden `Solverwechsel_CPSAT_HiGHS.py` ([Kapitel 22](#kap-praxisfallen)) und `Benchmark_Skalierung.py` ([Kapitel 23](#kap-testing)). Dort wandern zusätzlich **Datenobjekte** über die Prozessgrenze statt Zeichenketten — möglich, weil Domänenmodell und Lösungs-[DTO (Data Transfer Object)](#gloss:dto-data-transfer-object){.glossar-link} keinen Solver kennen ([Abschnitt 22.6](#sec:praxisfallen-or-kern)).
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
|
|
@ -3389,7 +3389,7 @@ Bei kleinen Modellen wirkt das umständlich. Bei realen Modellen mit 100 000 Var
|
|||
| Fahrzeugtouren | **OR-Tools Routing** | Fertige Metaheuristiken, jahrzehntelang optimiert |
|
||||
| MILP mit Fixkosten, Kardinalität | `highspy` oder CP-SAT | Branch-and-Cut auf ökonomischer Struktur |
|
||||
| 50 000+ Variablen, wiederholte Läufe | `highspy` oder Pyomo | Modellaufbau wird sonst zum Engpass |
|
||||
| Nichtkonvexes [NLP](#gloss:nichtlineare-programmierung-nlp){.glossar-link} | `scipy.optimize.minimize` | Bewusst mit mehreren Startpunkten arbeiten |
|
||||
| Nichtkonvexes [NLP (Nichtlineare Programmierung)](#gloss:nichtlineare-programmierung-nlp){.glossar-link} | `scipy.optimize.minimize` | Bewusst mit mehreren Startpunkten arbeiten |
|
||||
|
||||
> **🎯 Merksatz** Wählen Sie den Solver nach der **Struktur des Modells**, nicht nach Gewohnheit. Ein Zuweisungsproblem in CVXPY zu quälen oder ein Portfolio mit CP-SAT nachzubauen kostet Laufzeit und Nerven — und meist auch Lösungsqualität.
|
||||
|
||||
|
|
@ -4655,8 +4655,8 @@ Dieselbe Barriere gibt es rückwärts. Diese Sätze haben sich bewährt, wenn ei
|
|||
| bindende Bedingung mit Dualwert 0 | „Die Regel berührt den Plan, kostet uns aber nichts — dort zu verhandeln bringt nichts." |
|
||||
| `INFEASIBLE` | „Ihre Regeln widersprechen sich." **Nicht:** „Der Computer schafft es nicht." |
|
||||
| Optimalitätslücke von 2 % | „Besser als das hier geht es höchstens um 2 % — und die liegen unter unserer Datenungenauigkeit." |
|
||||
| [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} | „Wenn es schiefgeht, verlieren wir im Mittel so viel." (Der [VaR](#gloss:value-at-risk-var){.glossar-link} sagt nur, **ob** es schiefgeht.) |
|
||||
| [EVPI](#gloss:evpi-expected-value-of-perfect-information){.glossar-link} | „Selbst eine perfekte Prognose wäre uns höchstens so viel wert." |
|
||||
| [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} | „Wenn es schiefgeht, verlieren wir im Mittel so viel." (Der [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link} sagt nur, **ob** es schiefgeht.) |
|
||||
| [EVPI (Expected Value of Perfect Information)](#gloss:evpi-expected-value-of-perfect-information){.glossar-link} | „Selbst eine perfekte Prognose wäre uns höchstens so viel wert." |
|
||||
| [Relaxation](#gloss:relaxation){.glossar-link}`\index{Relaxation}`{=latex} | „Wir haben die Regel probeweise gelockert, um zu sehen, was sie kostet." |
|
||||
| Chance Constraint | „Der Plan hält in 95 von 100 Fällen — und der nächste Prozentpunkt kostet …" |
|
||||
|
||||
|
|
@ -4769,7 +4769,7 @@ Vier Kapitel, vier Werkzeugkästen. Welcher zu Ihrem Problem passt, entscheiden
|
|||
|
||||

|
||||
|
||||
> **🎯 Merksatz zum Diagramm** Die erste Frage ist die wichtigste — und sie lautet **nicht** „welcher [Solver](#gloss:solver){.glossar-link} ist der schnellste?“, sondern „welche **Struktur** hat mein Problem?“. Ein [Zuordnungsproblem](#gloss:zuordnungsproblem){.glossar-link}`\index{Zuordnungsproblem (1:1)}`{=latex} braucht keinen [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}-Solver, sondern eine Zeile `linear_sum_assignment`. Ein Dienstplan gehört nicht in ein [LP](#gloss:lineare-programmierung-lp){.glossar-link}, sondern zu [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex}. Wer die Struktur erkennt, hat die halbe Laufzeit gespart, bevor die erste Zeile Code geschrieben ist.
|
||||
> **🎯 Merksatz zum Diagramm** Die erste Frage ist die wichtigste — und sie lautet **nicht** „welcher [Solver](#gloss:solver){.glossar-link} ist der schnellste?“, sondern „welche **Struktur** hat mein Problem?“. Ein [Zuordnungsproblem](#gloss:zuordnungsproblem){.glossar-link}`\index{Zuordnungsproblem (1:1)}`{=latex} braucht keinen [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}-Solver, sondern eine Zeile `linear_sum_assignment`. Ein Dienstplan gehört nicht in ein [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}, sondern zu [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex}. Wer die Struktur erkennt, hat die halbe Laufzeit gespart, bevor die erste Zeile Code geschrieben ist.
|
||||
|
||||
Fällt Ihr Problem durch das Diagramm hindurch — nichtlineare [Zielfunktion](#gloss:zielfunktion){.glossar-link}`\index{Zielfunktion}`{=latex}, unsichere Daten, Entscheidungen über mehrere Zeitstufen —, dann ist [Teil III](#teil-nichtlinear) der richtige Ort. Dort steht ein zweites Diagramm für genau diese Fälle.
|
||||
|
||||
|
|
@ -5615,7 +5615,7 @@ Solver rechnen mit endlicher Genauigkeit und brechen ab, sobald ihre eigene Tole
|
|||
|
||||
| Toleranz | Was sie steuert | Typischer Standardwert |
|
||||
| --- | --- | --- |
|
||||
| **Primale Zulässigkeit** | Wie weit darf $\mathbf{A}\mathbf{x}$ die Schranke $\mathbf{b}$ überschreiten? | $10^{-7}$ (HiGHS), $10^{-6}$ ([CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link}) |
|
||||
| **Primale Zulässigkeit** | Wie weit darf $\mathbf{A}\mathbf{x}$ die Schranke $\mathbf{b}$ überschreiten? | $10^{-7}$ (HiGHS), $10^{-6}$ ([CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link}) |
|
||||
| **Duale Zulässigkeit** (Optimalität) | Wie weit dürfen die reduzierten Kosten das falsche Vorzeichen haben? | $10^{-7}$ |
|
||||
| **Ganzzahligkeit** | Wie weit darf eine Ganzzahlvariable von der nächsten ganzen Zahl abweichen? | $10^{-6}$ ([Kapitel 6](#kap-milp)) |
|
||||
|
||||
|
|
@ -5990,9 +5990,9 @@ brauchbare Aussage. Ein erfundener Einzelwert ist es nicht.
|
|||
>
|
||||
> **Worum geht es?** Um Entscheidungen, die nicht teilbar sind: ganze Maschinen, Ja/Nein, „höchstens fünf davon“. Wir zeigen mit einem konkreten Gegenbeispiel, warum Runden **falsch** ist, und lernen die Modellierungstricks, mit denen sich logische Regeln in lineare Ungleichungen übersetzen lassen.
|
||||
>
|
||||
> **Voraussetzungen:** [Kapitel 5](#kap-lp) ([LP](#gloss:lineare-programmierung-lp){.glossar-link}, [Relaxation](#gloss:relaxation){.glossar-link}`\index{Relaxation}`{=latex}, Schranken).
|
||||
> **Voraussetzungen:** [Kapitel 5](#kap-lp) ([LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}, [Relaxation](#gloss:relaxation){.glossar-link}`\index{Relaxation}`{=latex}, Schranken).
|
||||
>
|
||||
> **Danach können Sie:** Fixkosten, Entweder-Oder, Wenn-Dann und Kardinalitätsgrenzen modellieren, ein [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} mit [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} oder [HiGHS](#gloss:highs){.glossar-link} lösen, den [MIP-Gap](#gloss:mip-gap){.glossar-link}`\index{MIP-Gap}`{=latex} als Zusage an den Auftraggeber lesen — und ein Ergebnis erkennen, das nur deshalb gut aussieht, weil das Big-M zu groß gewählt war.
|
||||
> **Danach können Sie:** Fixkosten, Entweder-Oder, Wenn-Dann und Kardinalitätsgrenzen modellieren, ein [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} mit [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} oder [HiGHS](#gloss:highs){.glossar-link} lösen, den [MIP-Gap](#gloss:mip-gap){.glossar-link}`\index{MIP-Gap}`{=latex} als Zusage an den Auftraggeber lesen — und ein Ergebnis erkennen, das nur deshalb gut aussieht, weil das Big-M zu groß gewählt war.
|
||||
>
|
||||
> **Zeitbedarf:** ca. 6,5 Stunden.
|
||||
>
|
||||
|
|
@ -7258,7 +7258,7 @@ Hier wirkt der Hinweis: Faktor 2,2 bzw. 1,4. Beachten Sie aber, dass der Faktor
|
|||
> * **`if status == OPTIMAL: ... else: return None`.** Wirft eine Lösung weg, die 9 % vom Optimum entfernt und damit vollkommen brauchbar ist. Werten Sie den Gap aus, nicht nur den Status.
|
||||
> * **Zeitlimit ohne Gap-Auswertung.** Ein Limit erzwingt ein Ende, sagt aber nichts über die Qualität. Ohne den Gap wissen Sie nicht, ob Sie 0,1 % oder 60 % danebenliegen.
|
||||
> * **Warm-Start als Selbstverständlichkeit.** Messen Sie ihn — auf Ihrer Instanzklasse, gegen den kalten Lauf. In der Hälfte der Fälle bringt er nichts.
|
||||
> * **Einen Hinweis für eine unzulässige Lösung geben.** [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} und HiGHS verwerfen ihn dann stillschweigend. Prüfen Sie Ihre Startlösung vorher auf Zulässigkeit — sonst messen Sie einen Effekt, den es gar nicht gibt.
|
||||
> * **Einen Hinweis für eine unzulässige Lösung geben.** [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} und HiGHS verwerfen ihn dann stillschweigend. Prüfen Sie Ihre Startlösung vorher auf Zulässigkeit — sonst messen Sie einen Effekt, den es gar nicht gibt.
|
||||
|
||||
> **🎯 Merksatz** Ein Warm-Start kann das Ergebnis nie verfälschen — im schlimmsten Fall kostet er Zeit. Genau deshalb darf man ihn ausprobieren. Aber man muss ihn auch **messen**, statt an ihn zu glauben.
|
||||
|
||||
|
|
@ -7668,7 +7668,7 @@ funktioniert immer.
|
|||
> Fr -> Abel
|
||||
> ```
|
||||
|
||||
**Elf Zeilen Modell, und der Plan steht.** Beachten Sie besonders die Zeile `m.AddExactlyOne(...)`. Sie sagt wörtlich, was gemeint ist: *genau eine* Person je Tag. In [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} hätte man dafür eine Gleichung $\sum_p x_{p,d} = 1$ aufgestellt — machbar, aber schon eine Übersetzungsleistung. Bei Regeln wie „diese beiden Dienste nicht direkt hintereinander“ oder „höchstens eine Nachtschicht pro Woche“ wächst dieser Übersetzungsaufwand rasch; in [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} bleibt er eine Zeile.
|
||||
**Elf Zeilen Modell, und der Plan steht.** Beachten Sie besonders die Zeile `m.AddExactlyOne(...)`. Sie sagt wörtlich, was gemeint ist: *genau eine* Person je Tag. In [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} hätte man dafür eine Gleichung $\sum_p x_{p,d} = 1$ aufgestellt — machbar, aber schon eine Übersetzungsleistung. Bei Regeln wie „diese beiden Dienste nicht direkt hintereinander“ oder „höchstens eine Nachtschicht pro Woche“ wächst dieser Übersetzungsaufwand rasch; in [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} bleibt er eine Zeile.
|
||||
|
||||
**Und jetzt sehen Sie sich das Ergebnis genau an.** *Cor bekommt keinen einzigen Dienst.* Dane arbeitet Montag **und** Dienstag hintereinander. Ist das ein Fehler?
|
||||
|
||||
|
|
@ -7695,7 +7695,7 @@ Nach diesem Kapitel können Sie …
|
|||
|
||||
## 7.3 Ein anderes Denkmodell {#sec:cpsat-ein-anderes-denkmodell}
|
||||
|
||||
Während [LP](#gloss:lineare-programmierung-lp){.glossar-link} und MILP auf algebraischen Gleichungen und Simplex-Matrizen beruhen, kommt **Constraint Programming (CP)**`\index{Constraint Programming (CP)}`{=latex} aus der künstlichen Intelligenz:
|
||||
Während [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} und MILP auf algebraischen Gleichungen und Simplex-Matrizen beruhen, kommt **Constraint Programming (CP)**`\index{Constraint Programming (CP)}`{=latex} aus der künstlichen Intelligenz:
|
||||
|
||||
| | MILP | Constraint Programming |
|
||||
| --- | --- | --- |
|
||||
|
|
@ -7823,7 +7823,7 @@ CP-SAT stellt mächtige Makros`\index{Globale Constraints}`{=latex} bereit, die
|
|||
| `NewIntervalVar(start, size, end, name)` | Zeitintervall mit Start, Dauer, Ende | Aufträge, Operationen, Belegungen |
|
||||
| `AddNoOverlap(intervals)` | Intervalle überschneiden sich **nicht** | Eine Maschine, ein Raum, eine Person |
|
||||
| `AddCumulative(intervals, bedarfe, kapazitaet)` | Zu **keinem Zeitpunkt** übersteigt der Parallelverbrauch die Kapazität | Personalstärke, Stromlast, Kranstunden |
|
||||
| `AddCircuit(arcs)` | Die gewählten Kanten bilden **einen** Rundweg | [TSP](#gloss:tsp-traveling-salesperson-problem){.glossar-link}-artige Reihenfolgeprobleme |
|
||||
| `AddCircuit(arcs)` | Die gewählten Kanten bilden **einen** Rundweg | [TSP (Traveling Salesperson Problem)](#gloss:tsp-traveling-salesperson-problem){.glossar-link}-artige Reihenfolgeprobleme |
|
||||
| `.OnlyEnforceIf(bool)` | Bedingung gilt **nur wenn** | Reifizierung: Regel an-/abschaltbar machen |
|
||||
|
||||
> **🔤 Formel-Übersetzer: was ein globales Constraint zusichert**
|
||||
|
|
@ -9314,7 +9314,7 @@ Nach diesem Kapitel können Sie …
|
|||
2. … den **Flusserhaltungssatz**`\index{Flusserhaltung}`{=latex} aufstellen und seine Bedeutung erklären.
|
||||
3. … begründen, warum Zuordnungsprobleme **ohne** Ganzzahligkeitsbedingung ganzzahlig lösbar sind (totale Unimodularität`\index{Totale Unimodularität}`{=latex}).
|
||||
4. … ein Vehicle Routing Problem mit Kapazitäten und Zeitfenstern mit [OR-Tools](#gloss:or-tools){.glossar-link}`\index{OR-Tools}`{=latex} lösen.
|
||||
5. … einschätzen, wann ein spezialisierter Algorithmus einem allgemeinen [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} überlegen ist.
|
||||
5. … einschätzen, wann ein spezialisierter Algorithmus einem allgemeinen [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} überlegen ist.
|
||||
6. … begründen, warum eine gierige Zuordnung systematisch schlechter ist als eine gemeinsame Optimierung.
|
||||
7. … einen Tourenplan gegen die Wirklichkeit prüfen — unabhängig von den Bausteinen, aus denen das Modell gebaut wurde.
|
||||
|
||||
|
|
@ -9513,7 +9513,7 @@ $$
|
|||
|
||||
> **Satz.** Die Extrempunkte der Menge`\index{Konvexität!Menge}`{=latex} aller doppelt-stochastischen Matrizen (alle Zeilensummen $= 1$, alle Spaltensummen $= 1$, $x_{ij} \ge 0$) sind **genau** die Permutationsmatrizen (alle $x_{ij} \in \{0,1\}$).
|
||||
|
||||
**Warum das praktisch enorm wichtig ist:**`\index{Satz von Birkhoff und von Neumann}`{=latex} Nach dem Fundamentalsatz aus [Kapitel 2](#kap-fundament) liegt das [LP](#gloss:lineare-programmierung-lp){.glossar-link}-Optimum in einer Ecke. Die Ecken sind hier laut Satz automatisch 0/1-wertig. Also gilt:
|
||||
**Warum das praktisch enorm wichtig ist:**`\index{Satz von Birkhoff und von Neumann}`{=latex} Nach dem Fundamentalsatz aus [Kapitel 2](#kap-fundament) liegt das [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}-Optimum in einer Ecke. Die Ecken sind hier laut Satz automatisch 0/1-wertig. Also gilt:
|
||||
|
||||
> **🎯 Merksatz** Beim Zuordnungsproblem müssen Sie die Ganzzahligkeit **nicht** fordern — ein gewöhnlicher LP-Solver liefert von selbst eine 0/1-Lösung. Sie sparen sich damit die NP-Schwere von Branch-and-Bound vollständig.
|
||||
|
||||
|
|
@ -9651,7 +9651,7 @@ if __name__ == "__main__":
|
|||
|
||||
## 8.5 Das Vehicle Routing Problem mit Zeitfenstern {#sec:graphen-das-vehicle-routing-problem-mit-zeitfenstern}
|
||||
|
||||
Das **Traveling Salesperson Problem ([TSP](#gloss:tsp-traveling-salesperson-problem){.glossar-link})**`\index{TSP (Traveling Salesperson Problem)}`{=latex}, deutsch *Problem des Handlungsreisenden*, fragt nach der kürzesten Rundreise durch $N$ Städte. Das **Capacitated Vehicle Routing Problem with Time Windows ([CVRPTW](#gloss:cvrptw){.glossar-link})**`\index{CVRPTW}`{=latex} erweitert es auf eine **Flotte** mit Kapazitätsgrenzen und Kundenzeitfenstern $[e_i, l_i]$.
|
||||
Das **Traveling Salesperson Problem ([TSP (Traveling Salesperson Problem)](#gloss:tsp-traveling-salesperson-problem){.glossar-link})**`\index{TSP (Traveling Salesperson Problem)}`{=latex}, deutsch *Problem des Handlungsreisenden*, fragt nach der kürzesten Rundreise durch $N$ Städte. Das **Capacitated Vehicle Routing Problem with Time Windows ([CVRPTW](#gloss:cvrptw){.glossar-link})**`\index{CVRPTW}`{=latex} erweitert es auf eine **Flotte** mit Kapazitätsgrenzen und Kundenzeitfenstern $[e_i, l_i]$.
|
||||
|
||||

|
||||
|
|
@ -9851,7 +9851,7 @@ if __name__ == "__main__":
|
|||
loese_cvrptw()
|
||||
```
|
||||
|
||||
> **⚠️ Typische Fehler beim [VRP](#gloss:vehicle-routing-problem-vrp){.glossar-link}**
|
||||
> **⚠️ Typische Fehler beim [VRP (Vehicle Routing Problem)](#gloss:vehicle-routing-problem-vrp){.glossar-link}**
|
||||
>
|
||||
> * **`Min(CumulVar)` mit „Ankunftszeit“ verwechseln.** Der Solver liefert ein *Intervall* möglicher Zeiten. `Min()` ist die früheste, `Max()` die späteste zulässige Zeit — die tatsächliche Fahrt kann irgendwo dazwischen starten.
|
||||
> * **Servicezeit im Depot mitzählen.** Beim Start am Depot fällt keine Servicezeit an, sonst verschiebt sich der ganze Plan.
|
||||
|
|
@ -10165,7 +10165,7 @@ plausibel aussieht.
|
|||
* **Totale Unimodularität ist zerbrechlich.** Eine einzige zusätzliche Bedingung, die nicht ins Schema passt — Kardinalität, Fixkosten, Mindestmenge —, zerstört sie. Prüfen Sie das, bevor Sie sich auf die Struktur verlassen.
|
||||
* **Der beste erste Zug ist selten Teil der besten Gesamtlösung.** Gierige Regeln kosten schon bei vier Zuordnungen 8 %.
|
||||
|
||||
**Ausblick.** [Teil III](#teil-nichtlinear) verlässt die lineare Welt. [Kapitel 11](#kap-qp-nlp) führt quadratische Zielfunktionen und die [KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}-Bedingungen ein — das mathematische Fundament der Portfoliooptimierung.
|
||||
**Ausblick.** [Teil III](#teil-nichtlinear) verlässt die lineare Welt. [Kapitel 11](#kap-qp-nlp) führt quadratische Zielfunktionen und die [KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}-Bedingungen ein — das mathematische Fundament der Portfoliooptimierung.
|
||||
|
||||
|
||||
---
|
||||
|
|
@ -11039,7 +11039,7 @@ Drei Größen, drei völlig verschiedene Empfehlungen:
|
|||
|
||||
| Aufträge | Empfehlung |
|
||||
| ---: | --- |
|
||||
| 60 | **Exakt.** [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} beweist das Optimum in 2 Sekunden. Die Metaheuristik liegt 3,8 % daneben — und wüsste es nicht. |
|
||||
| 60 | **Exakt.** [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} beweist das Optimum in 2 Sekunden. Die Metaheuristik liegt 3,8 % daneben — und wüsste es nicht. |
|
||||
| 200 | **Exakt.** Kein Beweis mehr, aber der Gap liegt unter 1 %, und der Wert ist rund 11 % besser als der heuristische. |
|
||||
| 500 | **Heuristisch.** CP-SAT liefert eine Lösung, die 5,2 % **schlechter** ist als die Faustregel eines Meisters. |
|
||||
|
||||
|
|
@ -11059,7 +11059,7 @@ Das ist der Unterschied zwischen *besser als vorher* und *gut*. Eine Metaheurist
|
|||
|
||||
Die Tabelle oben endet mit einem Widerspruch. Bei 500 Aufträgen scheitert der exakte Solver an der **Größe**; die Metaheuristik scheitert an der **Kleinheit ihrer Züge** — sie verschiebt jeweils einen einzigen Auftrag und kann eine ganze Passage nicht auf einmal umbauen.
|
||||
|
||||
**Large Neighborhood Search**`\index{Large Neighborhood Search}`{=latex} ([LNS](#gloss:large-neighborhood-search-lns){.glossar-link}) setzt beide ein, jeden für das, was er kann:
|
||||
**Large Neighborhood Search**`\index{Large Neighborhood Search}`{=latex} ([LNS (Large Neighborhood Search)](#gloss:large-neighborhood-search-lns){.glossar-link}) setzt beide ein, jeden für das, was er kann:
|
||||
|
||||
| Schritt | Was passiert |
|
||||
| --- | --- |
|
||||
|
|
@ -11623,7 +11623,7 @@ Nach diesem Kapitel können Sie …
|
|||
|
||||
1. … erklären, warum das naheliegende Zuordnungsmodell an **Symmetrie** scheitert.
|
||||
2. … ein Problem in **Master** und **Pricing-Teilproblem** zerlegen.
|
||||
3. … die Schleife schreiben: Master-[LP](#gloss:lineare-programmierung-lp){.glossar-link} lösen, Dualwerte auslesen, Teilproblem lösen, Spalte hinzufügen.
|
||||
3. … die Schleife schreiben: Master-[LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} lösen, Dualwerte auslesen, Teilproblem lösen, Spalte hinzufügen.
|
||||
4. … das Abbruchkriterium über die **reduzierten Kosten** begründen.
|
||||
5. … an einer Kennzahl der Instanz abschätzen, ob sich das Verfahren lohnt.
|
||||
|
||||
|
|
@ -12198,7 +12198,7 @@ Und selbst dort, wo die Ersparnis null ist, liefert das Verfahren etwas, das die
|
|||
|
||||
## 10.10 Selbsttest {#sec:dekomposition-selbsttest}
|
||||
|
||||
1. Erklären Sie Symmetrie in einem [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} an einem Beispiel aus Ihrem Arbeitsumfeld.
|
||||
1. Erklären Sie Symmetrie in einem [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} an einem Beispiel aus Ihrem Arbeitsumfeld.
|
||||
2. Was ist beim Zuschnitt eine „Spalte", und was steht darin?
|
||||
3. Woher kommen die Preise, mit denen das Teilproblem rechnet?
|
||||
4. Warum ist das Verfahren exakt, obwohl es fast alle Muster nie ansieht?
|
||||
|
|
@ -12226,8 +12226,8 @@ Sechs Kapitel, sechs Werkzeuge. Jedes einzelne wurde im Zusammenhang gezeigt; hi
|
|||
|
||||
| Verfahren | Wofür es gebaut ist | Was Sie bekommen | Wo es aufhört | Kapitel |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| **[LP](#gloss:lineare-programmierung-lp){.glossar-link}** | teilbare Mengen, lineare Zusammenhänge | beweisbares Optimum **plus Schattenpreise** | sobald etwas ganzzahlig sein muss | [Kapitel 5](#kap-lp) |
|
||||
| **[MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}** | Ja/Nein-Entscheidungen, Fixkosten, Logik | beweisbares Optimum, Gap als Fortschrittsmaß | Laufzeit wächst mit der Zahl der Binärvariablen | [Kapitel 6](#kap-milp) |
|
||||
| **[LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}** | teilbare Mengen, lineare Zusammenhänge | beweisbares Optimum **plus Schattenpreise** | sobald etwas ganzzahlig sein muss | [Kapitel 5](#kap-lp) |
|
||||
| **[MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}** | Ja/Nein-Entscheidungen, Fixkosten, Logik | beweisbares Optimum, Gap als Fortschrittsmaß | Laufzeit wächst mit der Zahl der Binärvariablen | [Kapitel 6](#kap-milp) |
|
||||
| **[CP-SAT](#gloss:cp-sat){.glossar-link}**`\index{CP-SAT}`{=latex} | Zuweisung, Reihenfolge, Kalender, harte Logik | beweisbares Optimum, sehr ausdrucksstarke Bedingungen | keine Schattenpreise, keine stetigen Größen | [Kapitel 7](#kap-cpsat) |
|
||||
| **Graphenalgorithmen** | Flüsse, Zuordnung, Touren | oft **polynomiell** statt exponentiell | nur, wenn die Struktur wirklich passt | [Kapitel 8](#kap-graphen) |
|
||||
| **Metaheuristiken** | wenn der exakte [Solver](#gloss:solver){.glossar-link} aussteigt | eine gute Lösung in **fester Zeit** | keine Garantie, kein Beweis, keine Schranke | [Kapitel 9](#kap-metaheuristiken) |
|
||||
|
|
@ -12239,8 +12239,8 @@ Sechs Kapitel, sechs Werkzeuge. Jedes einzelne wurde im Zusammenhang gezeigt; hi
|
|||
|
||||
| Behauptung | Gemessen | Wo |
|
||||
| --- | --- | --- |
|
||||
| „Der exakte Solver ist immer besser." | Bei 500 Aufträgen liefert [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} eine Lösung, die **5,2 % schlechter** ist als die Faustregel eines Meisters | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| „Metaheuristiken sind ungenau." | Faustregel 2 497 → Annealing 2 343 → Annealing plus [LNS](#gloss:large-neighborhood-search-lns){.glossar-link} **2 289** Minuten [Rüstzeit](#gloss:ruestzeit){.glossar-link}`\index{Rüstzeit}`{=latex}; untere Schranke 1 768 | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| „Der exakte Solver ist immer besser." | Bei 500 Aufträgen liefert [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} eine Lösung, die **5,2 % schlechter** ist als die Faustregel eines Meisters | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| „Metaheuristiken sind ungenau." | Faustregel 2 497 → Annealing 2 343 → Annealing plus [LNS (Large Neighborhood Search)](#gloss:large-neighborhood-search-lns){.glossar-link} **2 289** Minuten [Rüstzeit](#gloss:ruestzeit){.glossar-link}`\index{Rüstzeit}`{=latex}; untere Schranke 1 768 | [Kapitel 9](#kap-metaheuristiken) |
|
||||
| „Man muss alle Variablen aufschreiben." | 28 erzeugte Muster von **46 408** möglichen — und die Lösung ist beweisbar optimal | [Kapitel 10](#kap-dekomposition) |
|
||||
| „Dekomposition lohnt sich immer." | Bei drei Stücken je Rolle **11 %** Ersparnis, bei sechs **nichts** | [Kapitel 10](#kap-dekomposition) |
|
||||
| „Mit Seed ist der Lauf reproduzierbar." | Schon **zwei** Arbeiter liefern bei identischem Seed drei verschiedene Pläne zum selben Zielwert | [Abschnitt 7.7](#sec:cpsat-parallele-suche) |
|
||||
|
|
@ -12282,7 +12282,7 @@ Zwei weitere Kapitel schließen sich an, weil sie dieselbe Voraussetzung aufgebe
|
|||
>
|
||||
> **Voraussetzungen:** [Kapitel 2](#kap-fundament) (Konvexität, Eigenwerte), [Kapitel 5](#kap-lp) (Dualität, Schattenpreise). Gradienten werden in [Abschnitt 11.2](#sec:qp-nlp-lernziele) wiederholt.
|
||||
>
|
||||
> **Danach können Sie:** Ein quadratisches Programm aufstellen, die [KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}-Bedingungen anwenden, den Zusammenhang zwischen [Lagrange-Multiplikator](#gloss:lagrange-multiplikator){.glossar-link}`\index{Lagrange-Multiplikator}`{=latex} und [Schattenpreis](#gloss:schattenpreis){.glossar-link} erklären, eine gültige [Kovarianzmatrix](#gloss:kovarianzmatrix){.glossar-link}`\index{Kovarianzmatrix}`{=latex} konstruieren — und mit nicht-konvexen Problemen umgehen, ohne ein lokales Optimum für das Optimum zu halten.
|
||||
> **Danach können Sie:** Ein quadratisches Programm aufstellen, die [KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}-Bedingungen anwenden, den Zusammenhang zwischen [Lagrange-Multiplikator](#gloss:lagrange-multiplikator){.glossar-link}`\index{Lagrange-Multiplikator}`{=latex} und [Schattenpreis](#gloss:schattenpreis){.glossar-link} erklären, eine gültige [Kovarianzmatrix](#gloss:kovarianzmatrix){.glossar-link}`\index{Kovarianzmatrix}`{=latex} konstruieren — und mit nicht-konvexen Problemen umgehen, ohne ein lokales Optimum für das Optimum zu halten.
|
||||
>
|
||||
> **Zeitbedarf:** ca. 6,5 Stunden.
|
||||
>
|
||||
|
|
@ -12364,7 +12364,7 @@ Der letzte Term ist der entscheidende: Bei negativer Korrelation ist er **negati
|
|||
|
||||
Nach diesem Kapitel können Sie …
|
||||
|
||||
1. … ein **quadratisches Programm ([QP](#gloss:quadratische-programmierung-qp){.glossar-link})** aufstellen und von einem allgemeinen nichtlinearen Programm abgrenzen.
|
||||
1. … ein **quadratisches Programm ([QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link})** aufstellen und von einem allgemeinen nichtlinearen Programm abgrenzen.
|
||||
2. … die **KKT-Bedingungen** herleiten und auf ein Optimierungsproblem anwenden.
|
||||
3. … den Zusammenhang zwischen **Lagrange-Multiplikator** und **Schattenpreis**`\index{Schattenpreis}`{=latex} erklären.
|
||||
4. … zwischen **konvex**`\index{Konvexität}`{=latex} und **streng konvex**`\index{Konvexität!streng konvex}`{=latex} unterscheiden und eine gültige, positiv semidefinite **Kovarianzmatrix**`\index{Kovarianzmatrix}`{=latex} konstruieren.
|
||||
|
|
@ -12576,7 +12576,7 @@ lässt nur $x \le 3$ zu, und $\lambda^* = 4$ ist genau die Steigung von $f$ am R
|
|||
> | $g_i(\mathbf{x}^*) \le 0$ | „Der Plan hält alle Regeln ein.“ |
|
||||
> | $\lambda_i^* \ge 0$ | „Eine Grenze kann nur bremsen, nie antreiben.“ Ein negativer Preis wäre widersinnig. |
|
||||
> | $\lambda_i^* \cdot g_i(\mathbf{x}^*) = 0$ | „Was Reserve hat, ist nichts wert. Was etwas wert ist, ist ausgereizt.“ Nie beides. |
|
||||
> | $\lambda_i^*$ selbst | Der **Schattenpreis** von Bedingung $i$ — dieselbe Größe wie im [LP](#gloss:lineare-programmierung-lp){.glossar-link} ([Kapitel 5](#kap-lp)), nur für krumme Ränder. |
|
||||
> | $\lambda_i^*$ selbst | Der **Schattenpreis** von Bedingung $i$ — dieselbe Größe wie im [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} ([Kapitel 5](#kap-lp)), nur für krumme Ränder. |
|
||||
>
|
||||
> **Alle vier zusammen in einem Satz:** *Wir stehen an einer Stelle, an der jede Verbesserung an eine Grenze stößt — und wir wissen für jede dieser Grenzen, was ihre Lockerung wert wäre.*
|
||||
>
|
||||
|
|
@ -13243,7 +13243,7 @@ Wird zusätzlich noch ganzzahlig entschieden — „welche Anlage läuft überha
|
|||
|
||||
| Werkzeug | Art | Was es leistet |
|
||||
| --- | --- | --- |
|
||||
| **Ipopt** (über `cyipopt` oder [Pyomo](#gloss:pyomo){.glossar-link}`\index{Pyomo}`{=latex}) | lokaler [NLP](#gloss:nichtlineare-programmierung-nlp){.glossar-link}-Solver | Innere-Punkte-Verfahren für große, glatte NLPs mit tausenden Variablen — deutlich leistungsfähiger als `scipy`, aber ebenfalls **nur lokal** |
|
||||
| **Ipopt** (über `cyipopt` oder [Pyomo](#gloss:pyomo){.glossar-link}`\index{Pyomo}`{=latex}) | lokaler [NLP (Nichtlineare Programmierung)](#gloss:nichtlineare-programmierung-nlp){.glossar-link}-Solver | Innere-Punkte-Verfahren für große, glatte NLPs mit tausenden Variablen — deutlich leistungsfähiger als `scipy`, aber ebenfalls **nur lokal** |
|
||||
| **Bonmin**, **Couenne** | MINLP | Bonmin lokal, Couenne mit globaler Garantie für viele Klassen |
|
||||
| **[SCIP](#gloss:scip){.glossar-link}**`\index{SCIP}`{=latex}, **BARON**, **[Gurobi](#gloss:gurobi){.glossar-link}**`\index{Gurobi}`{=latex} | global | Beweisbar globales Optimum, mit entsprechendem Rechenaufwand |
|
||||
| **Pyomo** ([Abschnitt 3.7](#sec:oekosystem-pyomo-linopy)) | Modellierungsschicht | Bindet alle oben genannten an, ohne dass das Modell umgeschrieben werden muss |
|
||||
|
|
@ -13311,7 +13311,7 @@ else:
|
|||
> Sein erster Versuch mit CVXPY bricht ab:
|
||||
>
|
||||
> ```
|
||||
> [DCPError](#gloss:dcperror){.glossar-link}: Problem does not follow [DCP](#gloss:dcp-disciplined-convex-programming){.glossar-link} rules.
|
||||
> [DCPError](#gloss:dcperror){.glossar-link}: Problem does not follow [DCP (Disciplined Convex Programming)](#gloss:dcp-disciplined-convex-programming){.glossar-link} rules.
|
||||
> The objective is not DCP. Its following subexpressions are not: QuadForm(...)
|
||||
> ```
|
||||
>
|
||||
|
|
@ -13968,7 +13968,7 @@ deutlich teurer ist als Leerlauf (5 EUR).
|
|||
|
||||
**Lesen Sie die Vergleichstabelle von unten nach oben.** Die beiden extremen Haltungen sind die teuersten: Wer den Worst Case abdeckt (500 Einheiten), zahlt 5 000 € zu viel für Kapazität, die in 80 % der Fälle brachliegt. Wer optimistisch plant (100), zahlt 2 625 € Strafe für ständige Notzukäufe. Die naive Mittelwertplanung liegt dazwischen — aber eben auch nicht optimal.
|
||||
|
||||
Der **[EVPI](#gloss:evpi-expected-value-of-perfect-information){.glossar-link} von 7 375 €** ist bemerkenswert hoch: 45 % der Gesamtkosten entstehen allein daraus, dass man die Zukunft nicht kennt. In so einem Fall lohnt sich Investition in bessere Prognosen tatsächlich — anders als in dem Beispiel aus der Aufgabe *EVPI interpretieren* ([Abschnitt 12.8](#sec:unsicherheit-uebungsaufgaben)).
|
||||
Der **[EVPI (Expected Value of Perfect Information)](#gloss:evpi-expected-value-of-perfect-information){.glossar-link} von 7 375 €** ist bemerkenswert hoch: 45 % der Gesamtkosten entstehen allein daraus, dass man die Zukunft nicht kennt. In so einem Fall lohnt sich Investition in bessere Prognosen tatsächlich — anders als in dem Beispiel aus der Aufgabe *EVPI interpretieren* ([Abschnitt 12.8](#sec:unsicherheit-uebungsaufgaben)).
|
||||
|
||||
> **💡 Was ist der EVPI?** Der **Expected Value of Perfect Information**`\index{EVPI}`{=latex} beziffert, wie viel eine perfekte Prognose wert wäre: die Differenz zwischen den Kosten unter Unsicherheit und den Kosten bei vollständigem Wissen. Er ist eine **Obergrenze für jedes Prognoseprojekt**. Wenn der EVPI bei 12 000 € pro Jahr liegt, lohnt sich keine Prognosesoftware für 50 000 € — selbst wenn sie perfekt wäre. Diese Zahl bewahrt Projekte vor teuren Fehlinvestitionen.
|
||||
|
||||
|
|
@ -14154,7 +14154,7 @@ z_s &\in \{0,1\}
|
|||
\end{aligned}
|
||||
$$
|
||||
|
||||
Aus dem Kegelproblem wird ein [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} mit $S$ Binärvariablen. Für $M$ gilt, was [Kapitel 6](#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.
|
||||
Aus dem Kegelproblem wird ein [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} mit $S$ Binärvariablen. Für $M$ gilt, was [Kapitel 6](#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
|
||||
|
||||
|
|
@ -14488,7 +14488,7 @@ Der szenariobasierte Weg kennt diese Fälle, weil sie in den Daten stehen. Er ko
|
|||
|
||||
**Aufgabe 12.4 ⭐⭐ — EVPI interpretieren.** Ihr Modell liefert EVPI = 8 400 € pro Jahr. Ein Anbieter verlangt 15 000 € jährlich für eine Prognoselösung, die „80 % Treffsicherheit“ verspricht. Wie argumentieren Sie?
|
||||
|
||||
**Aufgabe 12.5 ⭐⭐⭐ — Monte-Carlo erweitern.** Erweitern Sie `Monte_Carlo.py`: (a) Fügen Sie ein Servicelevel-Kriterium hinzu: „Die Unterdeckung darf höchstens in 5 % der Fälle auftreten.“ Welche Kapazität ist dafür nötig, und was kostet sie zusätzlich? (b) Berechnen Sie den [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} der Kosten (Mittelwert der schlechtesten 5 %). (c) Zeichnen Sie ein Histogramm der Kosten für drei Kapazitäten.
|
||||
**Aufgabe 12.5 ⭐⭐⭐ — Monte-Carlo erweitern.** Erweitern Sie `Monte_Carlo.py`: (a) Fügen Sie ein Servicelevel-Kriterium hinzu: „Die Unterdeckung darf höchstens in 5 % der Fälle auftreten.“ Welche Kapazität ist dafür nötig, und was kostet sie zusätzlich? (b) Berechnen Sie den [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} der Kosten (Mittelwert der schlechtesten 5 %). (c) Zeichnen Sie ein Histogramm der Kosten für drei Kapazitäten.
|
||||
|
||||
**Aufgabe 12.6 ⭐⭐ — 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.
|
||||
|
||||
|
|
@ -14667,7 +14667,7 @@ Nach diesem Kapitel können Sie …
|
|||
2. … Zustand, Stufe, Aktion und Wertfunktion für ein gegebenes Problem benennen.
|
||||
3. … eine Rückwärtsinduktion`\index{Rückwärtsinduktion}`{=latex} von Hand für ein kleines Problem durchführen.
|
||||
4. … das Almgren-Chriss-Ausführungsproblem lösen und die Lösung interpretieren.
|
||||
5. … einschätzen, wann [DP](#gloss:dynamische-programmierung-dp){.glossar-link} funktioniert und wann der „[Fluch der Dimensionalität](#gloss:fluch-der-dimensionalitaet){.glossar-link}`\index{Fluch der Dimensionalität}`{=latex}“ zuschlägt.
|
||||
5. … einschätzen, wann [DP (Dynamische Programmierung)](#gloss:dynamische-programmierung-dp){.glossar-link} funktioniert und wann der „[Fluch der Dimensionalität](#gloss:fluch-der-dimensionalitaet){.glossar-link}`\index{Fluch der Dimensionalität}`{=latex}“ zuschlägt.
|
||||
6. … die Wertfunktion als **Nachschlagetabelle** lesen: Sie liefert keine Planfolge, sondern eine Regel, die auch bei Abweichungen gilt.
|
||||
7. … einen [Zustandsraum](#gloss:zustandsraum){.glossar-link}`\index{Zustandsraum}`{=latex} auf Vollständigkeit prüfen und erkennen, wann eine Kostenart Vorgeschichte erfordert.
|
||||
|
||||
|
|
@ -15209,7 +15209,7 @@ Das Problem entsteht, sobald der Zustand **mehrere Dimensionen** hat:
|
|||
|
||||
**Aufgabe 13.3 ⭐⭐ — Rückwärtsinduktion von Hand.** 5 Einheiten in 3 Perioden, Kosten $C(n) = n^2 + 2n$. Erstellen Sie die vollständige Wertfunktionstabelle und bestimmen Sie den optimalen Pfad. Prüfen Sie mit `Bellman_Minimalbeispiel.py` (angepasst).
|
||||
|
||||
**Aufgabe 13.4 ⭐⭐ — [Rucksackproblem](#gloss:rucksackproblem){.glossar-link}`\index{Rucksackproblem}`{=latex} als DP.** Lösen Sie das Rucksackproblem aus [Kapitel 6](#kap-milp) mit dynamischer Programmierung statt [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}. (Zustand: verbleibende Kapazität; Stufe: betrachteter Gegenstand.) Vergleichen Sie Laufzeit und Ergebnis mit dem MILP-[Solver](#gloss:solver){.glossar-link}.
|
||||
**Aufgabe 13.4 ⭐⭐ — [Rucksackproblem](#gloss:rucksackproblem){.glossar-link}`\index{Rucksackproblem}`{=latex} als DP.** Lösen Sie das Rucksackproblem aus [Kapitel 6](#kap-milp) mit dynamischer Programmierung statt [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}. (Zustand: verbleibende Kapazität; Stufe: betrachteter Gegenstand.) Vergleichen Sie Laufzeit und Ergebnis mit dem MILP-[Solver](#gloss:solver){.glossar-link}.
|
||||
|
||||
**Aufgabe 13.5 ⭐⭐⭐ — Risikoaversion kalibrieren.** Untersuchen Sie mit `Mehrperiodige_Order_Execution.py`: (a) Bei welchem $\lambda$ verkauft das Modell in der ersten Periode mehr als 50 %? (b) Stellen Sie den Zusammenhang zwischen $\lambda$ und den erwarteten Gesamtkosten dar. (c) Ein Händler sagt: „Ich will höchstens 20 % Marktauswirkungskosten und den Rest an Risiko.“ Welches $\lambda$ setzen Sie?
|
||||
|
||||
|
|
@ -15833,7 +15833,7 @@ Das Programm rechnet diese Hülle in `untere_huelle()` unabhängig aus und vergl
|
|||
|
||||
> **⚠️ Der Grund liegt in der Ganzzahligkeit**
|
||||
>
|
||||
> Bei einem reinen [LP](#gloss:lineare-programmierung-lp){.glossar-link} ist der zulässige Bereich konvex, und die Pareto-Front liegt vollständig auf ihrer eigenen konvexen Hülle — dort findet die gewichtete Summe alles. Sobald Entscheidungen **ganzzahlig** werden (welcher Träger, welches Lager, welche Schicht), zerfällt der Bereich in einzelne Punkte, und zwischen ihnen entstehen Einbuchtungen.
|
||||
> Bei einem reinen [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} ist der zulässige Bereich konvex, und die Pareto-Front liegt vollständig auf ihrer eigenen konvexen Hülle — dort findet die gewichtete Summe alles. Sobald Entscheidungen **ganzzahlig** werden (welcher Träger, welches Lager, welche Schicht), zerfällt der Bereich in einzelne Punkte, und zwischen ihnen entstehen Einbuchtungen.
|
||||
>
|
||||
> Deshalb betrifft dieses Problem praktisch jedes betriebliche Mehrzielmodell. Wer mit Gewichten arbeitet, verliert nicht ein paar Nachkommastellen, sondern **ganze Alternativen** — im Beispiel 40 % der Front.
|
||||
|
||||
|
|
@ -15953,7 +15953,7 @@ Diese Zahl ist mit etwas vergleichbar, das das Unternehmen ohnehin kennt: dem in
|
|||
## 14.12 Selbsttest {#sec:mehrziel-selbsttest}
|
||||
|
||||
1. Erklären Sie Pareto-Dominanz an einem Beispiel aus Ihrem Arbeitsumfeld.
|
||||
2. Warum ist „gewichtete Summe" bei einem reinen LP unproblematisch und bei einem [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} nicht?
|
||||
2. Warum ist „gewichtete Summe" bei einem reinen LP unproblematisch und bei einem [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} nicht?
|
||||
3. Ein Kollege sagt: „Ich nehme $w = 0{,}5$, das ist neutral." Was ist daran falsch?
|
||||
4. Beschreiben Sie das ε-Constraint-Verfahren in drei Sätzen, ohne Formeln.
|
||||
5. Sie legen einer Geschäftsführung eine Front mit zwölf Punkten vor. Welche Spalte brauchen Sie, damit die Entscheidung fallen kann?
|
||||
|
|
@ -16584,7 +16584,7 @@ Hier war es ein einziger [Parameter](#gloss:parameter){.glossar-link}`\index{Par
|
|||
|
||||
| Was nicht gilt | Woran Sie es merken | Werkzeug | Kapitel |
|
||||
| --- | --- | --- | --- |
|
||||
| **Linearität** | Risiko wächst quadratisch, Kosten degressiv, Sättigung | [QP](#gloss:quadratische-programmierung-qp){.glossar-link}, konvexe Optimierung, [KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link} | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **Linearität** | Risiko wächst quadratisch, Kosten degressiv, Sättigung | [QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link}, konvexe Optimierung, [KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link} | [Kapitel 11](#kap-qp-nlp) |
|
||||
| **Feste Daten** | Nachfrage, Wind, Rendite stehen erst morgen fest | Monte-Carlo, Zweistufigkeit, Robustheit, Chance Constraints | [Kapitel 12](#kap-unsicherheit) |
|
||||
| **Eine Periode** | die Entscheidung heute verändert, was übermorgen möglich ist | [Bellman-Gleichung](#gloss:bellman-gleichung){.glossar-link}`\index{Bellman-Gleichung}`{=latex}, [Rückwärtsinduktion](#gloss:rueckwaertsinduktion){.glossar-link}`\index{Rückwärtsinduktion}`{=latex} | [Kapitel 13](#kap-dynamische-programmierung) |
|
||||
| **Ein Ziel** | zwei Kennzahlen sollen gleichzeitig stimmen | [Pareto-Front](#gloss:pareto-front){.glossar-link}`\index{Pareto-Front}`{=latex}, ε-Constraint | [Kapitel 14](#kap-mehrziel) |
|
||||
|
|
@ -16640,7 +16640,7 @@ Er hat drei Abschnitte, und Sie können nach jedem aufhören:
|
|||
>
|
||||
> **Worum geht es?** Um den Nachweis, dass die Verfahren aus Teil II und III unverändert in der Finanzwelt funktionieren — und um die drei Stellen, an denen die Analogie endet.
|
||||
>
|
||||
> **Voraussetzungen:** [Kapitel 1](#kap-einfuehrung) (Allokation als [LP](#gloss:lineare-programmierung-lp){.glossar-link}), [Kapitel 12](#kap-unsicherheit) (Szenarien) und [Abschnitt 22.6](#sec:praxisfallen-or-kern) (`or_kern.py`).
|
||||
> **Voraussetzungen:** [Kapitel 1](#kap-einfuehrung) (Allokation als [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}), [Kapitel 12](#kap-unsicherheit) (Szenarien) und [Abschnitt 22.6](#sec:praxisfallen-or-kern) (`or_kern.py`).
|
||||
>
|
||||
> **Danach können Sie:** ein betriebswirtschaftliches Modell in die andere Domäne übersetzen, ohne den Modellcode anzufassen; Schattenpreise in beiden Welten lesen; und benennen, welche Annahmen dabei **nicht** mitwandern.
|
||||
>
|
||||
|
|
@ -16712,7 +16712,7 @@ Nach diesem Kapitel können Sie …
|
|||
|
||||
1. … ein Allokationsproblem aus der einen Domäne in die andere übersetzen, indem Sie die Daten austauschen statt des Codes.
|
||||
2. … den Schattenpreis in beiden Welten deuten — als Wert einer Ressource und als Preis des Risikos.
|
||||
3. … erklären, warum die [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link}-Formulierung aus [Kapitel 20](#kap-cvar) auf Lieferverzüge genauso passt wie auf Kursverluste.
|
||||
3. … erklären, warum die [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link}-Formulierung aus [Kapitel 20](#kap-cvar) auf Lieferverzüge genauso passt wie auf Kursverluste.
|
||||
4. … die drei Stellen benennen, an denen die Analogie **nicht** trägt — und begründen, warum das Übertragen von Methoden dort gefährlich wird.
|
||||
|
||||
---
|
||||
|
|
@ -17148,7 +17148,7 @@ steht im Programm genau einmal und wird zweimal aufgerufen.
|
|||
> | --- | --- | --- |
|
||||
> | $w$ | Anteil je Anlageklasse | Bestellanteil je Lieferant |
|
||||
> | $\ell_s$ | Verlust in Szenario $s$, in Prozentpunkten | Verzug in Szenario $s$, in Tagen |
|
||||
> | $\gamma$ | der [VaR](#gloss:value-at-risk-var){.glossar-link}: „so schlimm wird es an 95 % der Tage höchstens" | „so viele Tage Verzug höchstens bei 95 % der Bestellungen" |
|
||||
> | $\gamma$ | der [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link}: „so schlimm wird es an 95 % der Tage höchstens" | „so viele Tage Verzug höchstens bei 95 % der Bestellungen" |
|
||||
> | $u_s$ | Überschuss über diese Schwelle | dasselbe |
|
||||
> | Zielwert | CVaR: Mittelwert der schlechtesten 5 % | dasselbe |
|
||||
>
|
||||
|
|
@ -17174,7 +17174,7 @@ Eine Analogie ist nur so nützlich wie die Grenzen, die man ihr zieht. Drei Ding
|
|||
| --- | --- | --- |
|
||||
| **Woher die Zahlen kommen** | gemessen: drei Montagestunden sind drei Montagestunden | geschätzt: die erwartete Rendite hat einen Fehler, der größer sein kann als die Unterschiede zwischen den Anlagen ([Kapitel 19](#kap-markowitz)) |
|
||||
| **Ob die Vergangenheit trägt** | Lieferzeiten haben physikalische Ursachen und ändern sich langsam | Kurse entstehen aus dem Verhalten von Marktteilnehmern, die auf Modelle reagieren — ein erkanntes Muster verschwindet oft deshalb, weil es erkannt wurde ([Kapitel 21](#kap-handelsmaschine)) |
|
||||
| **Ob Teilbarkeit erlaubt ist** | 37,4 % eines Lieferanten gibt es nicht: Verträge, Mindestabnahmen, Rüstzeiten → [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} | 37,4 % eines Fonds sind ein normaler Auftrag → LP/[QP](#gloss:quadratische-programmierung-qp){.glossar-link} genügt |
|
||||
| **Ob Teilbarkeit erlaubt ist** | 37,4 % eines Lieferanten gibt es nicht: Verträge, Mindestabnahmen, Rüstzeiten → [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} | 37,4 % eines Fonds sind ein normaler Auftrag → LP/[QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link} genügt |
|
||||
|
||||
> **⚠️ Der Fehler, vor dem diese Tabelle schützt**
|
||||
>
|
||||
|
|
@ -17315,7 +17315,7 @@ Eine Analogie ist nur so nützlich wie die Grenzen, die man ihr zieht. Drei Ding
|
|||
|
||||
Die Merit-Order — Kraftwerke nach Grenzkosten sortieren und von unten auffüllen — ist damit nur für einen **einzelnen** Zeitpunkt richtig. Sobald ein Tag geplant wird, hängt jede Stunde an allen anderen: Ein Block, der um 8 Uhr angefahren wird, muss bis mindestens 16 Uhr laufen, und diese Entscheidung fällt am Vorabend.
|
||||
|
||||
> **🎯 Merksatz** Anfahrkosten und Mindestlaufzeiten machen aus 24 unabhängigen Stundenentscheidungen **ein** Problem. Genau deshalb ist die Kraftwerkseinsatzplanung ein [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} und keine Sortierung.
|
||||
> **🎯 Merksatz** Anfahrkosten und Mindestlaufzeiten machen aus 24 unabhängigen Stundenentscheidungen **ein** Problem. Genau deshalb ist die Kraftwerkseinsatzplanung ein [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} und keine Sortierung.
|
||||
|
||||
**Warum funktioniert das?** Der Umschlagpunkt ist eine einfache Rechnung: Die Anfahrkostendifferenz (38 500 €) geteilt durch die Grenzkostendifferenz je Stunde (83 €/MWh × 120 MW = 9 960 €/h) ergibt 3,9 Stunden. Bei zwei Kraftwerken kann man das im Kopf ausrechnen — bei fünf Blöcken und 24 Stunden nicht mehr.
|
||||
|
||||
|
|
@ -17328,7 +17328,7 @@ Nach diesem Kapitel können Sie …
|
|||
1. … ein Unit-Commitment-Modell mit Anfahrkosten und Mindestlaufzeiten aufstellen.
|
||||
2. … erklären, warum eine **binäre erste Stufe** das zweistufige Modell aus [Kapitel 12](#kap-unsicherheit) verschärft.
|
||||
3. … zeigen, dass eine Planung auf den Erwartungswert nicht nur ungenau, sondern **systematisch zu knapp** ist.
|
||||
4. … eine [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link}-Schranke auf eine physikalische Größe (nicht gedeckte Energie) legen.
|
||||
4. … eine [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link}-Schranke auf eine physikalische Größe (nicht gedeckte Energie) legen.
|
||||
5. … begründen, wann eine Risikoschranke etwas ändert — und wann sie überflüssig ist.
|
||||
|
||||
---
|
||||
|
|
@ -18520,7 +18520,7 @@ if __name__ == "__main__":
|
|||
|
||||
**Aufgabe 18.4 ⭐⭐ — Spaltenreihenfolge prüfen.** Laden Sie fünf Ticker in einer bewusst unsortierten Reihenfolge. Zeigen Sie, dass `raw["Close"].columns` abweicht, und dass `raw["Close"][tickers]` das behebt. Was passiert, wenn ein Ticker nicht existiert?
|
||||
|
||||
**Aufgabe 18.5 ⭐⭐⭐ — Beide Shrinkage-Ziele vergleichen.** Implementieren Sie das Konstant-Korrelations-Ziel vollständig (inklusive eigener Berechnung von $\delta$ nach Ledoit/Wolf 2003 oder per Kreuzvalidierung). Vergleichen Sie mit `sklearn` anhand: (a) der Konditionszahl, (b) der Out-of-Sample-Volatilität eines [GMV](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}-Portfolios (nach dem Muster von `Schaetzrauschen_Demo.py`), (c) der Stabilität der Gewichte über rollierende Fenster.
|
||||
**Aufgabe 18.5 ⭐⭐⭐ — Beide Shrinkage-Ziele vergleichen.** Implementieren Sie das Konstant-Korrelations-Ziel vollständig (inklusive eigener Berechnung von $\delta$ nach Ledoit/Wolf 2003 oder per Kreuzvalidierung). Vergleichen Sie mit `sklearn` anhand: (a) der Konditionszahl, (b) der Out-of-Sample-Volatilität eines [GMV (Global Minimum Variance Portfolio)](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}-Portfolios (nach dem Muster von `Schaetzrauschen_Demo.py`), (c) der Stabilität der Gewichte über rollierende Fenster.
|
||||
|
||||
**Aufgabe 18.6 ⭐⭐⭐ — Error-Maximizer selbst messen.** Erweitern Sie `Schaetzrauschen_Demo.py` um eine dritte Variante: die **Gleichgewichtung** ($w_i = 1/N$), die überhaupt keine Schätzung benötigt. (a) Ab welchem $T/N$ schlägt die Stichproben-Optimierung die Gleichgewichtung? (b) Ab welchem $T/N$ schlägt Ledoit-Wolf sie? (c) Was folgt daraus für die Praxis?
|
||||
|
||||
|
|
@ -18769,7 +18769,7 @@ e 0: \mathbf{w}^ op\mathbf{S}\mathbf{w} = 0$ | „In genau diesen Richtungen mis
|
|||
>
|
||||
> **Worum geht es?** Um das Modell, das 1952 die quantitative Finanzwirtschaft begründete — und um die Restriktionen, ohne die es in der Praxis unbrauchbar bleibt.
|
||||
>
|
||||
> **Voraussetzungen:** [Kapitel 11](#kap-qp-nlp) ([QP](#gloss:quadratische-programmierung-qp){.glossar-link}, [KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}), [Kapitel 18](#kap-finanzdaten) (Kovarianz, Shrinkage).
|
||||
> **Voraussetzungen:** [Kapitel 11](#kap-qp-nlp) ([QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link}, [KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}), [Kapitel 18](#kap-finanzdaten) (Kovarianz, Shrinkage).
|
||||
>
|
||||
> **Danach können Sie:** Die Effizienzgrenze berechnen, das Maximum-Sharpe-Portfolio über die [Korn-Transformation](#gloss:korn-transformation){.glossar-link}`\index{Korn-Transformation}`{=latex} bestimmen, institutionelle Nebenbedingungen einbauen — und beurteilen, wann eine Renditeschätzung das Ergebnis wertlos macht.
|
||||
>
|
||||
|
|
@ -18990,7 +18990,7 @@ $$
|
|||
>
|
||||
> | $\lambda$ | Verhalten | Ergebnis |
|
||||
> | --- | --- | --- |
|
||||
> | $0$ | Risiko zählt allein | **[GMV](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}** — Global Minimum Variance Portfolio |
|
||||
> | $0$ | Risiko zählt allein | **[GMV (Global Minimum Variance Portfolio)](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}** — Global Minimum Variance Portfolio |
|
||||
> | mittel | Abwägung | ein Punkt auf der Effizienzgrenze |
|
||||
> | $\to\infty$ | Rendite zählt allein | alles in den Titel mit höchstem $\mu$ |
|
||||
>
|
||||
|
|
@ -19664,9 +19664,9 @@ Drei praktische Konsequenzen:
|
|||
>
|
||||
> **Worum geht es?** Um zwei Schwächen des Markowitz-Modells: Es unterschätzt Extremverluste und ignoriert die Kosten des Umschichtens. Beide lassen sich mit konvexen Mitteln beheben.
|
||||
>
|
||||
> **Voraussetzungen:** [Kapitel 19](#kap-markowitz), [Kapitel 5](#kap-lp) ([LP](#gloss:lineare-programmierung-lp){.glossar-link}-Formulierungen).
|
||||
> **Voraussetzungen:** [Kapitel 19](#kap-markowitz), [Kapitel 5](#kap-lp) ([LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}-Formulierungen).
|
||||
>
|
||||
> **Danach können Sie:** [VaR](#gloss:value-at-risk-var){.glossar-link} und [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} unterscheiden, den CVaR nach Rockafellar/Uryasev als lineares Programm formulieren, Turnover über die $L_1$-Norm bestrafen — und begründen, warum VaR-Kennzahlen nicht über Einheiten addiert werden dürfen.
|
||||
> **Danach können Sie:** [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link} und [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} unterscheiden, den CVaR nach Rockafellar/Uryasev als lineares Programm formulieren, Turnover über die $L_1$-Norm bestrafen — und begründen, warum VaR-Kennzahlen nicht über Einheiten addiert werden dürfen.
|
||||
>
|
||||
> **Zeitbedarf:** ca. 5 Stunden.
|
||||
>
|
||||
|
|
@ -20217,7 +20217,7 @@ if __name__ == "__main__":
|
|||
> risiko = cp.norm2(L.T @ w) # = sqrt(w' sigma w)
|
||||
> ```
|
||||
>
|
||||
> und **nicht** als das Naheliegende, `cp.sqrt(cp.quad_form(w, sigma))`. Der naheliegende Ausdruck ist nicht [DCP](#gloss:dcp-disciplined-convex-programming){.glossar-link} und wird von CVXPY mit einem `DCPError` abgelehnt: `cp.sqrt` ist konkav und verlangt deshalb ein **konkaves** Argument, `quad_form` ist aber konvex. Die Regel wird verletzt, obwohl die Funktion`\index{Konvexität!Funktion}`{=latex} als ganze mathematisch völlig harmlos ist — $\sqrt{w^\top \Sigma w}$ ist konvex, DCP kann es nur nicht *sehen*.
|
||||
> und **nicht** als das Naheliegende, `cp.sqrt(cp.quad_form(w, sigma))`. Der naheliegende Ausdruck ist nicht [DCP (Disciplined Convex Programming)](#gloss:dcp-disciplined-convex-programming){.glossar-link} und wird von CVXPY mit einem `DCPError` abgelehnt: `cp.sqrt` ist konkav und verlangt deshalb ein **konkaves** Argument, `quad_form` ist aber konvex. Die Regel wird verletzt, obwohl die Funktion`\index{Konvexität!Funktion}`{=latex} als ganze mathematisch völlig harmlos ist — $\sqrt{w^\top \Sigma w}$ ist konvex, DCP kann es nur nicht *sehen*.
|
||||
>
|
||||
> Wichtig ist die Fehlerdiagnose dahinter, weil sie leicht in die Irre geht: `cp.psd_wrap(sigma)` sieht nach der Lösung aus und ist keine. Es unterdrückt die **numerische** Beanstandung, dass $\Sigma$ nicht als positiv semidefinit erkannt wird — gegen die **strukturelle** Regelverletzung im Aufbau hilft es nicht.
|
||||
>
|
||||
|
|
@ -21256,7 +21256,7 @@ Sechs Kapitel, zwei Branchen, die sich für unvergleichbar halten. Die Werkstatt
|
|||
| --- | --- | --- |
|
||||
| „Planen mit der Prognose ist gut genug." | Der Erwartungswert-Plan kostet **149 % mehr** (874 870 € statt 351 356 €) und wirft in **28 von 40** Szenarien Last ab | [Kapitel 17](#kap-supplychain) |
|
||||
| „Dann sparen wir eben beim Brennstoff." | Genau das tut er: 12 725 € gespart, **536 239 €** Lastabwurf bezahlt — das 42-fache. Die Anfahrkosten sind in beiden Plänen gleich | [Kapitel 17](#kap-supplychain) |
|
||||
| „Der [VaR](#gloss:value-at-risk-var){.glossar-link} sagt, wie riskant es ist." | VaR **1,86 %**, [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} **2,99 %** — und der schlechteste Tag der Stichprobe (**−23,0 %**) ändert am VaR **nichts** | [Kapitel 20](#kap-cvar) |
|
||||
| „Der [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link} sagt, wie riskant es ist." | VaR **1,86 %**, [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} **2,99 %** — und der schlechteste Tag der Stichprobe (**−23,0 %**) ändert am VaR **nichts** | [Kapitel 20](#kap-cvar) |
|
||||
| „Die [Kovarianzmatrix](#gloss:kovarianzmatrix){.glossar-link}`\index{Kovarianzmatrix}`{=latex} ist eine Eingabe wie jede andere." | Aus kurzen Reihen geschätzt ist sie schlecht konditioniert; die Optimierung setzt dann auf Schätzrauschen | [Kapitel 18](#kap-finanzdaten) |
|
||||
|
||||
## Drei Fehler, die dieser Teil verhindert
|
||||
|
|
@ -21355,7 +21355,7 @@ Nach diesem Kapitel können Sie …
|
|||
6. … die Architektur einer produktionsreifen OR-Plattform skizzieren.
|
||||
7. … eine **modellunabhängige Abnahmeprüfung** schreiben, die eine Lösung gegen die Anforderungen prüft statt gegen das Modell.
|
||||
8. … Status, Gap und Zeitausschöpfung protokollieren und begründen, warum eine konstante Laufzeit bei Zeitlimit ein Warnsignal ist.
|
||||
9. … ein Modell in Domänenschicht, Modellbauer und Lösungs-[DTO](#gloss:dto-data-transfer-object){.glossar-link} trennen — und begründen, warum sich das nicht wegen des Solverwechsels lohnt, sondern wegen der Prüfbarkeit.
|
||||
9. … ein Modell in Domänenschicht, Modellbauer und Lösungs-[DTO (Data Transfer Object)](#gloss:dto-data-transfer-object){.glossar-link} trennen — und begründen, warum sich das nicht wegen des Solverwechsels lohnt, sondern wegen der Prüfbarkeit.
|
||||
10. … die Statuswerte verschiedener Solverbibliotheken auf eine gemeinsame Sprache abbilden.
|
||||
|
||||
---
|
||||
|
|
@ -21633,7 +21633,7 @@ Ausführlich in [Kapitel 21](#kap-handelsmaschine) behandelt. Die Kurzfassung: B
|
|||
|
||||
### Falle 5 — Laufzeitexplosion`\index{Laufzeitexplosion (Fehlerbild)}`{=latex}
|
||||
|
||||
Exakte Optimalität kann bei [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} oder [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} Minuten bis Stunden dauern — und die Laufzeit wächst nicht linear mit der Problemgröße.
|
||||
Exakte Optimalität kann bei [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} oder [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} Minuten bis Stunden dauern — und die Laufzeit wächst nicht linear mit der Problemgröße.
|
||||
|
||||
| Einsatzszenario | Empfohlenes Zeitlimit | Akzeptabler [MIP-Gap](#gloss:mip-gap){.glossar-link}`\index{MIP-Gap}`{=latex} |
|
||||
| --- | --- | --- |
|
||||
|
|
@ -22072,7 +22072,7 @@ aus.
|
|||
|
||||
### Drei Befunde, und keiner steht im Solverergebnis
|
||||
|
||||
**Erstens: bindend heißt nicht teuer.** Fünf Bedingungen binden, aber „Lackierbudget Schicht 2“ tut es mit einem Schattenpreis von **0,00 €**. Sie berührt den Plan, ohne ihn zu verteuern — wer sie nachverhandelt, gewinnt nichts. Das ist derselbe Unterschied, den `Erklaerbarkeit.py` oben an einer einzelnen Zuweisung zeigt, hier im Dualwert eines [LP](#gloss:lineare-programmierung-lp){.glossar-link}.
|
||||
**Erstens: bindend heißt nicht teuer.** Fünf Bedingungen binden, aber „Lackierbudget Schicht 2“ tut es mit einem Schattenpreis von **0,00 €**. Sie berührt den Plan, ohne ihn zu verteuern — wer sie nachverhandelt, gewinnt nichts. Das ist derselbe Unterschied, den `Erklaerbarkeit.py` oben an einer einzelnen Zuweisung zeigt, hier im Dualwert eines [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}.
|
||||
|
||||
**Zweitens: Der Schattenpreis ist eine Momentaufnahme.** Er gilt für die **nächste** Einheit. Ein Planer kauft aber keine Einheit, sondern eine Schicht. Für die Lackiererei verspricht die Hochrechnung $4{,}00 \cdot 30 = 120$ €; gemessen kommen **60 €**. Der Preis von 4,00 € gilt exakt bis **+15 Stunden**, danach begrenzt etwas anderes — **die zweite Hälfte der Sonderschicht wäre bezahlt und wirkungslos.**
|
||||
|
||||
|
|
@ -22162,7 +22162,7 @@ zeigt nach innen auf die Domäne, und die Domäne zeigt auf nichts. Erzeugt von
|
|||
|
||||
Der unscheinbarste, aber wirksamste Teil ist die Statusübersetzung. Dieselbe Aussage heißt in den fünf im Buch verwendeten Bibliotheken:
|
||||
|
||||
| Bedeutung | pywraplp | [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} | HiGHS`\index{HiGHS}`{=latex} | [SciPy](#gloss:scipy){.glossar-link} | CVXPY`\index{CVXPY}`{=latex} |
|
||||
| Bedeutung | pywraplp | [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} | HiGHS`\index{HiGHS}`{=latex} | [SciPy](#gloss:scipy){.glossar-link} | CVXPY`\index{CVXPY}`{=latex} |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| beweisbar optimal | `Solver.OPTIMAL` | `cp_model.OPTIMAL` | `"Optimal"` | `status == 0` | `"optimal"` |
|
||||
| zulässig, nicht bewiesen | `Solver.FEASIBLE` | `cp_model.FEASIBLE` | `"Time limit reached"` | — | `"optimal_inaccurate"` |
|
||||
|
|
@ -23615,7 +23615,7 @@ sichtbar wird, und gibt Zeit zum Handeln.
|
|||
> AssertionError: Plan [31. 48.] braucht [141. 234.], verfuegbar sind [140. 232.]
|
||||
> ```
|
||||
|
||||
**Und jetzt der Punkt.** Der Solver hat richtig gerechnet: 30,67 Tische und 48 Stühle sind das Optimum des [LP](#gloss:lineare-programmierung-lp){.glossar-link}. Das Runden hat den Plan kaputt gemacht — 31 Tische brauchen eine Montagestunde mehr, als es gibt. Ohne die drei Zeilen wäre dieser Plan in die Fertigung gegangen, und dort hätte am Monatsende eine Stunde gefehlt, die niemand einer Zeile Python zugeordnet hätte.
|
||||
**Und jetzt der Punkt.** Der Solver hat richtig gerechnet: 30,67 Tische und 48 Stühle sind das Optimum des [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}. Das Runden hat den Plan kaputt gemacht — 31 Tische brauchen eine Montagestunde mehr, als es gibt. Ohne die drei Zeilen wäre dieser Plan in die Fertigung gegangen, und dort hätte am Monatsende eine Stunde gefehlt, die niemand einer Zeile Python zugeordnet hätte.
|
||||
|
||||
Bemerkenswert ist, **was** der Test prüft. Er prüft nicht, ob 30,67 das Optimum ist — das könnte er gar nicht, dafür bräuchte er einen zweiten Solver. Er prüft die Eigenschaft, die jede brauchbare Lösung haben muss: *Sie hält die Kapazität ein.* Diese Verschiebung — **von der Frage nach dem richtigen Wert zur Frage nach den notwendigen Eigenschaften** — ist der Schlüssel zum ganzen Kapitel.
|
||||
|
||||
|
|
@ -24562,7 +24562,7 @@ Die zweite unbequeme Zahl steht ganz rechts: **[CVXPY](#gloss:cvxpy){.glossar-li
|
|||
|
||||
> **⚠️ Was diese Tabelle nicht sagt**
|
||||
>
|
||||
> Sie sagt **nicht** „ortools ist langsamer als scipy". Gemessen wurde *ein* Problemtyp in *einer* Formulierung auf *einer* Maschine. Ein [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} statt eines LP, eine andere Modellierung desselben Problems oder ein anderer Rechner können die Reihenfolge umdrehen — und bei MILPs tun sie es regelmäßig.
|
||||
> Sie sagt **nicht** „ortools ist langsamer als scipy". Gemessen wurde *ein* Problemtyp in *einer* Formulierung auf *einer* Maschine. Ein [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} statt eines LP, eine andere Modellierung desselben Problems oder ein anderer Rechner können die Reihenfolge umdrehen — und bei MILPs tun sie es regelmäßig.
|
||||
>
|
||||
> Übertragbar ist der **Trend**, nicht der Absolutwert: dass der Aufbauanteil mit der Größe wächst, dass CVXPY einen konstanten Speichersockel hat. Der Zweck des Programms ist, dass Sie es auf Ihrer Maschine mit Ihrem Problem laufen lassen.
|
||||
|
||||
|
|
@ -24987,13 +24987,13 @@ Das zugehoerige Dockerfile ist kurz genug, um es ganz zu zeigen:
|
|||
>
|
||||
> **1. Das Domänenmodell ist das API-Schema.** Der [Parameter](#gloss:parameter){.glossar-link} heißt `problem: Produktionsproblem` — mehr steht nicht da. FastAPI validiert die Anfrage damit gegen dieselben Pydantic-Regeln wie der Excel-Import aus [Kapitel 1](#kap-einfuehrung) und antwortet bei Unsinn mit `422`, **bevor** ein Solver startet. Die drei abgewiesenen Anfragen im Selbsttest sind genau die drei Fälle, die `or_kern.py` schon beim Einlesen abfängt.
|
||||
>
|
||||
> **2. Die Antwort enthält Status und Gap, nicht nur Zahlen.** Ein Aufrufer, der nur die Mengen bekommt, kann nicht unterscheiden, ob er ein bewiesenes Optimum oder einen Zeitlimit-Abbruch in der Hand hält. Das `Loesung`-Objekt geht deshalb vollständig durch die Schnittstelle — dasselbe [DTO](#gloss:dto-data-transfer-object){.glossar-link}, das in [Abschnitt 22.7](#sec:praxisfallen-solverwechsel) schon eine Prozessgrenze überlebt hat.
|
||||
> **2. Die Antwort enthält Status und Gap, nicht nur Zahlen.** Ein Aufrufer, der nur die Mengen bekommt, kann nicht unterscheiden, ob er ein bewiesenes Optimum oder einen Zeitlimit-Abbruch in der Hand hält. Das `Loesung`-Objekt geht deshalb vollständig durch die Schnittstelle — dasselbe [DTO (Data Transfer Object)](#gloss:dto-data-transfer-object){.glossar-link}, das in [Abschnitt 22.7](#sec:praxisfallen-solverwechsel) schon eine Prozessgrenze überlebt hat.
|
||||
>
|
||||
> **3. Die Abnahmeprüfung läuft auch hier.** `pruefe_loesung()` steht im Arbeiter, nicht nur im Skript. Ein Dienst ohne sie liefert Fehler schneller aus, als ein Mensch sie finden könnte.
|
||||
|
||||
### Threads oder Prozesse? Eine Messung, keine Meinung
|
||||
|
||||
Punkt 6 des Selbsttests misst, ob vier Solverläufe in Threads sich überlappen. Das Ergebnis ist ein Faktor von rund 3,5 bei vier Threads: **OR-Tools rechnet in C++ und gibt den [GIL](#gloss:gil-global-interpreter-lock){.glossar-link} während `Solve()` frei.** Ein Threadpool genügt also, es braucht keine eigenen Prozesse.
|
||||
Punkt 6 des Selbsttests misst, ob vier Solverläufe in Threads sich überlappen. Das Ergebnis ist ein Faktor von rund 3,5 bei vier Threads: **OR-Tools rechnet in C++ und gibt den [GIL (Global Interpreter Lock)](#gloss:gil-global-interpreter-lock){.glossar-link} während `Solve()` frei.** Ein Threadpool genügt also, es braucht keine eigenen Prozesse.
|
||||
|
||||
Das gilt aber nicht allgemein. Eine in reinem Python geschriebene Heuristik ([Kapitel 9](#kap-metaheuristiken)) hält den GIL die ganze Zeit — für sie braucht derselbe Dienst einen `ProcessPoolExecutor`. Die Entscheidung gehört gemessen, nicht angenommen.
|
||||
|
||||
|
|
@ -25193,7 +25193,7 @@ Halten Sie sich an diese Reihenfolge — sie ist aus vielen gescheiterten und ei
|
|||
* Variablen: $x_{p,t,s} \in \{0,1\}$ — Person, Tag, Schicht.
|
||||
* Hart: Mindestbesetzung je Schicht **und** Qualifikationsmix (mindestens eine examinierte Kraft); nach Nachtschicht ≥ 2 freie Tage; höchstens 6 Arbeitstage in Folge; monatliche Sollstunden ± 10 %.
|
||||
* Weich: Wunschfrei, gleichmäßige Wochenendverteilung, ungeteilte Dienste, stabile Schichtfolgen (nicht Früh–Nacht–Früh).
|
||||
* Solver: [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} mit Intervall- und Cumulative-Constraints.
|
||||
* Solver: [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} mit Intervall- und Cumulative-Constraints.
|
||||
|
||||
**Abnahmekriterien.**
|
||||
- [ ] Alle gesetzlichen Regeln nachweislich eingehalten (per `assert` geprüft).
|
||||
|
|
@ -25298,7 +25298,7 @@ Halten Sie sich an diese Reihenfolge — sie ist aus vielen gescheiterten und ei
|
|||
**Ausgangslage.** Für ein bestehendes Portfolio soll ein monatlicher Risikobericht entstehen.
|
||||
|
||||
**Inhalte des Berichts.**
|
||||
* [VaR](#gloss:value-at-risk-var){.glossar-link} und [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} auf 95 % und 99 %, historisch **und** Monte-Carlo-simuliert.
|
||||
* [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link} und [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} auf 95 % und 99 %, historisch **und** Monte-Carlo-simuliert.
|
||||
* Risikobeiträge je Position (*marginal CVaR*): Wer treibt das Risiko?
|
||||
* Stresstests: Was passiert bei −20 % Aktienmarkt, +200 Basispunkten Zins, Korrelationsanstieg auf 0,9?
|
||||
* Historische Szenarien nachspielen (2008, März 2020).
|
||||
|
|
@ -25320,7 +25320,7 @@ Halten Sie sich an diese Reihenfolge — sie ist aus vielen gescheiterten und ei
|
|||
**Ausgangslage.** P3 hat funktioniert — mit 30 Kunden. Der Auftraggeber kommt mit 400 zurück, und derselbe Code liefert nach zwanzig Minuten noch keine Lösung. Das ist keine Panne, sondern der erwartbare Umschlagpunkt.
|
||||
|
||||
**Modellskizze.** Zwei Verfahren am **selben** Problem, verglichen unter **gleichem Zeitbudget**:
|
||||
* Exakt: [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} oder CP-SAT wie in P3, mit Zeitlimit und protokolliertem Gap.
|
||||
* Exakt: [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} oder CP-SAT wie in P3, mit Zeitlimit und protokolliertem Gap.
|
||||
* Heuristisch: Startlösung mit einer Faustregel, dann Verbesserung durch Simulated Annealing oder Large Neighborhood Search ([Kapitel 9](#kap-metaheuristiken)).
|
||||
* Messgröße ist nicht „wer gewinnt", sondern **ab welcher Instanzgröße** sich das Blatt wendet.
|
||||
|
||||
|
|
@ -25390,7 +25390,7 @@ Halten Sie sich an diese Reihenfolge — sie ist aus vielen gescheiterten und ei
|
|||
| Trainingsplan eines Sportvereins (Hallen, Trainer, Altersgruppen) | CP-SAT | [Kapitel 7](#kap-cpsat) |
|
||||
| Budgetaufteilung auf Projekte mit Abhängigkeiten | MILP | [Kapitel 6](#kap-milp) |
|
||||
| Schnittoptimierung für Zuschnitt (Holz, Blech, Stoff) | MILP / Spaltengenerierung | [Kapitel 10](#kap-dekomposition) |
|
||||
| Speiseplan unter Nährwert- und Budgetgrenzen | [LP](#gloss:lineare-programmierung-lp){.glossar-link} | [Kapitel 5](#kap-lp) |
|
||||
| Speiseplan unter Nährwert- und Budgetgrenzen | [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} | [Kapitel 5](#kap-lp) |
|
||||
| Prüfungsplanung (keine Kollisionen, Erholungspausen) | CP-SAT | [Kapitel 7](#kap-cpsat) |
|
||||
| Ladeplanung für E-Fahrzeugflotte (Lastspitzen vermeiden) | MILP + Cumulative | [Kapitel 6](#kap-milp), [Kapitel 7](#kap-cpsat) |
|
||||
| Bewässerungsplan im Kleingarten (Wasser, Wetterprognose) | Stochastisch | [Kapitel 12](#kap-unsicherheit) |
|
||||
|
|
@ -25525,7 +25525,7 @@ Für $\mathbf{P}_2$ ergibt sich eine PSD-Matrix mit Korrelation exakt $1{,}0$
|
|||
|
||||
### Finde den Denkfehler — Die unauffällige Transposition
|
||||
|
||||
(a) **Warum nichts auffällt.** $\mathbf{A}$ ist quadratisch, also passen die Dimensionen auch transponiert. [NumPy](#gloss:numpy){.glossar-link} prüft Formen, nicht Bedeutungen; der Solver bekommt ein vollkommen zulässiges [LP](#gloss:lineare-programmierung-lp){.glossar-link} vorgelegt und löst es korrekt — nur eben ein **anderes**. Eine Transposition ist genau dann gefährlich, wenn sie folgenlos *aussieht*: Wäre die Matrix $2 \times 3$ gewesen, hätte NumPy sofort einen Dimensionsfehler geworfen.
|
||||
(a) **Warum nichts auffällt.** $\mathbf{A}$ ist quadratisch, also passen die Dimensionen auch transponiert. [NumPy](#gloss:numpy){.glossar-link} prüft Formen, nicht Bedeutungen; der Solver bekommt ein vollkommen zulässiges [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} vorgelegt und löst es korrekt — nur eben ein **anderes**. Eine Transposition ist genau dann gefährlich, wenn sie folgenlos *aussieht*: Wäre die Matrix $2 \times 3$ gewesen, hätte NumPy sofort einen Dimensionsfehler geworfen.
|
||||
|
||||
(b) **Der Plan an den echten Restriktionen.** Mit $\mathbf{A} = \begin{pmatrix} 1 & 2 \\ 3 & 1\end{pmatrix}$ und $\mathbf{x} = (5{,}6;\ 0{,}8)$:
|
||||
|
||||
|
|
@ -25565,7 +25565,7 @@ Vorbeugend hilft außerdem, Matrizen nie positionsweise abzutippen, sondern übe
|
|||
|
||||
## A.3 Lösungen zu Kapitel „Das Python-Ökosystem für OR — Solver, Bindings und Modellierungsschichten“ {#sec:loesungen-oekosystem}
|
||||
|
||||
**3.1 — Solverwahl.** (a) [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} (diskrete Zuordnung mit Zeitfenstern). (b) `scipy.optimize.linprog` (klassisches Mischungs-LP, klein). (c) [CVXPY](#gloss:cvxpy){.glossar-link}`\index{CVXPY}`{=latex} (konvexes [QP](#gloss:quadratische-programmierung-qp){.glossar-link}). (d) [MIQP](#gloss:miqp){.glossar-link} — CVXPY mit Binärvariablen und MIQP-fähigem Solver, oder Heuristik. (e) [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} über `highspy` oder [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} (Standortproblem mit Fixkosten). (f) `scipy.optimize.minimize` mit Multistart (nicht konvex).
|
||||
**3.1 — Solverwahl.** (a) [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} (diskrete Zuordnung mit Zeitfenstern). (b) `scipy.optimize.linprog` (klassisches Mischungs-LP, klein). (c) [CVXPY](#gloss:cvxpy){.glossar-link}`\index{CVXPY}`{=latex} (konvexes [QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link}). (d) [MIQP](#gloss:miqp){.glossar-link} — CVXPY mit Binärvariablen und MIQP-fähigem Solver, oder Heuristik. (e) [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} über `highspy` oder [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} (Standortproblem mit Fixkosten). (f) `scipy.optimize.minimize` mit Multistart (nicht konvex).
|
||||
|
||||
**3.2 — Bäckerei viermal.** Alle vier müssen $Z = 448$ (ganzzahlig) bzw. $450$ (kontinuierlich) liefern. Denken Sie an die Prozesstrennung, falls `ortools` und `highspy` kollidieren.
|
||||
|
||||
|
|
@ -25957,9 +25957,9 @@ Beachten Sie, dass Werk 3 seine günstigste Verbindung (L4 zu 5) voll ausschöpf
|
|||
|
||||
**8.5 — Engpass finden.** Die Dualwerte der Kapazitätsschranken (`res.upper.marginals` bei `linprog`) zeigen es direkt; alternativ jede Kapazität einzeln um 1 erhöhen und neu rechnen. Im Beispiel ist die Kante `Werk_A → Umschlag` der Engpass (voll ausgelastet, günstigster Weg).
|
||||
|
||||
**8.6 — [VRP](#gloss:vehicle-routing-problem-vrp){.glossar-link} variieren.** (a) Mit 3 Fahrzeugen werden die Touren länger, die Gesamtfahrzeit steigt leicht, die Auslastung deutlich. (b) Unlösbar, sobald $\text{Kapazität} \times \text{Fahrzeuge} < \text{Gesamtbedarf}$ (hier: bei 3 Fahrzeugen à 10 sind 30 < 37 → unlösbar) **oder** wenn Zeitfenster nicht mehr eingehalten werden können. (c) 1 s liefert meist eine brauchbare, 30 s eine spürbar bessere Lösung — die [Metaheuristik](#gloss:metaheuristik){.glossar-link}`\index{Metaheuristik}`{=latex} verbessert kontinuierlich. (d) Doppelte Servicezeit kann Zeitfenster verletzen → möglicherweise unlösbar.
|
||||
**8.6 — [VRP (Vehicle Routing Problem)](#gloss:vehicle-routing-problem-vrp){.glossar-link} variieren.** (a) Mit 3 Fahrzeugen werden die Touren länger, die Gesamtfahrzeit steigt leicht, die Auslastung deutlich. (b) Unlösbar, sobald $\text{Kapazität} \times \text{Fahrzeuge} < \text{Gesamtbedarf}$ (hier: bei 3 Fahrzeugen à 10 sind 30 < 37 → unlösbar) **oder** wenn Zeitfenster nicht mehr eingehalten werden können. (c) 1 s liefert meist eine brauchbare, 30 s eine spürbar bessere Lösung — die [Metaheuristik](#gloss:metaheuristik){.glossar-link}`\index{Metaheuristik}`{=latex} verbessert kontinuierlich. (d) Doppelte Servicezeit kann Zeitfenster verletzen → möglicherweise unlösbar.
|
||||
|
||||
**8.7 — [TSP](#gloss:tsp-traveling-salesperson-problem){.glossar-link} mit MTZ.** Erwartetes Ergebnis: Bei 8 Städten löst das MILP in Sekunden. Ab etwa 12–15 Städten wird die schwache MTZ-Relaxation zum Problem, und die Laufzeit steigt stark — während [OR-Tools](#gloss:or-tools){.glossar-link}`\index{OR-Tools}`{=latex} weiterhin in Sekundenbruchteilen sehr gute Touren liefert.
|
||||
**8.7 — [TSP (Traveling Salesperson Problem)](#gloss:tsp-traveling-salesperson-problem){.glossar-link} mit MTZ.** Erwartetes Ergebnis: Bei 8 Städten löst das MILP in Sekunden. Ab etwa 12–15 Städten wird die schwache MTZ-Relaxation zum Problem, und die Laufzeit steigt stark — während [OR-Tools](#gloss:or-tools){.glossar-link}`\index{OR-Tools}`{=latex} weiterhin in Sekundenbruchteilen sehr gute Touren liefert.
|
||||
|
||||
### Finde den Denkfehler — Die vergessene Dimension
|
||||
|
||||
|
|
@ -26033,7 +26033,7 @@ Alles, was der Kollege sagt, stimmt. Der Fehler liegt darin, was er *nicht* sagt
|
|||
|
||||
`Metaheuristik_vs_Exakt.py` liefert die fehlende Zahl in der Spalte *Schranke*: **1 768 Minuten**. Der Abstand der vorgestellten Lösung zum Bestmöglichen beträgt also bis zu 25 %, nicht 0 %. In derselben Nacht, in der 640 Stunden gefeiert werden, liegen möglicherweise weitere 2 000 Stunden ungenutzt herum.
|
||||
|
||||
Die Konsequenz ist keine Absage an das Projekt — 6,2 % sind echt und werden verdient. Die Konsequenz ist eine ehrliche Fortschreibung: „Wir heben 6,2 % und wissen, dass bis zu einem Viertel noch offen ist. Der nächste Schritt ist [LNS](#gloss:large-neighborhood-search-lns){.glossar-link}.“ Wer die Schranke verschweigt, erklärt das Projekt für abgeschlossen und lässt den größeren Teil liegen.
|
||||
Die Konsequenz ist keine Absage an das Projekt — 6,2 % sind echt und werden verdient. Die Konsequenz ist eine ehrliche Fortschreibung: „Wir heben 6,2 % und wissen, dass bis zu einem Viertel noch offen ist. Der nächste Schritt ist [LNS (Large Neighborhood Search)](#gloss:large-neighborhood-search-lns){.glossar-link}.“ Wer die Schranke verschweigt, erklärt das Projekt für abgeschlossen und lässt den größeren Teil liegen.
|
||||
|
||||
> Dasselbe Muster in anderer Verkleidung: Kapitel Handelsmaschine, `Data_Snooping.py` — dort fehlt nicht die Schranke, sondern die Zahl der Versuche. Beide Male macht eine weggelassene Kennzahl aus einem korrekten Ergebnis eine irreführende Aussage.
|
||||
|
||||
|
|
@ -26128,7 +26128,7 @@ Die Schranke sagt: *Weniger als 73 Rollen sind unmöglich.* Sie sagt **nicht**:
|
|||
|
||||
**11.2 — [Komplementärer Schlupf](#gloss:komplementaerer-schlupf){.glossar-link}`\index{Komplementärer Schlupf}`{=latex}.** Ja, verträglich: $\lambda_i w_i = 0$ gilt für alle $i$ ($w_2 = 0$ mit $\lambda_2 > 0$; die anderen mit $\lambda = 0$). $\lambda_2 = 0{,}03$ bedeutet: Würde man Titel 2 zwingen, ein kleines positives Gewicht zu tragen, verschlechterte sich der Zielwert um 0,03 je Einheit — die Nichtnegativitätsschranke ist dort **bindend**.
|
||||
|
||||
**11.3 — [KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link} von Hand.** $\mathcal{L} = x_1^2 + x_2^2 + \lambda(4 - x_1 - x_2)$. Stationarität: $2x_1 = \lambda$, $2x_2 = \lambda$ → $x_1 = x_2$. Bindend ($\lambda > 0$): $x_1 + x_2 = 4$ → $x_1 = x_2 = 2$, $\lambda = 4$. Prüfung: $\lambda = 4 > 0$ ✓, $f = 8$. **Interpretation:** Würde die Forderung auf $\ge 4{,}1$ steigen, stiege $f$ um etwa $4 \cdot 0{,}1 = 0{,}4$. Probe: $2\cdot(2{,}05)^2 = 8{,}405$ ✓.
|
||||
**11.3 — [KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link} von Hand.** $\mathcal{L} = x_1^2 + x_2^2 + \lambda(4 - x_1 - x_2)$. Stationarität: $2x_1 = \lambda$, $2x_2 = \lambda$ → $x_1 = x_2$. Bindend ($\lambda > 0$): $x_1 + x_2 = 4$ → $x_1 = x_2 = 2$, $\lambda = 4$. Prüfung: $\lambda = 4 > 0$ ✓, $f = 8$. **Interpretation:** Würde die Forderung auf $\ge 4{,}1$ steigen, stiege $f$ um etwa $4 \cdot 0{,}1 = 0{,}4$. Probe: $2\cdot(2{,}05)^2 = 8{,}405$ ✓.
|
||||
|
||||
**11.4 — Unmögliche Korrelationsmatrix.** Eigenwerte $\approx (-0{,}62;\ 1{,}0;\ 2{,}62)$ → **nicht PSD**, also unmöglich. Anschaulich: Wenn A stark **positiv** mit B korreliert und B stark positiv mit C, kann A nicht gleichzeitig stark **negativ** mit C korrelieren — Korrelation ist eingeschränkt transitiv. Formal: $\rho_{AC} \ge \rho_{AB}\rho_{BC} - \sqrt{(1-\rho_{AB}^2)(1-\rho_{BC}^2)} = 0{,}81 - 0{,}19 = 0{,}62$; verlangt waren $-0{,}9$.
|
||||
|
||||
|
|
@ -26198,7 +26198,7 @@ Der Ausweg auf `scipy` hat das Warnsystem umgangen, nicht das Problem gelöst. R
|
|||
|
||||
**12.3 — Zweistufig rechnen.** (a) Mit Spot = 60: Ableitung bei $x \in (100,250)$: $40 - 60\cdot0{,}5 + 5\cdot0{,}5 = 40-30+2{,}5 = +12{,}5 > 0$ → Kapazität **senken**. Bei $x < 100$: $40 - 60 = -20 < 0$ → erhöhen. Optimum daher $x^* = 100$. (b) Billige Nachbesserung macht Vorhalten unattraktiv. (c) Bei $x = 225$ 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.
|
||||
|
||||
**12.4 — [EVPI](#gloss:evpi-expected-value-of-perfect-information){.glossar-link} interpretieren.** Selbst eine **perfekte** Prognose wäre nur 8 400 € pro Jahr wert. Eine Lösung für 15 000 € kann sich also **niemals** rechnen — unabhängig von ihrer Güte. Argument: „Der theoretische Maximalnutzen liegt unter dem Preis.“
|
||||
**12.4 — [EVPI (Expected Value of Perfect Information)](#gloss:evpi-expected-value-of-perfect-information){.glossar-link} interpretieren.** Selbst eine **perfekte** Prognose wäre nur 8 400 € pro Jahr wert. Eine Lösung für 15 000 € kann sich also **niemals** rechnen — unabhängig von ihrer Güte. Argument: „Der theoretische Maximalnutzen liegt unter dem Preis.“
|
||||
|
||||
**12.5 — Monte-Carlo erweitern.** (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) `cvar = kosten[kosten >= np.quantile(kosten, 0.95)].mean()`. (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.
|
||||
|
||||
|
|
@ -26281,7 +26281,7 @@ Und die Formulierung gegenüber dem Auftraggeber lautet nicht „der Umbau dauer
|
|||
|
||||
**13.3 — [Rückwärtsinduktion](#gloss:rueckwaertsinduktion){.glossar-link}`\index{Rückwärtsinduktion}`{=latex}.** Mit $C(n) = n^2 + 2n$ und 5 Einheiten in 3 Perioden ergibt sich als optimaler Pfad $2 \to 2 \to 1$ (oder eine Permutation davon) mit Gesamtkosten $8 + 8 + 3 = 19$. Alles auf einmal kostet $25 + 10 = 35$.
|
||||
|
||||
**13.4 — Rucksack als [DP](#gloss:dynamische-programmierung-dp){.glossar-link}.**
|
||||
**13.4 — Rucksack als [DP (Dynamische Programmierung)](#gloss:dynamische-programmierung-dp){.glossar-link}.**
|
||||
```python
|
||||
V = np.zeros((n + 1, kapazitaet + 1))
|
||||
for i in range(1, n + 1):
|
||||
|
|
@ -26488,7 +26488,7 @@ Bei 40 Lieferanten hat die Kovarianzmatrix 820 zu schätzende Einträge. Wer daf
|
|||
|
||||
Benötigt würden: Lieferzeit-Zeitreihen je Lieferant über denselben Zeitraum, gleich getaktet. Genau daran scheitert es in der Praxis meist — die Daten liegen in Bestellvorgängen, nicht in einer Matrix.
|
||||
|
||||
**16.4 — [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link} mit Ganzzahligkeit.** Man ergänzt Binärvariablen $y_j$ je Lieferant und die Kopplung $w_j \le y_j$ sowie $\sum_j y_j \le 3$. Da CVXPY gemischt-ganzzahlige Probleme unterstützt, genügt `cp.Variable(n, boolean=True)`.
|
||||
**16.4 — [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link} mit Ganzzahligkeit.** Man ergänzt Binärvariablen $y_j$ je Lieferant und die Kopplung $w_j \le y_j$ sowie $\sum_j y_j \le 3$. Da CVXPY gemischt-ganzzahlige Probleme unterstützt, genügt `cp.Variable(n, boolean=True)`.
|
||||
|
||||
Zu erwarten ist ein **höherer** CVaR: Der zulässige Bereich wird kleiner, und die Feinabstimmung über sechs Lieferanten fällt weg. Der Aufschlag ist der Preis der Vertragswirklichkeit — und genau die Zahl, die man dem Einkauf vorlegt, wenn dort jemand sagt, drei Lieferanten seien genug.
|
||||
|
||||
|
|
@ -26649,7 +26649,7 @@ Und immer: **außerhalb des Schätzzeitraums prüfen.** Ein Modell, das nur im e
|
|||
### Selbsttest {#selbsttest-loesung-finanzdaten}
|
||||
1. Log-Renditen sind Differenzen von Logarithmen — die addieren sich über die Zeit. Diskrete Renditen sind lineare Anteile am Kapital — die addieren sich über gewichtete Positionen.
|
||||
2. Die Optimierung sucht die Richtungen kleinster geschätzter Varianz — genau jene, deren Eigenwerte am stärksten nach unten verzerrt sind. Sie optimiert dadurch in das Schätzrauschen hinein.
|
||||
3. Der Rang von $\mathbf{X}^\top\mathbf{X}$ ist höchstens $T < N$ — die Matrix ist nicht invertierbar, das [GMV](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}-Problem hat unendlich viele Lösungen.
|
||||
3. Der Rang von $\mathbf{X}^\top\mathbf{X}$ ist höchstens $T < N$ — die Matrix ist nicht invertierbar, das [GMV (Global Minimum Variance Portfolio)](#gloss:global-minimum-variance-portfolio-gmv){.glossar-link}-Problem hat unendlich viele Lösungen.
|
||||
4. Stichprobenmatrix (unverzerrt, verrauscht) mit strukturiertem Ziel (verzerrt, stabil). $\delta$ wird analytisch so bestimmt, dass der erwartete quadratische Fehler minimal wird.
|
||||
5. Skalierte Einheitsmatrix (sklearn) und Konstant-Korrelations-Ziel (LW 2003).
|
||||
|
||||
|
|
@ -26738,7 +26738,7 @@ Zusammen ergibt das das beobachtete Bild: 38 % Konzentration in einer Anlage, ob
|
|||
|
||||
## A.20 Lösungen zu Kapitel „Tail-Risiko, CVaR und Transaktionskosten`\index{Transaktionskosten}`{=latex}“ {#sec:loesungen-cvar}
|
||||
|
||||
**20.1 — [VaR](#gloss:value-at-risk-var){.glossar-link} und CVaR von Hand.** Sortierte Verluste: $-2{,}0; -1{,}2; -0{,}8; -0{,}4; 0{,}3; 0{,}6; 1{,}1; 2{,}1; 5{,}4; 8{,}9$. Das 80 %-Quantil ist der 8. Wert: $\text{VaR}_{80\%} = 2{,}1$. $\text{CVaR}_{80\%} = $ Mittel der schlechtesten 20 % $= (5{,}4+8{,}9)/2 = \mathbf{7{,}15}$.
|
||||
**20.1 — [VaR (Value at Risk)](#gloss:value-at-risk-var){.glossar-link} und CVaR von Hand.** Sortierte Verluste: $-2{,}0; -1{,}2; -0{,}8; -0{,}4; 0{,}3; 0{,}6; 1{,}1; 2{,}1; 5{,}4; 8{,}9$. Das 80 %-Quantil ist der 8. Wert: $\text{VaR}_{80\%} = 2{,}1$. $\text{CVaR}_{80\%} = $ Mittel der schlechtesten 20 % $= (5{,}4+8{,}9)/2 = \mathbf{7{,}15}$.
|
||||
|
||||
**20.2 — [Subadditivität](#gloss:subadditivitaet){.glossar-link}`\index{Subadditivität}`{=latex}.** Ein Risikomaß sollte Diversifikation nie bestrafen: Das Risiko eines zusammengelegten Portfolios darf nicht größer sein als die Summe der Einzelrisiken. Wird das verletzt, hätte eine Bank einen Anreiz, Portfolios künstlich aufzuspalten, um Eigenkapitalanforderungen zu senken — ökonomisch unsinnig.
|
||||
|
||||
|
|
@ -27002,7 +27002,7 @@ Was geholfen hätte — drei Dinge, keines davon ein Unit-Test:
|
|||
3. „Grün" heißt nur, dass kein Test fehlgeschlagen ist — das gilt auch für eine Suite aus lauter `assert True`. „Prüft etwas" heißt, dass die Tests bei einem eingebauten Fehler rot würden; genau das misst der Mutationstest.
|
||||
4. Weil sonst nicht erkennbar ist, welche Hälfte die Zeit kostet. Im Kapitel gehen bei OR-Tools 78 % in den Aufbau — wer nur die Gesamtzeit sieht, wechselt den Solver und ändert damit fast nichts.
|
||||
5. Weil die Rechnung Sekunden bis Minuten dauert. Eine synchrone Antwort läuft in den Timeout des Reverse Proxy und blockiert währenddessen einen Arbeiter. `202` heißt „angenommen, noch nicht fertig" — genau die richtige Aussage.
|
||||
6. Ein Threadpool genügt, wenn der Solver den [GIL](#gloss:gil-global-interpreter-lock){.glossar-link} freigibt — das tun die C++-Bibliotheken (OR-Tools, HiGHS) während `Solve()`, im Kapitel mit Faktor 3,5 bei vier Threads gemessen. Eine in reinem Python geschriebene Heuristik hält den GIL; für sie braucht es Prozesse.
|
||||
6. Ein Threadpool genügt, wenn der Solver den [GIL (Global Interpreter Lock)](#gloss:gil-global-interpreter-lock){.glossar-link} freigibt — das tun die C++-Bibliotheken (OR-Tools, HiGHS) während `Solve()`, im Kapitel mit Faktor 3,5 bei vier Threads gemessen. Eine in reinem Python geschriebene Heuristik hält den GIL; für sie braucht es Prozesse.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -27221,7 +27221,7 @@ for topf, grenze in BUDGETS.items():
|
|||
if TOPF[i] == topf) <= grenze)
|
||||
```
|
||||
|
||||
> 💡 **Der [Schattenpreis](#gloss:schattenpreis){.glossar-link}`\index{Schattenpreis}`{=latex} des Budgets ist die Zahl, nach der die Geschäftsführung fragt:** „Was bringt der nächste Euro?“ Bei einem **[LP](#gloss:lineare-programmierung-lp){.glossar-link}** ist er direkt ablesbar. Bei **Ganzzahligkeit gibt es ihn nicht** — die Dualwerte der [Relaxation](#gloss:relaxation){.glossar-link}`\index{Relaxation}`{=latex} sind keine gültige Antwort. Rechnen Sie stattdessen mit erhöhtem Budget neu und vergleichen Sie die Zielwerte ([Abschnitt 5.9](#sec:lp-entartung)).
|
||||
> 💡 **Der [Schattenpreis](#gloss:schattenpreis){.glossar-link}`\index{Schattenpreis}`{=latex} des Budgets ist die Zahl, nach der die Geschäftsführung fragt:** „Was bringt der nächste Euro?“ Bei einem **[LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}** ist er direkt ablesbar. Bei **Ganzzahligkeit gibt es ihn nicht** — die Dualwerte der [Relaxation](#gloss:relaxation){.glossar-link}`\index{Relaxation}`{=latex} sind keine gültige Antwort. Rechnen Sie stattdessen mit erhöhtem Budget neu und vergleichen Sie die Zielwerte ([Abschnitt 5.9](#sec:lp-entartung)).
|
||||
|
||||
> ⚠️ **Die LP-Relaxation verspricht zu viel.** Sie darf die letzte Maßnahme anteilig kaufen und liefert deshalb eine Schranke, die spürbar über dem tatsächlich Erreichbaren liegen kann. Wer sie als Prognose berichtet, verspricht Geld, das nicht kommt.
|
||||
|
||||
|
|
@ -27245,7 +27245,7 @@ Mit Mindestwartezeit $w$: $\text{start}_B \ge \text{ende}_A + w$.
|
|||
modell.AddNoOverlap([intervall_1, intervall_2, ...])
|
||||
```
|
||||
|
||||
In [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} bräuchte man je Paar eine Disjunktion (B4) — bei $k$ Jobs sind das $\binom{k}{2}$ Konstruktionen. **Nehmen Sie hier [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex}.**
|
||||
In [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} bräuchte man je Paar eine Disjunktion (B4) — bei $k$ Jobs sind das $\binom{k}{2}$ Konstruktionen. **Nehmen Sie hier [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex}.**
|
||||
|
||||
### B15 — Kumulative Ressource
|
||||
|
||||
|
|
@ -27370,7 +27370,7 @@ $$\sum_j x_{ij} = 1\ \forall i,\qquad \sum_i x_{ij} = 1\ \forall j,\qquad x_{ij}
|
|||
|
||||
**MTZ (einfach, aber schwach):**`\index{MTZ-Formulierung}`{=latex} $$u_i - u_j + C x_{ij} \le C - d_j \qquad \forall i\ne j$$
|
||||
|
||||
**Besser in der Praxis:**`\index{Subtour!Eliminierung}`{=latex} `AddCircuit` in [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} oder die [Routing-Bibliothek](#gloss:routing-bibliothek){.glossar-link}`\index{Routing-Bibliothek}`{=latex} von [OR-Tools](#gloss:or-tools){.glossar-link}.
|
||||
**Besser in der Praxis:**`\index{Subtour!Eliminierung}`{=latex} `AddCircuit` in [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} oder die [Routing-Bibliothek](#gloss:routing-bibliothek){.glossar-link}`\index{Routing-Bibliothek}`{=latex} von [OR-Tools](#gloss:or-tools){.glossar-link}.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -27458,7 +27458,7 @@ for kunde, (frueh, spaet) in enumerate(zeitfenster):
|
|||
|
||||
> Nimm eine Bedingung versuchsweise heraus. Bleibt der Rest unlösbar, wurde sie nicht gebraucht: weg damit, endgültig. Wird der Rest lösbar, war sie beteiligt: sie bleibt.
|
||||
|
||||
Nach genau einem Durchlauf über alle $n$ Bedingungen ist die übrig gebliebene Menge`\index{Konvexität!Menge}`{=latex} **unreduzierbar** — entfernt man aus ihr irgendeine Bedingung, ist der Rest lösbar. Das ist ein *Irreducible Infeasible Subset*`\index{IIS (Irreducible Infeasible Subset)}`{=latex}, kurz [IIS](#gloss:iis-irreducible-infeasible-subset){.glossar-link}. Kommerzielle Solver bieten das als fertige Funktion`\index{Konvexität!Funktion}`{=latex} an (`computeIIS` bei [Gurobi](#gloss:gurobi){.glossar-link}`\index{Gurobi}`{=latex}, der Conflict Refiner bei CPLEX); im Open-Source-Werkzeugkasten dieses Buchs gibt es sie nicht — sie ist aber in zwanzig Zeilen selbst geschrieben, und sie kostet $n$ Aufrufe des Solvers statt $2^n$ durchprobierter Teilmengen.
|
||||
Nach genau einem Durchlauf über alle $n$ Bedingungen ist die übrig gebliebene Menge`\index{Konvexität!Menge}`{=latex} **unreduzierbar** — entfernt man aus ihr irgendeine Bedingung, ist der Rest lösbar. Das ist ein *Irreducible Infeasible Subset*`\index{IIS (Irreducible Infeasible Subset)}`{=latex}, kurz [IIS (Irreducible Infeasible Subset)](#gloss:iis-irreducible-infeasible-subset){.glossar-link}. Kommerzielle Solver bieten das als fertige Funktion`\index{Konvexität!Funktion}`{=latex} an (`computeIIS` bei [Gurobi](#gloss:gurobi){.glossar-link}`\index{Gurobi}`{=latex}, der Conflict Refiner bei CPLEX); im Open-Source-Werkzeugkasten dieses Buchs gibt es sie nicht — sie ist aber in zwanzig Zeilen selbst geschrieben, und sie kostet $n$ Aufrufe des Solvers statt $2^n$ durchprobierter Teilmengen.
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
|
|
@ -27848,11 +27848,11 @@ print(f"Aufbau {t1-t0:.2f}s | Loesen {t2-t1:.2f}s")
|
|||
```
|
||||
Bei CVXPY und bei Schleifen über Szenarien ist oft der **Aufbau** der Engpass, nicht der Solver (siehe [Abschnitt 20.6](#sec:cvar-implementierung-cvar-portfolio-mit-reibung)).
|
||||
|
||||
**2. Big-M zu groß?** Der häufigste Grund für explodierende [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}-Laufzeiten. Setzen Sie $M$ auf die kleinste gültige Schranke ([Abschnitt 6.5](#sec:milp-modellierungstricks-big-m-und-logische-bedingungen)).
|
||||
**2. Big-M zu groß?** Der häufigste Grund für explodierende [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link}-Laufzeiten. Setzen Sie $M$ auf die kleinste gültige Schranke ([Abschnitt 6.5](#sec:milp-modellierungstricks-big-m-und-logische-bedingungen)).
|
||||
|
||||
**3. Symmetrie im Modell?** Identische Maschinen, austauschbare Mitarbeitende, gleichwertige Fahrzeuge — der Solver durchsucht alle Vertauschungen. Abhilfe: Ordnungsbedingungen (Muster B20).
|
||||
|
||||
**4. Falsche Solverfamilie?** Zuordnungsprobleme mit MILP, Routing mit [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} von Hand nachgebaut, konvexe Probleme mit `scipy.optimize.minimize` — jeweils Größenordnungen langsamer als das passende Werkzeug ([Abschnitt 3.6](#sec:oekosystem-wann-lohnt-sich-welche-ebene)).
|
||||
**4. Falsche Solverfamilie?** Zuordnungsprobleme mit MILP, Routing mit [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} von Hand nachgebaut, konvexe Probleme mit `scipy.optimize.minimize` — jeweils Größenordnungen langsamer als das passende Werkzeug ([Abschnitt 3.6](#sec:oekosystem-wann-lohnt-sich-welche-ebene)).
|
||||
|
||||
**5. Wird vektorisiert?**
|
||||
```python
|
||||
|
|
@ -27990,9 +27990,9 @@ cvxpy.error.DCPError: Problem does not follow DCP rules.
|
|||
|
||||
| Problematischer Ausdruck | Warum | Lösung |
|
||||
| ------------------------------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `x * y` (beide Variablen) | bilinear | umformulieren oder MILP/[NLP](#gloss:nichtlineare-programmierung-nlp){.glossar-link} |
|
||||
| `x * y` (beide Variablen) | bilinear | umformulieren oder MILP/[NLP (Nichtlineare Programmierung)](#gloss:nichtlineare-programmierung-nlp){.glossar-link} |
|
||||
| `a / x` | nicht konvex | `cp.inv_pos(x)` bei $x>0$ |
|
||||
| `cp.sqrt(cp.quad_form(w, S))` | `cp.sqrt` ist **konkav** und verlangt ein konkaves Argument — `quad_form` ist konvex. Der Ausdruck ist nie [DCP](#gloss:dcp-disciplined-convex-programming){.glossar-link}, egal wie sauber $S$ ist | Cholesky $S = LL^\top$, dann `cp.norm2(L.T @ w)`: die 2-Norm eines **affinen** Ausdrucks (siehe `CVaR_Portfolio.py`) |
|
||||
| `cp.sqrt(cp.quad_form(w, S))` | `cp.sqrt` ist **konkav** und verlangt ein konkaves Argument — `quad_form` ist konvex. Der Ausdruck ist nie [DCP (Disciplined Convex Programming)](#gloss:dcp-disciplined-convex-programming){.glossar-link}, egal wie sauber $S$ ist | Cholesky $S = LL^\top$, dann `cp.norm2(L.T @ w)`: die 2-Norm eines **affinen** Ausdrucks (siehe `CVaR_Portfolio.py`) |
|
||||
| `cp.quad_form(w, S)` bei numerisch unsauberem $S$ | Eigenwerte knapp unter null durch Rundung — CVXPY erkennt $S$ nicht als PSD | `cp.psd_wrap(S)`, **wenn** $S$ nachweislich PSD ist (z. B. eine Kovarianzmatrix). Behebt nur diese numerische Beanstandung, keine Regelverletzung im Aufbau |
|
||||
| Quotient (z. B. [Sharpe Ratio](#gloss:sharpe-ratio){.glossar-link}`\index{Sharpe-Ratio}`{=latex}) | nicht konvex | [Korn-Transformation](#gloss:korn-transformation){.glossar-link}`\index{Korn-Transformation}`{=latex} ([Abschnitt 19.4](#sec:markowitz-das-mean-variance-modell)) |
|
||||
| `cp.log(x)` maximieren | konkav — das ist **erlaubt** | in `cp.Maximize` verwenden |
|
||||
|
|
@ -28083,7 +28083,7 @@ tech_indices = [0, 1, 2, 3] # SCHLECHT
|
|||
|
||||
$$\max\; 10x_1 + 15x_2 + 25x_3 \quad\text{u.d.N.}\quad x_1 + x_2 + 2x_3 \le 40,\;\; 2x_1 + 3x_2 + x_3 \le 50,\;\; x \ge 0$$
|
||||
|
||||
Damit ist jeder Schnipsel selbstprüfend: Kommt bei Ihnen etwas anderes als 530 heraus, liegt es an der Übertragung, nicht am Modell. (Die Ausnahme ist [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} — ein rein stetiges [LP](#gloss:lineare-programmierung-lp){.glossar-link} ist dort das falsche Werkzeug; die Seite zeigt stattdessen die [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link}-eigenen Bausteine.)
|
||||
Damit ist jeder Schnipsel selbstprüfend: Kommt bei Ihnen etwas anderes als 530 heraus, liegt es an der Übertragung, nicht am Modell. (Die Ausnahme ist [CP-SAT](#gloss:cp-sat){.glossar-link}`\index{CP-SAT}`{=latex} — ein rein stetiges [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link} ist dort das falsche Werkzeug; die Seite zeigt stattdessen die [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link}-eigenen Bausteine.)
|
||||
|
||||
> **Was dieser Anhang *nicht* ist.** Kein Vergleich und keine Empfehlung. Welche Bibliothek für welche Aufgabe taugt, steht in [Abschnitt 3.6](#sec:oekosystem-wann-lohnt-sich-welche-ebene); denselben Fall in vier Bibliotheken *nebeneinander* zeigt `Ein_System_Vier_Ansaetze.py`, die beiden Modellierungssprachen `Modellierungsschichten.py`. Hier geht es allein ums Nachschlagen.
|
||||
|
||||
|
|
@ -28207,7 +28207,7 @@ else:
|
|||
|
||||
## D3 — OR-Tools`\index{OR-Tools}`{=latex}: `pywraplp`
|
||||
|
||||
**Wofür.** Bequeme algebraische Schreibweise für LP und [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} mit umschaltbarem Backend (`GLOP`, `SCIP`, `CBC`, `SAT`). **Wofür nicht:** [Scheduling](#gloss:scheduling){.glossar-link} und kombinatorische Bedingungen — dafür ist CP-SAT (D4) da.
|
||||
**Wofür.** Bequeme algebraische Schreibweise für LP und [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} mit umschaltbarem Backend (`GLOP`, `SCIP`, `CBC`, `SAT`). **Wofür nicht:** [Scheduling](#gloss:scheduling){.glossar-link} und kombinatorische Bedingungen — dafür ist CP-SAT (D4) da.
|
||||
|
||||
```python
|
||||
from ortools.linear_solver import pywraplp
|
||||
|
|
@ -28299,7 +28299,7 @@ print(f"Laufzeit {loeser.WallTime():.3f}s, {loeser.NumBranches()} Verzweigungen"
|
|||
|
||||
## D5 — CVXPY`\index{CVXPY}`{=latex}
|
||||
|
||||
**Wofür.** Konvexe Probleme: quadratische Ziele, Normen, [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link}, alles mit Regularisierungstermen. **Wofür nicht:** große kombinatorische Modelle — der Aufbau der Ausdrücke wird dann selbst zum Engpass.
|
||||
**Wofür.** Konvexe Probleme: quadratische Ziele, Normen, [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link}, alles mit Regularisierungstermen. **Wofür nicht:** große kombinatorische Modelle — der Aufbau der Ausdrücke wird dann selbst zum Engpass.
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
|
|
@ -28332,7 +28332,7 @@ else:
|
|||
|
||||
### Die drei häufigsten Stolpersteine
|
||||
|
||||
1. **[DCP](#gloss:dcp-disciplined-convex-programming){.glossar-link}-Regeln vor dem Lösen prüfen.** `problem.is_dcp()` und dann die einzelnen Bedingungen — das nennt die Schuldige, statt einen `DCPError` ohne Ort zu werfen ([Anhang C](#anhang-fehlerdiagnose), C8).
|
||||
1. **[DCP (Disciplined Convex Programming)](#gloss:dcp-disciplined-convex-programming){.glossar-link}-Regeln vor dem Lösen prüfen.** `problem.is_dcp()` und dann die einzelnen Bedingungen — das nennt die Schuldige, statt einen `DCPError` ohne Ort zu werfen ([Anhang C](#anhang-fehlerdiagnose), C8).
|
||||
2. **`OPTIMAL_INACCURATE` ist kein Erfolg.** Der Solver hat aufgegeben und meldet das leise. Diesen Fall immer eigens behandeln.
|
||||
3. **Der Aufbau kann teurer sein als das Lösen.** Schleifen über Szenarien durch Vektorausdrücke ersetzen; `Parameter` statt Neuaufbau, wenn sich nur Zahlen ändern.
|
||||
|
||||
|
|
@ -28437,6 +28437,11 @@ Alle sechs Seiten haben denselben längsten Abschnitt: die **Statusauswertung**.
|
|||
|
||||
Nachschlagewerk zu allen Fachbegriffen, Abkürzungen, Algorithmen und Bibliotheken dieses Buchs. Jeder Eintrag nennt am Ende den Abschnitt, in dem der Begriff eingeführt wird — ein Klick dorthin führt in der Online-Fassung direkt zur Erklärung im Zusammenhang. Wer einen Begriff an *allen* Fundstellen sucht, benutzt das Stichwortverzeichnis.
|
||||
|
||||
```{=html}
|
||||
<nav class="register-sprungleiste"><a href="#a">A</a> <a href="#b">B</a> <a href="#c">C</a> <a href="#d">D</a> <a href="#e">E</a> <a href="#f">F</a> <a href="#g">G</a> <a href="#h">H</a> <a href="#i">I</a> <a href="#j">J</a> <a href="#k">K</a> <a href="#l">L</a> <a href="#m">M</a> <a href="#n">N</a> <a href="#o">O</a> <a href="#p">P</a> <a href="#q">Q</a> <a href="#r">R</a> <a href="#s">S</a> <a href="#t">T</a> <a href="#u">U</a> <a href="#v">V</a> <a href="#w">W</a> <a href="#y">Y</a> <a href="#z">Z</a></nav>
|
||||
```
|
||||
|
||||
|
||||
## A
|
||||
|
||||
::: {#gloss:absolutbetrag}
|
||||
|
|
@ -29484,7 +29489,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
* ★★★ **Wolsey, L. A. (2020):** *Integer Programming* (2. Aufl.). Wiley, Hoboken. DOI: 10.1002/9781119606475 [Ganzzahlige Optimierung] *[Branch-and-Bound](#gloss:branch-and-bound){.glossar-link}, [Branch-and-Cut](#gloss:branch-and-cut){.glossar-link}, Polyedertheorie, Formulierungsstärke. Die Begründung dafür, warum ein kleines $M$ besser ist als ein großes.*
|
||||
* ★★★ **Conforti, M., Cornuéjols, G. & Zambelli, G. (2014):** *Integer Programming.* Springer, Cham. DOI: 10.1007/978-3-319-11008-0 [Ganzzahlige Optimierung] *Modernere Darstellung als Wolsey, mit ausführlicher Behandlung von Schnittebenen und totaler Unimodularität.*
|
||||
* ★★ **Klotz, E. & Newman, A. M. (2013):** *Practical guidelines for solving difficult mixed integer linear programs.* In: *Surveys in Operations Research and Management Science* 18(1–2), S. 18–32. DOI: 10.1016/j.sorms.2012.12.001 [Ganzzahlige Optimierung] *Was zu tun ist, wenn ein Modell nicht fertig rechnet — Skalierung, Formulierung, Symmetrie. Die Literaturgrundlage von [Anhang C](#anhang-fehlerdiagnose).*
|
||||
* ★★ **Achterberg, T. (2009):** *[SCIP](#gloss:scip){.glossar-link}: solving constraint integer programs.* In: *Mathematical Programming Computation* 1(1), S. 1–41. DOI: 10.1007/s12532-008-0001-1 [[Solver](#gloss:solver){.glossar-link}: SCIP] *Beschreibt die Verbindung von [MILP](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} und Constraint Programming in einem Solver.*
|
||||
* ★★ **Achterberg, T. (2009):** *[SCIP](#gloss:scip){.glossar-link}: solving constraint integer programs.* In: *Mathematical Programming Computation* 1(1), S. 1–41. DOI: 10.1007/s12532-008-0001-1 [[Solver](#gloss:solver){.glossar-link}: SCIP] *Beschreibt die Verbindung von [MILP (Gemischt-ganzzahlige Optimierung)](#gloss:gemischt-ganzzahlige-optimierung-milp){.glossar-link} und Constraint Programming in einem Solver.*
|
||||
|
||||
## Moderne Solver: Implementierung, Vergleich und Benchmarks
|
||||
|
||||
|
|
@ -29492,7 +29497,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
|
||||
* ★★★ **Huangfu, Q. & Hall, J. A. J. (2018):** *Parallelizing the dual revised simplex method.* In: *Mathematical Programming Computation* 10(1), S. 119–142. DOI: 10.1007/s12532-017-0130-5 [Solver: [HiGHS](#gloss:highs){.glossar-link}] *Die vom HiGHS-Projekt selbst benannte Zitierquelle. HiGHS ist das Backend von `scipy.optimize.linprog` und CVXPY. [highs.dev](https://highs.dev)*
|
||||
* ★★★ **Gleixner, A., Hendel, G., Gamrath, G. et al. (2021):** *MIPLIB 2017: data-driven compilation of the 6th mixed-integer programming library.* In: *Mathematical Programming Computation* 13(3), S. 443–490. DOI: 10.1007/s12532-020-00194-3 [Benchmarks] *Die Testmenge, auf der praktisch jeder Solververgleich beruht: 1065 Instanzen, davon 240 als Benchmark-Teilmenge. Frei zugänglich; Daten unter [miplib.zib.de](https://miplib.zib.de).*
|
||||
* ★★★ **Mittelmann, H. D.:** *Benchmarks for Optimization Software.* Arizona State University. [plato.asu.edu/bench.html](https://plato.asu.edu/bench.html) [Benchmarks] *Die laufend aktualisierte Referenzmessung für [LP](#gloss:lineare-programmierung-lp){.glossar-link}-, MILP- und [QP](#gloss:quadratische-programmierung-qp){.glossar-link}-Solver. **Wichtige Einschränkung:** Seit 2024 sind die kommerziellen Solver auf eigenen Wunsch nicht mehr enthalten; ein direkter Vergleich [Gurobi](#gloss:gurobi){.glossar-link} gegen HiGHS ist dort nicht mehr möglich.*
|
||||
* ★★★ **Mittelmann, H. D.:** *Benchmarks for Optimization Software.* Arizona State University. [plato.asu.edu/bench.html](https://plato.asu.edu/bench.html) [Benchmarks] *Die laufend aktualisierte Referenzmessung für [LP (Lineare Programmierung)](#gloss:lineare-programmierung-lp){.glossar-link}-, MILP- und [QP (Quadratische Programmierung)](#gloss:quadratische-programmierung-qp){.glossar-link}-Solver. **Wichtige Einschränkung:** Seit 2024 sind die kommerziellen Solver auf eigenen Wunsch nicht mehr enthalten; ein direkter Vergleich [Gurobi](#gloss:gurobi){.glossar-link} gegen HiGHS ist dort nicht mehr möglich.*
|
||||
* ★★ **Bolusani, S., Besançon, M., Bestuzheva, K. et al. (2024):** *The SCIP Optimization Suite 9.0.* Technischer Bericht, Zuse-Institut Berlin. arXiv:2402.17702 [Solver: SCIP] *Beschreibt Aufbau und Komponenten der Suite. Die Reihe wird fortgeschrieben — die jeweils aktuelle Fassung steht unter [scipopt.org](https://www.scipopt.org); beim Zitieren die tatsächlich benutzte Version angeben.*
|
||||
* ★★ **Perron, L. & Furnon, V.:** *[OR-Tools](#gloss:or-tools){.glossar-link}.* Google. [developers.google.com/optimization](https://developers.google.com/optimization) · Quellcode: [github.com/google/or-tools](https://github.com/google/or-tools) [Solver: OR-Tools] *Die Sammlung, aus der das Buch [CP-SAT](#gloss:cp-sat){.glossar-link} und die [Routing-Bibliothek](#gloss:routing-bibliothek){.glossar-link} benutzt.*
|
||||
|
||||
|
|
@ -29501,7 +29506,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
*Zu [Kapitel 7](#kap-cpsat).*
|
||||
|
||||
* ★★★ **Rossi, F., van Beek, P. & Walsh, T. (Hrsg., 2006):** *Handbook of Constraint Programming.* Foundations of Artificial Intelligence, Bd. 2. Elsevier, Amsterdam. [Constraint Programming] *Nach wie vor das Referenzwerk zu Propagation, globalen Constraints und Suchstrategien.*
|
||||
* ★★★ **Perron, L. & Furnon, V.:** *OR-Tools [CP](#gloss:constraint-programming-cp){.glossar-link}-[SAT](#gloss:sat-boolean-satisfiability){.glossar-link} Solver Documentation.* Google. [developers.google.com/optimization/cp](https://developers.google.com/optimization/cp) [Solver: CP-SAT] *Die einzige vollständige Beschreibung des im Buch benutzten Solvers. Der Abschnitt zu `AddNoOverlap` und `AddCumulative` deckt sich mit [Kapitel 7](#kap-cpsat).*
|
||||
* ★★★ **Perron, L. & Furnon, V.:** *OR-Tools [CP (Constraint Programming)](#gloss:constraint-programming-cp){.glossar-link}-[SAT (Boolean Satisfiability)](#gloss:sat-boolean-satisfiability){.glossar-link} Solver Documentation.* Google. [developers.google.com/optimization/cp](https://developers.google.com/optimization/cp) [Solver: CP-SAT] *Die einzige vollständige Beschreibung des im Buch benutzten Solvers. Der Abschnitt zu `AddNoOverlap` und `AddCumulative` deckt sich mit [Kapitel 7](#kap-cpsat).*
|
||||
* ★★ **Laborie, P., Rogerie, J., Shaw, P. & Vilím, P. (2018):** *IBM ILOG CP Optimizer for scheduling.* In: *Constraints* 23(2), S. 210–250. DOI: 10.1007/s10601-018-9281-x [[Scheduling](#gloss:scheduling){.glossar-link}] *Intervallvariablen und Ressourcenprofile aus Sicht des konkurrierenden Solvers — lehrreich für das Verständnis der Modellierungsprimitive.*
|
||||
* ★★ **Biere, A., Heule, M., van Maaren, H. & Walsh, T. (Hrsg., 2021):** *Handbook of Satisfiability* (2. Aufl.). Frontiers in Artificial Intelligence and Applications, Bd. 336. IOS Press, Amsterdam. DOI: 10.3233/FAIA336 [SAT] *Die Grundlage dessen, was CP-SAT unter der Haube tut: Conflict-Driven Clause Learning, Klausellernen, Neustarts.*
|
||||
|
||||
|
|
@ -29510,7 +29515,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
*Zu [Kapitel 8](#kap-graphen). Neuer Abschnitt.*
|
||||
|
||||
* ★★★ **Ahuja, R. K., Magnanti, T. L. & Orlin, J. B. (1993):** *Network Flows: Theory, Algorithms, and Applications.* Prentice Hall, Englewood Cliffs. [Netzwerkflüsse] *Das Standardwerk zu Min-Cost-Flow, Matching und totaler Unimodularität — der Grund, warum diese Modelle schon als LP ganzzahlig lösen.*
|
||||
* ★★★ **Toth, P. & Vigo, D. (Hrsg., 2014):** *Vehicle Routing: Problems, Methods, and Applications* (2. Aufl.). SIAM, Philadelphia. DOI: 10.1137/1.9781611973594 [[VRP](#gloss:vehicle-routing-problem-vrp){.glossar-link}] *Das Referenzwerk zur Tourenplanung, einschließlich Kapazitäten, Zeitfenstern und [Subtour](#gloss:subtour){.glossar-link}-Eliminierung.*
|
||||
* ★★★ **Toth, P. & Vigo, D. (Hrsg., 2014):** *Vehicle Routing: Problems, Methods, and Applications* (2. Aufl.). SIAM, Philadelphia. DOI: 10.1137/1.9781611973594 [[VRP (Vehicle Routing Problem)](#gloss:vehicle-routing-problem-vrp){.glossar-link}] *Das Referenzwerk zur Tourenplanung, einschließlich Kapazitäten, Zeitfenstern und [Subtour](#gloss:subtour){.glossar-link}-Eliminierung.*
|
||||
* ★★ **Vidal, T., Laporte, G. & Matl, P. (2020):** *A concise guide to existing and emerging vehicle routing problem variants.* In: *European Journal of Operational Research* 286(2), S. 401–416. DOI: 10.1016/j.ejor.2019.10.010 [VRP] *Übersicht über die Variantenvielfalt — hilfreich, um die eigene Aufgabe einzuordnen, bevor man modelliert. Frei zugänglich als arXiv:1906.06750.*
|
||||
* ★ **Kuhn, H. W. (1955):** *The Hungarian method for the assignment problem.* In: *Naval Research Logistics Quarterly* 2(1–2), S. 83–97. DOI: 10.1002/nav.3800020109 [[Zuordnungsproblem](#gloss:zuordnungsproblem){.glossar-link}] *Das Originalverfahren hinter `scipy.optimize.linear_sum_assignment`.*
|
||||
|
||||
|
|
@ -29518,7 +29523,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
|
||||
*Zu [Kapitel 9](#kap-metaheuristiken). Neuer Abschnitt.*
|
||||
|
||||
* ★★★ **Gendreau, M. & Potvin, J.-Y. (Hrsg., 2019):** *Handbook of Metaheuristics* (3. Aufl.). Springer, Cham. DOI: 10.1007/978-3-319-91086-4 [Metaheuristiken] *Sammelband zu [Tabu-Suche](#gloss:tabu-suche){.glossar-link}, [Simulated Annealing](#gloss:simulated-annealing){.glossar-link}, [LNS](#gloss:large-neighborhood-search-lns){.glossar-link}, genetischen Verfahren — jeweils von den Urhebern geschrieben.*
|
||||
* ★★★ **Gendreau, M. & Potvin, J.-Y. (Hrsg., 2019):** *Handbook of Metaheuristics* (3. Aufl.). Springer, Cham. DOI: 10.1007/978-3-319-91086-4 [Metaheuristiken] *Sammelband zu [Tabu-Suche](#gloss:tabu-suche){.glossar-link}, [Simulated Annealing](#gloss:simulated-annealing){.glossar-link}, [LNS (Large Neighborhood Search)](#gloss:large-neighborhood-search-lns){.glossar-link}, genetischen Verfahren — jeweils von den Urhebern geschrieben.*
|
||||
* ★★★ **Pisinger, D. & Ropke, S. (2010):** *Large Neighborhood Search.* In: Gendreau, M. & Potvin, J.-Y. (Hrsg.): *Handbook of Metaheuristics*, S. 399–419. Springer. DOI: 10.1007/978-1-4419-1665-5_13 [Metaheuristiken] *Die Darstellung des Verfahrens, das im Buch die exakte Suche auf Teilproblemen mit heuristischem Zerstören verbindet.*
|
||||
* ★★ **Kirkpatrick, S., Gelatt, C. D. & Vecchi, M. P. (1983):** *Optimization by Simulated Annealing.* In: *Science* 220(4598), S. 671–680. DOI: 10.1126/science.220.4598.671 [Metaheuristiken] *Die Originalarbeit; die Abkühlungsanalogie stammt von hier.*
|
||||
* ★★ **Sörensen, K. (2015):** *Metaheuristics — the metaphor exposed.* In: *International Transactions in Operational Research* 22(1), S. 3–18. DOI: 10.1111/itor.12001 [Metaheuristiken] *Kritik an der Flut naturanaloger „neuer" Verfahren. Vor der Auswahl einer [Metaheuristik](#gloss:metaheuristik){.glossar-link} zu lesen — sie erspart viel Zeit.*
|
||||
|
|
@ -29535,7 +29540,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
|
||||
*Zu [Kapitel 11](#kap-qp-nlp).*
|
||||
|
||||
* ★★★ **Boyd, S. & Vandenberghe, L. (2004):** *Convex Optimization.* Cambridge University Press. DOI: 10.1017/CBO9780511804441 [Konvexe Optimierung] *Referenzwerk für konvexe Mengen, [KKT](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}-Bedingungen, QP und SDP; die theoretische Basis von CVXPY. Frei verfügbar unter [stanford.edu/~boyd/cvxbook](https://web.stanford.edu/~boyd/cvxbook/).*
|
||||
* ★★★ **Boyd, S. & Vandenberghe, L. (2004):** *Convex Optimization.* Cambridge University Press. DOI: 10.1017/CBO9780511804441 [Konvexe Optimierung] *Referenzwerk für konvexe Mengen, [KKT (Karush-Kuhn-Tucker-Bedingungen)](#gloss:karush-kuhn-tucker-bedingungen-kkt){.glossar-link}-Bedingungen, QP und SDP; die theoretische Basis von CVXPY. Frei verfügbar unter [stanford.edu/~boyd/cvxbook](https://web.stanford.edu/~boyd/cvxbook/).*
|
||||
* ★★ **Kraft, D. (1988):** *A Software Package for Sequential Quadratic Programming.* DFVLR-FB 88-28, Deutsche Forschungs- und Versuchsanstalt für Luft- und Raumfahrt, Köln. [Nichtlineare Optimierung] *Die Originalarbeit zu [SLSQP](#gloss:slsqp){.glossar-link} — dem Verfahren hinter `scipy.optimize.minimize`.*
|
||||
* ★★ **Lobo, M. S., Vandenberghe, L., Boyd, S. & Lebret, H. (1998):** *Applications of second-order cone programming.* In: *Linear Algebra and its Applications* 284(1–3), S. 193–228. DOI: 10.1016/S0024-3795(98)10032-0 [[Konische Optimierung](#gloss:konische-optimierung){.glossar-link}] *Warum sich Risikoschranken und Normbedingungen als SOCP schreiben lassen — die Grundlage der Chance-Constraints-Formulierung in [Kapitel 12](#kap-unsicherheit).*
|
||||
|
||||
|
|
@ -29543,7 +29548,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
|
||||
*Zu [Kapitel 12](#kap-unsicherheit) und [Kapitel 17](#kap-supplychain). Aus dem früheren Block „Konvexe, nichtlineare und robuste Optimierung" herausgelöst und erweitert.*
|
||||
|
||||
* ★★★ **Birge, J. R. & Louveaux, F. (2011):** *Introduction to Stochastic Programming* (2. Aufl.). Springer, New York. DOI: 10.1007/978-1-4614-0237-4 [Stochastische Optimierung] *Das Standardwerk zur zweistufigen Optimierung, Szenariobäumen und dem Wert perfekter Information ([EVPI](#gloss:evpi-expected-value-of-perfect-information){.glossar-link}).*
|
||||
* ★★★ **Birge, J. R. & Louveaux, F. (2011):** *Introduction to Stochastic Programming* (2. Aufl.). Springer, New York. DOI: 10.1007/978-1-4614-0237-4 [Stochastische Optimierung] *Das Standardwerk zur zweistufigen Optimierung, Szenariobäumen und dem Wert perfekter Information ([EVPI (Expected Value of Perfect Information)](#gloss:evpi-expected-value-of-perfect-information){.glossar-link}).*
|
||||
* ★★★ **Ben-Tal, A., El Ghaoui, L. & Nemirovski, A. (2009):** *Robust Optimization.* Princeton University Press. DOI: 10.1515/9781400831050 [[Robuste Optimierung](#gloss:robuste-optimierung){.glossar-link}] *Die geschlossene Darstellung der robusten Gegenstücke und ihrer konischen Umformung.*
|
||||
* ★★★ **Bertsimas, D. & Sim, M. (2004):** *The Price of Robustness.* In: *Operations Research* 52(1), S. 35–53. DOI: 10.1287/opre.1030.0065 [Robuste Optimierung] *Quelle des Budgeted-Uncertainty-Ansatzes: Der [Parameter](#gloss:parameter){.glossar-link} $\Gamma$ regelt stufenlos, wie vorsichtig die Lösung wird.*
|
||||
* ★★ **Nemirovski, A. & Shapiro, A. (2007):** *Convex Approximations of Chance Constrained Programs.* In: *SIAM Journal on Optimization* 17(4), S. 969–996. DOI: 10.1137/050622328 [Chance Constraints] *Zeigt, wann sich eine Wahrscheinlichkeitsbedingung konvex annähern lässt — und wann nicht.*
|
||||
|
|
@ -29590,7 +29595,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
*Zu [Kapitel 18](#kap-finanzdaten), [Kapitel 19](#kap-markowitz), [Kapitel 20](#kap-cvar) und [Kapitel 21](#kap-handelsmaschine).*
|
||||
|
||||
* ★★★ **Markowitz, H. (1952):** *Portfolio Selection.* In: *The Journal of Finance* 7(1), S. 77–91. DOI: 10.2307/2975974 [Portfoliotheorie] *Die Arbeit, die das Zusammenspiel von Rendite und Kovarianz zum Optimierungsproblem gemacht hat.*
|
||||
* ★★★ **Rockafellar, R. T. & Uryasev, S. (2000):** *Optimization of Conditional Value-at-Risk.* In: *Journal of Risk* 2(3), S. 21–41. DOI: 10.21314/JOR.2000.038 [Risikomaße] *Der Satz, der die [CVaR](#gloss:conditional-value-at-risk-cvar){.glossar-link}-Minimierung in ein lineares Programm überführt.*
|
||||
* ★★★ **Rockafellar, R. T. & Uryasev, S. (2000):** *Optimization of Conditional Value-at-Risk.* In: *Journal of Risk* 2(3), S. 21–41. DOI: 10.21314/JOR.2000.038 [Risikomaße] *Der Satz, der die [CVaR (Conditional Value at Risk)](#gloss:conditional-value-at-risk-cvar){.glossar-link}-Minimierung in ein lineares Programm überführt.*
|
||||
* ★★★ **Ledoit, O. & Wolf, M. (2004):** *A well-conditioned estimator for large-dimensional covariance matrices.* In: *Journal of Multivariate Analysis* 88(2), S. 365–411. DOI: 10.1016/S0047-259X(03)00096-4 [Kovarianzschätzung] *Quelle des von `scikit-learn` verwendeten Shrinkage-Ziels (skalierte Einheitsmatrix).*
|
||||
* ★★★ **Cornuéjols, G., Peña, J. & Tütüncü, R. (2018):** *Optimization Methods in Finance* (2. Aufl.). Cambridge University Press. DOI: 10.1017/9781107297340 [Finanzoptimierung] *Die Brücke zwischen Optimierungstheorie und Finanzanwendung; deckt QP, SOCP und robuste Portfolios ab.*
|
||||
* ★★★ **Almgren, R. & Chriss, N. (2001):** *Optimal Execution of Portfolio Transactions.* In: *Journal of Risk* 3(2), S. 5–39. DOI: 10.21314/jor.2001.041 [Orderausführung] *Das Modell hinter dem Beispiel zur optimalen Orderausführung in [Kapitel 13](#kap-dynamische-programmierung).*
|
||||
|
|
@ -29603,7 +29608,7 @@ Frei zugängliche Fassungen sind vermerkt. Wo eine DOI angegeben ist, führt sie
|
|||
|
||||
*Zu [Kapitel 22](#kap-praxisfallen) und [Kapitel 23](#kap-testing). Neuer Abschnitt.*
|
||||
|
||||
* ★★★ **Chinneck, J. W. (2008):** *Feasibility and [Infeasibility](#gloss:infeasibility){.glossar-link} in Optimization: Algorithms and Computational Methods.* Springer, New York. DOI: 10.1007/978-0-387-74932-7 [Fehlerdiagnose] *Das Standardwerk zur Unlösbarkeitsdiagnose, einschließlich des Deletion Filters und der irreduziblen unlösbaren Teilmengen ([IIS](#gloss:iis-irreducible-infeasible-subset){.glossar-link}). Direkte Grundlage von [Anhang C](#anhang-fehlerdiagnose).*
|
||||
* ★★★ **Chinneck, J. W. (2008):** *Feasibility and [Infeasibility](#gloss:infeasibility){.glossar-link} in Optimization: Algorithms and Computational Methods.* Springer, New York. DOI: 10.1007/978-0-387-74932-7 [Fehlerdiagnose] *Das Standardwerk zur Unlösbarkeitsdiagnose, einschließlich des Deletion Filters und der irreduziblen unlösbaren Teilmengen ([IIS (Irreducible Infeasible Subset)](#gloss:iis-irreducible-infeasible-subset){.glossar-link}). Direkte Grundlage von [Anhang C](#anhang-fehlerdiagnose).*
|
||||
* ★★ **Sculley, D., Holt, G., Golovin, D. et al. (2015):** *Hidden Technical Debt in Machine Learning Systems.* In: *Advances in Neural Information Processing Systems* 28, S. 2503–2511. [Betrieb] *Über Systeme, deren Modell nur ein kleiner Teil ist — überträgt sich unmittelbar auf den Betrieb von Optimierungsdiensten. Frei zugänglich.*
|
||||
* ★★ **Kleppmann, M. (2017):** *Designing Data-Intensive Applications.* O'Reilly, Sebastopol. [Betrieb] *[Snapshot-Prinzip](#gloss:snapshot-prinzip){.glossar-link}, [Zustandslosigkeit](#gloss:zustandslosigkeit){.glossar-link}, Versionierung und Reproduzierbarkeit — die Architekturfragen hinter der OR-Plattform in [Kapitel 22](#kap-praxisfallen).*
|
||||
* ★★ **Ramírez, S.:** *FastAPI Documentation.* [fastapi.tiangolo.com](https://fastapi.tiangolo.com) [Betrieb] *Die Grundlage des Optimierungsdienstes in [Kapitel 23](#kap-testing), einschließlich der Eingabevalidierung über `pydantic`.*
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -5,6 +5,11 @@ Jeder Eintrag nennt am Ende den Abschnitt, in dem der Begriff eingeführt wird
|
|||
dorthin führt in der Online-Fassung direkt zur Erklärung im Zusammenhang. Wer einen Begriff an
|
||||
*allen* Fundstellen sucht, benutzt das Stichwortverzeichnis.
|
||||
|
||||
```{=html}
|
||||
<nav class="register-sprungleiste"><a href="#a">A</a> <a href="#b">B</a> <a href="#c">C</a> <a href="#d">D</a> <a href="#e">E</a> <a href="#f">F</a> <a href="#g">G</a> <a href="#h">H</a> <a href="#i">I</a> <a href="#j">J</a> <a href="#k">K</a> <a href="#l">L</a> <a href="#m">M</a> <a href="#n">N</a> <a href="#o">O</a> <a href="#p">P</a> <a href="#q">Q</a> <a href="#r">R</a> <a href="#s">S</a> <a href="#t">T</a> <a href="#u">U</a> <a href="#v">V</a> <a href="#w">W</a> <a href="#y">Y</a> <a href="#z">Z</a></nav>
|
||||
```
|
||||
|
||||
|
||||
## A
|
||||
|
||||
::: {#gloss:absolutbetrag}
|
||||
|
|
|
|||
|
|
@ -157,4 +157,4 @@ Details zu den Lernpfaden stehen in [`00_Vorwort_und_Lesehilfe.md`](00_Vorwort_u
|
|||
|
||||
---
|
||||
|
||||
*Autor / Herausgeber: Dieter Schlüter · Stand: 10. September 2026 v17.38*
|
||||
*Autor / Herausgeber: Dieter Schlüter · Stand: 10. September 2026 v17.51*
|
||||
|
|
|
|||
|
|
@ -1114,7 +1114,7 @@ _GLOSSAR_GL_RE = re.compile(r'\{gl:([^}]+)\}')
|
|||
def resolve_glossar(text: str, fuer_seite: bool = False) -> str:
|
||||
"""Verlinkt Glossar-Begriffe im Fließtext automatisch (erste Nennung je
|
||||
Begriff im uebergebenen Text) und loest {gl:}-Marken auf."""
|
||||
from glossar_eintraege_04 import LINK_TEXTE
|
||||
from glossar_eintraege_04 import LINK_TEXTE, ABBREV_ERSTE_NENNUNG
|
||||
|
||||
# {gl:Begriff}-Marken zuerst: erzwingen einen Link auch fuer Begriffe,
|
||||
# die nicht auto-linkbar sind. 'Begriff' ist der Anzeigetext im Link;
|
||||
|
|
@ -1165,13 +1165,15 @@ def resolve_glossar(text: str, fuer_seite: bool = False) -> str:
|
|||
last = 0
|
||||
for m in _GLOSSAR_TOKEN_RE.finditer(line):
|
||||
seg = line[last:m.start()]
|
||||
seg, t = _glossar_in_segment(seg, texte, seen, fuer_seite)
|
||||
seg, t = _glossar_in_segment(seg, texte, seen, fuer_seite,
|
||||
ABBREV_ERSTE_NENNUNG)
|
||||
treffer += t
|
||||
new_parts.append(seg)
|
||||
new_parts.append(m.group(0)) # Token unverändert
|
||||
last = m.end()
|
||||
rest = line[last:]
|
||||
rest, t = _glossar_in_segment(rest, texte, seen, fuer_seite)
|
||||
rest, t = _glossar_in_segment(rest, texte, seen, fuer_seite,
|
||||
ABBREV_ERSTE_NENNUNG)
|
||||
treffer += t
|
||||
new_parts.append(rest)
|
||||
lines[i] = ''.join(new_parts)
|
||||
|
|
@ -1188,17 +1190,22 @@ def _glossar_slug_fuer(begriff: str) -> str:
|
|||
|
||||
|
||||
def _glossar_in_segment(segment: str, texte: list[tuple[str, str]],
|
||||
seen: set[str], fuer_seite: bool) -> tuple[str, int]:
|
||||
seen: set[str], fuer_seite: bool,
|
||||
abbrev_erste: dict[str, str] | None = None
|
||||
) -> tuple[str, int]:
|
||||
"""Sucht im Fließtext-Segment nach Glossar-Begriffen und ersetzt das
|
||||
erste Vorkommen je Begriff durch einen Link.
|
||||
|
||||
Bei Abkürzungen (abbrev_erste) wird die ERSTE Nennung ausgeschrieben:
|
||||
'VaR' -> 'VaR (Value at Risk)' als Link-Text. Danach nur noch 'VaR'.
|
||||
Alle Link-Texte werden im Original-Segment gesucht (mit finditer, also
|
||||
alle Vorkommen), dann nach Position sortiert und nicht-ueberlappend
|
||||
ersetzt — laengste zuerst bei gleicher Position. So wird 'CP-SAT' als
|
||||
Ganzes erkannt, bevor 'CP' (als Teilstring darin) ein eigenes Match
|
||||
erzeugt. Wird ein Match wegen Ueberlappung übersprungen, wird das
|
||||
naechste Vorkommen desselben Begriffs genommen (falls nicht ueberlappend).
|
||||
erzeugt.
|
||||
"""
|
||||
if abbrev_erste is None:
|
||||
abbrev_erste = {}
|
||||
matches: list[tuple[int, int, str, str]] = []
|
||||
for link_text, slug in texte:
|
||||
if link_text in seen:
|
||||
|
|
@ -1229,7 +1236,9 @@ def _glossar_in_segment(segment: str, texte: list[tuple[str, str]],
|
|||
result.append(segment[last_end:start])
|
||||
ziel = (f'anhang-glossar.md#gloss:{slug}' if fuer_seite
|
||||
else f'#gloss:{slug}')
|
||||
result.append(f'[{link_text}]({ziel}){{.glossar-link}}')
|
||||
# Erste Nennung einer Abkürzung: ausgeschrieben als Link-Text.
|
||||
anzeige = abbrev_erste.get(link_text, link_text)
|
||||
result.append(f'[{anzeige}]({ziel}){{.glossar-link}}')
|
||||
seen.add(link_text)
|
||||
treffer += 1
|
||||
last_end = end
|
||||
|
|
|
|||
|
|
@ -180,7 +180,16 @@ def baue() -> str:
|
|||
break_long_words=False,
|
||||
break_on_hyphens=False))
|
||||
|
||||
zeilen = [KOPFZEILE, "", absatz(EINLEITUNG), ""]
|
||||
# Sprungleiste A B C ... — wie im Stichwortverzeichnis: ein Klick je
|
||||
# Buchstabe springt zur Ueberschrift '## <Buchstabe>' (Pandoc erzeugt daraus
|
||||
# id="a", id="b", ...). Nur im HTML (roh-Block); im PDF meaningless.
|
||||
buchstaben = sorted({anfangsbuchstabe(n) for n, _, _, _ in EINTRAEGE})
|
||||
sprungleiste = ("```{=html}\n"
|
||||
'<nav class="register-sprungleiste">'
|
||||
+ " ".join(f'<a href="#{b.lower()}">{b}</a>' for b in buchstaben)
|
||||
+ "</nav>\n```\n")
|
||||
|
||||
zeilen = [KOPFZEILE, "", absatz(EINLEITUNG), "", sprungleiste, ""]
|
||||
letzter = None
|
||||
for name, idx, text, ziel in sorted(EINTRAEGE,
|
||||
key=lambda e: sortierschluessel(e[0])):
|
||||
|
|
|
|||
|
|
@ -1535,6 +1535,31 @@ _NICHT_AUTO_LINKEN = frozenset({
|
|||
_ZU_KURZ_ABK = frozenset({"OR"})
|
||||
|
||||
|
||||
# ABBREV_ERSTE_NENNUNG: Abkürzung -> Anzeige-Text für die erste Nennung.
|
||||
# 'VaR' -> 'VaR (Value at Risk)', 'EVPI' -> 'EVPI (Expected Value ...)'.
|
||||
# Wird beim ersten Vorkommen der Abkürzung im Fließtext als Link-Text
|
||||
# verwendet; danach nur noch die Abkürzung. Siehe resolve_glossar().
|
||||
ABBREV_ERSTE_NENNUNG: dict[str, str] = {}
|
||||
|
||||
|
||||
def _erste_nennung(name: str, abk: str) -> str:
|
||||
"""Baut die erste-Nennung-Anzeige aus dem Glossar-Namen.
|
||||
|
||||
'Value at Risk (VaR)' + 'VaR' -> 'VaR (Value at Risk)'
|
||||
'EVPI (Expected Value ...)' + 'EVPI' -> 'EVPI (Expected Value ...)' (=name)
|
||||
"""
|
||||
m = _re.search(r"\(([^)]+)\)\s*$", name)
|
||||
if not m:
|
||||
return name
|
||||
in_paren = m.group(1).strip()
|
||||
before = name[: m.start()].strip()
|
||||
# Fall 1: Abkürzung in der Klammer -> 'Abk (Voller Name)'.
|
||||
if in_paren == abk:
|
||||
return f"{abk} ({before})"
|
||||
# Fall 2: Abkürzung vor der Klammer -> Name ist schon 'Abk (Voller Name)'.
|
||||
return name
|
||||
|
||||
|
||||
LINK_TEXTE: dict[str, str] = {}
|
||||
for _name, _idx, _text, _ziel in EINTRAEGE:
|
||||
if _name in _NICHT_AUTO_LINKEN:
|
||||
|
|
@ -1546,3 +1571,5 @@ for _name, _idx, _text, _ziel in EINTRAEGE:
|
|||
_abk = _abkuerzung_aus_name(_name)
|
||||
if _abk and _abk not in _ZU_KURZ_ABK:
|
||||
LINK_TEXTE[_abk] = _slug
|
||||
# Erste Nennung: ausgeschrieben ('VaR (Value at Risk)').
|
||||
ABBREV_ERSTE_NENNUNG[_abk] = _erste_nennung(_name, _abk)
|
||||
|
|
|
|||
|
|
@ -2444,7 +2444,7 @@ z
|
|||
</g>
|
||||
</g>
|
||||
<g id="text_14">
|
||||
<!-- Stand: 10. September 2026 v17.38 -->
|
||||
<!-- Stand: 10. September 2026 v17.51 -->
|
||||
<g style="fill: #c7d2fe" transform="translate(71.4528 818.05749) scale(0.12 -0.12)">
|
||||
<defs>
|
||||
<path id="DejaVuSans-31" d="M 794 531
|
||||
|
|
@ -2546,75 +2546,29 @@ L 525 4134
|
|||
L 525 4666
|
||||
z
|
||||
" transform="scale(0.015625)"/>
|
||||
<path id="DejaVuSans-33" d="M 2597 2516
|
||||
Q 3050 2419 3304 2112
|
||||
Q 3559 1806 3559 1356
|
||||
Q 3559 666 3084 287
|
||||
Q 2609 -91 1734 -91
|
||||
Q 1441 -91 1130 -33
|
||||
Q 819 25 488 141
|
||||
L 488 750
|
||||
Q 750 597 1062 519
|
||||
Q 1375 441 1716 441
|
||||
Q 2309 441 2620 675
|
||||
Q 2931 909 2931 1356
|
||||
Q 2931 1769 2642 2001
|
||||
Q 2353 2234 1838 2234
|
||||
L 1294 2234
|
||||
L 1294 2753
|
||||
L 1863 2753
|
||||
Q 2328 2753 2575 2939
|
||||
Q 2822 3125 2822 3475
|
||||
Q 2822 3834 2567 4026
|
||||
Q 2313 4219 1838 4219
|
||||
Q 1578 4219 1281 4162
|
||||
Q 984 4106 628 3988
|
||||
L 628 4550
|
||||
Q 988 4650 1302 4700
|
||||
Q 1616 4750 1894 4750
|
||||
Q 2613 4750 3031 4423
|
||||
Q 3450 4097 3450 3541
|
||||
Q 3450 3153 3228 2886
|
||||
Q 3006 2619 2597 2516
|
||||
z
|
||||
" transform="scale(0.015625)"/>
|
||||
<path id="DejaVuSans-38" d="M 2034 2216
|
||||
Q 1584 2216 1326 1975
|
||||
Q 1069 1734 1069 1313
|
||||
Q 1069 891 1326 650
|
||||
Q 1584 409 2034 409
|
||||
Q 2484 409 2743 651
|
||||
Q 3003 894 3003 1313
|
||||
Q 3003 1734 2745 1975
|
||||
Q 2488 2216 2034 2216
|
||||
z
|
||||
M 1403 2484
|
||||
Q 997 2584 770 2862
|
||||
Q 544 3141 544 3541
|
||||
Q 544 4100 942 4425
|
||||
Q 1341 4750 2034 4750
|
||||
Q 2731 4750 3128 4425
|
||||
Q 3525 4100 3525 3541
|
||||
Q 3525 3141 3298 2862
|
||||
Q 3072 2584 2669 2484
|
||||
Q 3125 2378 3379 2068
|
||||
Q 3634 1759 3634 1313
|
||||
Q 3634 634 3220 271
|
||||
Q 2806 -91 2034 -91
|
||||
Q 1263 -91 848 271
|
||||
Q 434 634 434 1313
|
||||
Q 434 1759 690 2068
|
||||
Q 947 2378 1403 2484
|
||||
z
|
||||
M 1172 3481
|
||||
Q 1172 3119 1398 2916
|
||||
Q 1625 2713 2034 2713
|
||||
Q 2441 2713 2670 2916
|
||||
Q 2900 3119 2900 3481
|
||||
Q 2900 3844 2670 4047
|
||||
Q 2441 4250 2034 4250
|
||||
Q 1625 4250 1398 4047
|
||||
Q 1172 3844 1172 3481
|
||||
<path id="DejaVuSans-35" d="M 691 4666
|
||||
L 3169 4666
|
||||
L 3169 4134
|
||||
L 1269 4134
|
||||
L 1269 2991
|
||||
Q 1406 3038 1543 3061
|
||||
Q 1681 3084 1819 3084
|
||||
Q 2600 3084 3056 2656
|
||||
Q 3513 2228 3513 1497
|
||||
Q 3513 744 3044 326
|
||||
Q 2575 -91 1722 -91
|
||||
Q 1428 -91 1123 -41
|
||||
Q 819 9 494 109
|
||||
L 494 744
|
||||
Q 775 591 1075 516
|
||||
Q 1375 441 1709 441
|
||||
Q 2250 441 2565 725
|
||||
Q 2881 1009 2881 1497
|
||||
Q 2881 1984 2565 2268
|
||||
Q 2250 2553 1709 2553
|
||||
Q 1456 2553 1204 2497
|
||||
Q 953 2441 691 2322
|
||||
L 691 4666
|
||||
z
|
||||
" transform="scale(0.015625)"/>
|
||||
</defs>
|
||||
|
|
@ -2649,8 +2603,8 @@ z
|
|||
<use xlink:href="#DejaVuSans-31" transform="translate(1508.886719 0)"/>
|
||||
<use xlink:href="#DejaVuSans-37" transform="translate(1572.509766 0)"/>
|
||||
<use xlink:href="#DejaVuSans-2e" transform="translate(1636.132812 0)"/>
|
||||
<use xlink:href="#DejaVuSans-33" transform="translate(1667.919922 0)"/>
|
||||
<use xlink:href="#DejaVuSans-38" transform="translate(1731.542969 0)"/>
|
||||
<use xlink:href="#DejaVuSans-35" transform="translate(1667.919922 0)"/>
|
||||
<use xlink:href="#DejaVuSans-31" transform="translate(1731.542969 0)"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_15">
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 88 KiB |
Loading…
Reference in a new issue