diff --git a/CLAUDE.md b/CLAUDE.md
index d251e89..e5847d6 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -170,8 +170,10 @@ gehört wie die Arbeit, die sie beschreibt.
## Diagramme
-`bilder_04/erzeuge_*.py` erzeugen 18 der 32 Kapiteldiagramme, jeweils **aus derselben
-Instanz wie das zugehörige Buchprogramm**. (Das 33. SVG im Verzeichnis ist `titelseite.svg`,
+`bilder_04/erzeuge_*.py` erzeugen 29 der 42 Kapiteldiagramme, jeweils **aus derselben
+Instanz wie das zugehörige Buchprogramm**. Die elf neueren benutzen `bilder_04/stil_04.py`
+— Palette, `rcParams` und `speichere()` an einer Stelle statt elfmal; die älteren setzen
+`svg.hashsalt` und `metadata={"Date": None}` weiterhin selbst. (Das 33. SVG im Verzeichnis ist `titelseite.svg`,
die der Build bei jedem Lauf selbst schreibt — deshalb nennt `README.md` 33 und diese Datei
32.) Das ist kein Selbstzweck: Von zehn nachgebauten Bildern förderten
sieben einen Fehler zutage — dreimal ein Modell, das im Buch gar nicht vorkommt, einmal
diff --git a/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf b/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf
index e5a586d..5107196 100644
Binary files a/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf and b/OR_HTML_04/Operations_Research_mit_Python_Version_04.pdf differ
diff --git a/OR_HTML_04/assets/search-index.js b/OR_HTML_04/assets/search-index.js
index a3ef263..96a4559 100644
--- a/OR_HTML_04/assets/search-index.js
+++ b/OR_HTML_04/assets/search-index.js
@@ -1 +1 @@
-window.OR_SEARCH_INDEX = [{"seite":"vorwort.html","titel":"Vorwort & Lesehilfe","anker":null,"text":""},{"seite":"notation.html","titel":"Notation & Abkürzungen","anker":null,"text":""},{"seite":"notation.html","titel":"1. Die Symbole der Optimierung","anker":"die-symbole-der-optimierung","text":""},{"seite":"notation.html","titel":"1.1 Grundgrößen jedes Modells","anker":"grundgrößen-jedes-modells","text":""},{"seite":"notation.html","titel":"1.2 Mengen und Zahlbereiche","anker":"mengen-und-zahlbereiche","text":""},{"seite":"notation.html","titel":"1.3 Operatoren und Schreibweisen","anker":"operatoren-und-schreibweisen","text":""},{"seite":"notation.html","titel":"1.4 Symbole der Finanzkapitel (Teil IV)","anker":"symbole-der-finanzkapitel-teil-iv","text":""},{"seite":"notation.html","titel":"1.5 Symbole der Verfahrenskapitel (Teil II und III)","anker":"symbole-der-verfahrenskapitel-teil-ii-und-iii","text":"Diese Zeichen kommen erst in den Kapiteln vor, die über das klassische LP hinausgehen."},{"seite":"notation.html","titel":"2. Abkürzungen — vollständig ausgeschrieben","anker":"abkürzungen-vollständig-ausgeschrieben","text":""},{"seite":"notation.html","titel":"2.1 Problemklassen und Verfahren","anker":"problemklassen-und-verfahren","text":""},{"seite":"notation.html","titel":"2.2 Probleme mit Eigennamen","anker":"probleme-mit-eigennamen","text":""},{"seite":"notation.html","titel":"2.3 Finanz- und Risikokennzahlen","anker":"finanz--und-risikokennzahlen","text":""},{"seite":"notation.html","titel":"2.4 Software, Solver und Schnittstellen","anker":"software-solver-und-schnittstellen","text":""},{"seite":"notation.html","titel":"2.5 Begriffe aus dem Solver-Alltag","anker":"begriffe-aus-dem-solver-alltag","text":""},{"seite":"notation.html","titel":"3. Konventionen in diesem Buch","anker":"konventionen-in-diesem-buch","text":"Vektoren sind grundsätzlich Spaltenvektoren und werden fett gesetzt: \\mathbf{x}. Ein transponierter Vektor \\mathbf{x}^\\top ist eine Zeile. Skalare bleiben mager: n, Z."},{"seite":"einfuehrung.html","titel":"Kapitel 1: Einführung in Operations Research — Vom Ursprung zur mathematischen Entscheidungsfindung","anker":null,"text":""},{"seite":"einfuehrung.html","titel":"1.1 In 5 Minuten gelöst","anker":"sec:einfuehrung-schnellstart","text":"Bevor wir über Theorie sprechen, lösen Sie ein echtes Problem. Kopieren Sie den folgenden Block, führen Sie ihn aus, sehen Sie das Ergebnis — die Erklärung kommt danach."},{"seite":"einfuehrung.html","titel":"1.2 Lernziele","anker":"sec:einfuehrung-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"einfuehrung.html","titel":"1.3 Was ist Operations Research wirklich?","anker":"sec:einfuehrung-was-ist-operations-research-wirklich","text":"Im Alltag lösen wir Probleme intuitiv: durch Ausprobieren, Daumenregeln, Erfahrung. Das funktioniert erstaunlich gut — bis eine bestimmte Schwelle überschritten wird. Dann bricht d"},{"seite":"einfuehrung.html","titel":"Die drei Stufen der Analytik","anker":"die-drei-stufen-der-analytik","text":"OR beantwortet nicht die beschreibende Frage „Was ist passiert?“ und nicht die vorhersagende Frage „Was wird passieren?“, sondern die vorschreibende (präskriptive) Kernfrage:"},{"seite":"einfuehrung.html","titel":"1.4 Warum Ausprobieren scheitert — mit eigener Rechnung","anker":"sec:einfuehrung-warum-ausprobieren-scheitert-mit-eigener-rechnung","text":"Die Behauptung „vollständiges Durchprobieren ist unmöglich“ wird oft aufgestellt und selten belegt. Rechnen wir sie einmal selbst nach — das Ergebnis prägt sich besser ein als jede"},{"seite":"einfuehrung.html","titel":"1.5 Historischer Kontext und Evolution","anker":"sec:einfuehrung-historischer-kontext-und-evolution","text":"Der Begriff entstand im Vorfeld des Zweiten Weltkriegs in Großbritannien. Militärische Führungsstäbe standen vor neuartigen logistischen und strategischen Fragen: Wie platziert man"},{"seite":"einfuehrung.html","titel":"1.6 Die vier universellen Bausteine jedes OR-Problems","anker":"sec:einfuehrung-die-vier-universellen-bausteine-jedes-or","text":"Dies ist der wichtigste Abschnitt des Kapitels. Jedes Optimierungsproblem der Welt lässt sich — unabhängig von der Branche — auf vier Elemente reduzieren. Wenn Sie später vor einem"},{"seite":"einfuehrung.html","titel":"Baustein 1 — Entscheidungsvariablen (x)","anker":"baustein-1-entscheidungsvariablen-x","text":"Die Stellschrauben des Modells: Werte, die der Algorithmus aktiv festlegen darf."},{"seite":"einfuehrung.html","titel":"Baustein 2 — Parameter / Eingabedaten (c, A, b)","anker":"baustein-2-parameter-eingabedaten-c-a-b","text":"Die unveränderlichen Fakten der Realität: historische Renditen, Maschinenstundensätze, Lagerkapazitäten, Steuerquoten, Entfernungen, Qualifikationen."},{"seite":"einfuehrung.html","titel":"Baustein 3 — Zielfunktion (f(x))","anker":"baustein-3-zielfunktion-fx","text":"Ein mathematischer Ausdruck, der die Güte einer Lösung zu einer einzigen Zahl verdichtet:"},{"seite":"einfuehrung.html","titel":"Baustein 4 — Nebenbedingungen (Constraints)","anker":"baustein-4-nebenbedingungen-constraints","text":"Regeln, die den Raum der erlaubten Lösungen einschränken:"},{"seite":"einfuehrung.html","titel":"Die vier Bausteine als eine Formel","anker":"die-vier-bausteine-als-eine-formel","text":"Setzt man die vier Bausteine zusammen, entsteht die Standardform, in der Ihnen jedes Optimierungsmodell dieses Buches begegnen wird. Sie sieht auf den ersten Blick sperrig aus — de"},{"seite":"einfuehrung.html","titel":"Die Bausteine in der Praxis: eine Vorlage","anker":"die-bausteine-in-der-praxis-eine-vorlage","text":"Damit die Zerlegung zur Gewohnheit wird, hier eine Vorlage, die Sie bei jedem neuen Problem ausfüllen können — vor der ersten Codezeile."},{"seite":"einfuehrung.html","titel":"1.7 Erstes Python-Vollbeispiel: Ressourcenallokation im Rechenzentrum","anker":"sec:einfuehrung-erstes-python-vollbeispiel-ressourcenallokation-im-rechenzentrum","text":""},{"seite":"einfuehrung.html","titel":"Szenario","anker":"szenario","text":"Ein quantitatives Handelshaus betreibt Serverkapazitäten für zwei Algorithmentypen:"},{"seite":"einfuehrung.html","titel":"Mathematische Formulierung","anker":"mathematische-formulierung","text":"Entscheidungsvariablen:"},{"seite":"einfuehrung.html","titel":"Umsetzung mit Google OR-Tools","anker":"umsetzung-mit-google-or-tools","text":""},{"seite":"einfuehrung.html","titel":"1.8 Von Excel zu Python: Ihre Daten liegen schon da","anker":"sec:einfuehrung-excel-bruecke","text":"In den allermeisten Betrieben liegen die Zahlen, die ein Optimierungsmodell braucht, nicht in einer Datenbank, sondern in einer Tabellenkalkulation. Und viele Leserinnen und Leser "},{"seite":"einfuehrung.html","titel":"1.9 Übungsaufgaben","anker":"sec:einfuehrung-uebungsaufgaben","text":""},{"seite":"einfuehrung.html","titel":"1.10 Finde den Denkfehler","anker":"sec:einfuehrung-denkfehler","text":"Ein Programm, das abstürzt, ist harmlos — Sie sehen sofort, dass etwas nicht stimmt. Gefährlich sind Programme, die fehlerfrei durchlaufen, einen Status OPTIMAL melden und eine Zah"},{"seite":"einfuehrung.html","titel":"1.11 Micro-Quiz","anker":"sec:einfuehrung-quiz","text":""},{"seite":"einfuehrung.html","titel":"1.12 Selbsttest","anker":"sec:einfuehrung-selbsttest","text":""},{"seite":"einfuehrung.html","titel":"1.13 Zusammenfassung","anker":"sec:einfuehrung-zusammenfassung","text":""},{"seite":"fundament.html","titel":"Kapitel 2: Das mathematische Fundament — Vektoren, Matrizen, Konvexität","anker":null,"text":""},{"seite":"fundament.html","titel":"2.1 In 5 Minuten gelöst","anker":"sec:fundament-schnellstart","text":"Dieses Kapitel handelt von Geometrie. Bevor wir Vektoren und Matrizen einführen, sehen Sie die zentrale Einsicht in Aktion — ganz ohne Solver, mit acht Zeilen NumPy."},{"seite":"fundament.html","titel":"2.2 Lernziele","anker":"sec:fundament-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"fundament.html","titel":"2.3 Warum überhaupt Vektoren und Matrizen?","anker":"sec:fundament-warum-ueberhaupt-vektoren-und-matrizen","text":"In Kapitel 1 hatten wir zwei Variablen und drei Nebenbedingungen. Das ließ sich bequem ausschreiben. Reale Modelle haben hunderte bis hunderttausende Variablen — dort wäre Ausschre"},{"seite":"fundament.html","titel":"Die Bausteine","anker":"die-bausteine","text":"Sei n die Anzahl der Entscheidungsvariablen und m die Anzahl der Nebenbedingungen."},{"seite":"fundament.html","titel":"Die kanonische Standardform","anker":"die-kanonische-standardform","text":"Damit lässt sich jedes lineare Programm in drei Zeilen schreiben:"},{"seite":"fundament.html","titel":"Dasselbe in Python","anker":"dasselbe-in-python","text":""},{"seite":"fundament.html","titel":"2.4 Der zulässige Lösungsraum und das Polyeder","anker":"sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder","text":"Jede lineare Ungleichung a_{i1}x_1 + a_{i2}x_2 \\le b_i definiert geometrisch eine Halbebene (im \\mathbb{R}^2) bzw. einen Halbraum (im \\mathbb{R}^n): Die zugehörige Gleichung ist ei"},{"seite":"fundament.html","titel":"Der Fundamentalsatz der linearen Optimierung","anker":"der-fundamentalsatz-der-linearen-optimierung","text":""},{"seite":"fundament.html","titel":"2.5 Konvexität: die Grenze zwischen leicht und schwer","anker":"sec:fundament-konvexitaet-die-grenze-zwischen-leicht-und","text":"Hier kommt die vielleicht wichtigste Einsicht des ganzen Buches. In der Optimierungstheorie verläuft die Trennlinie zwischen „zuverlässig lösbar“ und „im Allgemeinen hoffnungslos“ "},{"seite":"fundament.html","titel":"Konvexe Menge","anker":"konvexe-menge","text":"Eine Menge \\mathcal{C} \\subseteq \\mathbb{R}^n heißt konvex, wenn für alle Punkte \\mathbf{x}, \\mathbf{y} \\in \\mathcal{C} und jedes \\theta \\in [0,1] gilt:"},{"seite":"fundament.html","titel":"Konvexe Funktion","anker":"konvexe-funktion","text":"Eine Funktion f: \\mathcal{C} \\to \\mathbb{R} heißt konvex, wenn für alle \\mathbf{x}, \\mathbf{y} \\in \\mathcal{C} und \\theta \\in [0,1] gilt:"},{"seite":"fundament.html","titel":"Der zentrale Satz","anker":"der-zentrale-satz","text":""},{"seite":"fundament.html","titel":"Was ist konvex, was nicht?","anker":"was-ist-konvex-was-nicht","text":""},{"seite":"fundament.html","titel":"Konvexität sichtbar machen","anker":"konvexität-sichtbar-machen","text":""},{"seite":"fundament.html","titel":"2.6 Geometrische Visualisierung des Lösungsraums","anker":"sec:fundament-geometrische-visualisierung-des-loesungsraums","text":"Wir zeichnen nun den Lösungsraum aus Kapitel 1 und lesen das Optimum ab. Zweidimensionale Bilder sind der schnellste Weg, Intuition für höhere Dimensionen aufzubauen — auch wenn ma"},{"seite":"fundament.html","titel":"2.7 Wenn die Zahlen nicht zusammenpassen: Kondition und Skalierung","anker":"sec:fundament-kondition","text":"Bis hierher war die lineare Algebra exakt. Ein Rechner rechnet aber nicht exakt, sondern mit rund 16 signifikanten Stellen — und Ihre Betriebsdaten sind ohnehin nur auf wenige Stel"},{"seite":"fundament.html","titel":"Die geometrische Vorstellung: zwei fast parallele Linien","anker":"die-geometrische-vorstellung-zwei-fast-parallele-linien","text":"Zwei Nebenbedingungen legen im Zweidimensionalen einen Schnittpunkt fest. Stehen die zugehörigen Geraden kreuzweise aufeinander, ist der Schnittpunkt robust: Verschiebt man eine Ge"},{"seite":"fundament.html","titel":"Woher schlechte Kondition im Alltag kommt","anker":"woher-schlechte-kondition-im-alltag-kommt","text":"Fast nie aus exotischer Mathematik — fast immer aus Einheiten:"},{"seite":"fundament.html","titel":"Ruiz-Equilibrierung: das Modell gesundrechnen","anker":"ruiz-equilibrierung-das-modell-gesundrechnen","text":"Die Gegenmaßnahme ist erstaunlich schlicht. Man multipliziert jede Zeile und jede Spalte der Matrix mit einem Faktor, sodass die Beträge überall in derselben Größenordnung landen:"},{"seite":"fundament.html","titel":"Das Experiment","anker":"das-experiment","text":"Das folgende Programm führt beides vor — die Fehlerverstärkung und ihre Behebung — und schließt mit der praktischen Konsequenz, die Sie in Kapitel 6 wieder brauchen werden: warum e"},{"seite":"fundament.html","titel":"2.8 Übungsaufgaben","anker":"sec:fundament-uebungsaufgaben","text":""},{"seite":"fundament.html","titel":"2.9 Finde den Denkfehler","anker":"sec:fundament-denkfehler","text":""},{"seite":"fundament.html","titel":"2.10 Micro-Quiz","anker":"sec:fundament-quiz","text":""},{"seite":"fundament.html","titel":"2.11 Selbsttest","anker":"sec:fundament-selbsttest","text":""},{"seite":"fundament.html","titel":"2.12 Zusammenfassung","anker":"sec:fundament-zusammenfassung","text":""},{"seite":"oekosystem.html","titel":"Kapitel 3: Das Python-Ökosystem für OR — Solver, Bindings und Modellierungsschichten","anker":null,"text":""},{"seite":"oekosystem.html","titel":"3.1 In 5 Minuten gelöst","anker":"sec:oekosystem-schnellstart","text":""},{"seite":"oekosystem.html","titel":"3.2 Lernziele","anker":"sec:oekosystem-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"oekosystem.html","titel":"3.3 Die Zwei-Schichten-Architektur","anker":"sec:oekosystem-die-zwei-schichten-architektur","text":"Im modernen Operations Research schreibt man Optimierungsalgorithmen nicht selbst. Man nutzt eine zweischichtige Architektur:"},{"seite":"oekosystem.html","titel":"3.4 Die Werkzeuge im Vergleich","anker":"sec:oekosystem-die-werkzeuge-im-vergleich","text":""},{"seite":"oekosystem.html","titel":"Die Entscheidung in drei Fragen","anker":"die-entscheidung-in-drei-fragen","text":"Statt die Tabelle auswendig zu lernen, beantworten Sie drei Fragen:"},{"seite":"oekosystem.html","titel":"3.5 Ein System — vier Programmieransätze","anker":"sec:oekosystem-ein-system-vier-programmieransaetze","text":"Nichts macht die Unterschiede so deutlich wie dasselbe Problem, viermal gelöst. Wir nehmen:"},{"seite":"oekosystem.html","titel":"Wie die Isolation aussieht, wenn sie tragen soll","anker":"wie-die-isolation-aussieht-wenn-sie-tragen-soll","text":"„Eigener Prozess” ist schnell gesagt. Die naheliegende Umsetzung — ein Codeschnipsel als Zeichenkette an python -c übergeben — funktioniert und ist trotzdem die schlechteste: Der S"},{"seite":"oekosystem.html","titel":"Was das CSR-Format bedeutet","anker":"was-das-csr-format-bedeutet","text":"highspy erwartet die Nebenbedingungsmatrix im CSR-Format (Compressed Sparse Row, komprimierte Zeilendarstellung). Statt der vollen Matrix speichert man nur die Einträge ungleich nu"},{"seite":"oekosystem.html","titel":"3.6 Wann lohnt sich welche Ebene?","anker":"sec:oekosystem-wann-lohnt-sich-welche-ebene","text":""},{"seite":"oekosystem.html","titel":"3.7 Modellierungsschichten für große Modelle: Pyomo und Linopy","anker":"sec:oekosystem-pyomo-linopy","text":"Die vier Bibliotheken aus dem Vierfach-Vergleich decken den Alltag weitgehend ab. Sobald Modelle industrielle Größe erreichen — zehntausende Variablen, Daten aus mehreren Systemen,"},{"seite":"oekosystem.html","titel":"Pyomo: die algebraische Denkweise","anker":"pyomo-die-algebraische-denkweise","text":"Pyomo ist im deutschsprachigen Raum der De-facto-Standard für große LP- und MILP-Modelle in Energiewirtschaft, Chemie und Logistik. Sein Kennzeichen: Es denkt in Mengen und Indizes"},{"seite":"oekosystem.html","titel":"Linopy: eine Zeile, zehntausend Nebenbedingungen","anker":"linopy-eine-zeile-zehntausend-nebenbedingungen","text":"Linopy verfolgt einen anderen Ansatz: Variablen sind beschriftete Arrays (xarray), keine indizierten Einzelobjekte. Damit wird aus"},{"seite":"oekosystem.html","titel":"Die Schichten im Überblick","anker":"die-schichten-im-überblick","text":""},{"seite":"oekosystem.html","titel":"3.8 Wo die Zeit wirklich hingeht: vektorisierte Modellgenerierung","anker":"sec:oekosystem-vektorisierung","text":"Eine der hartnäckigsten Fehlannahmen in Optimierungsprojekten lautet: „Wenn es zu langsam ist, brauchen wir einen besseren Solver.“ Messen Sie erst — oft stimmt das nicht."},{"seite":"oekosystem.html","titel":"Vier Stufen an einem Transportproblem","anker":"vier-stufen-an-einem-transportproblem","text":"Wir bauen dasselbe Transportproblem (m Werke, n Kunden, m \\cdot n Variablen) auf vier Arten auf:"},{"seite":"oekosystem.html","titel":"3.9 Übungsaufgaben","anker":"sec:oekosystem-uebungsaufgaben","text":""},{"seite":"oekosystem.html","titel":"3.10 Finde den Denkfehler","anker":"sec:oekosystem-denkfehler","text":""},{"seite":"oekosystem.html","titel":"3.11 Micro-Quiz","anker":"sec:oekosystem-quiz","text":""},{"seite":"oekosystem.html","titel":"3.12 Selbsttest","anker":"sec:oekosystem-selbsttest","text":""},{"seite":"oekosystem.html","titel":"3.13 Zusammenfassung","anker":"sec:oekosystem-zusammenfassung","text":""},{"seite":"modellierung.html","titel":"Kapitel 4: Vom Management-Wunsch zum Modell","anker":null,"text":""},{"seite":"modellierung.html","titel":"4.1 In 5 Minuten gelöst","anker":"sec:modellierung-schnellstart","text":""},{"seite":"modellierung.html","titel":"4.2 Lernziele","anker":"sec:modellierung-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"modellierung.html","titel":"4.3 Ein Satz ist noch kein Modell","anker":"sec:modellierung-vier-fragen","text":"Was aus einer Besprechung mitkommt, klingt meist so:"},{"seite":"modellierung.html","titel":"4.4 Derselbe Datensatz, fünf Modelle","anker":"sec:modellierung-fuenf-modelle","text":"Das Programm dieses Kapitels arbeitet die vier Fragen an einer Auftragsannahme ab: 14 Anfragen verlangen 800 Maschinenstunden, verfügbar sind 300."},{"seite":"modellierung.html","titel":"Teil 1: Drei Ziele, drei Pläne","anker":"teil-1-drei-ziele-drei-pläne","text":""},{"seite":"modellierung.html","titel":"Teil 2: Ein Satz, drei Lesarten","anker":"teil-2-ein-satz-drei-lesarten","text":"„Stammkunden dürfen wir nicht verlieren.” Jeder im Raum nickt. Niemand merkt, dass drei verschiedene Modelle gemeint sein können:"},{"seite":"modellierung.html","titel":"Teil 3: Hart oder weich","anker":"teil-3-hart-oder-weich","text":"Dieselbe Regel als Strafkosten je abgelehntem Stammkundenauftrag:"},{"seite":"modellierung.html","titel":"Teil 4: Ein Quartal später","anker":"teil-4-ein-quartal-später","text":"Die harte Lesart A wurde eingebaut, alles lief drei Monate lang. Dann fragt Weber einen Auftrag über 320 Maschinenstunden an — mehr, als der ganze Zeitraum hergibt."},{"seite":"modellierung.html","titel":"4.5 Der Gesprächsleitfaden","anker":"sec:modellierung-leitfaden","text":"Was aus den vier Teilen als Handwerkszeug bleibt — Fragen, die man in der ersten Besprechung stellt, bevor eine Zeile Code entsteht:"},{"seite":"modellierung.html","titel":"4.6 Deutsch — OR: ein Übersetzungslexikon","anker":"sec:modellierung-glossar","text":"Die zwölf Fragen liefern Sätze. Sätze sind noch kein Modell — aber die meisten von ihnen haben eine Standardübersetzung, und wer sie kennt, spart sich das Nachdenken für die Fälle,"},{"seite":"modellierung.html","titel":"Fünf Wendungen, bei denen die Übersetzung eine Entscheidung erzwingt","anker":"fünf-wendungen-bei-denen-die-übersetzung-eine-entscheidung-erzwingt","text":"Die Tabelle oben tut so, als sei die Zuordnung eindeutig. Bei den folgenden fünf ist sie es nicht — und das Nachfragen ist die eigentliche Modellierungsarbeit:"},{"seite":"modellierung.html","titel":"Und die Gegenrichtung: OR — Deutsch","anker":"und-die-gegenrichtung-or-deutsch","text":"Dieselbe Barriere gibt es rückwärts. Diese Sätze haben sich bewährt, wenn ein Ergebnis jemandem erklärt werden muss, der das Modell nicht kennt:"},{"seite":"modellierung.html","titel":"4.7 Übungsaufgaben","anker":"sec:modellierung-uebungsaufgaben","text":""},{"seite":"modellierung.html","titel":"4.8 Finde den Denkfehler","anker":"sec:modellierung-denkfehler","text":""},{"seite":"modellierung.html","titel":"4.9 Micro-Quiz","anker":"sec:modellierung-quiz","text":""},{"seite":"modellierung.html","titel":"4.10 Selbsttest","anker":"sec:modellierung-selbsttest","text":""},{"seite":"modellierung.html","titel":"4.11 Zusammenfassung","anker":"sec:modellierung-zusammenfassung","text":""},{"seite":"synthese-grundlagen.html","titel":"Synthese Teil I","anker":null,"text":""},{"seite":"synthese-grundlagen.html","titel":"Was welches Kapitel klärt","anker":"was-welches-kapitel-klärt","text":""},{"seite":"synthese-grundlagen.html","titel":"Die Reihenfolge ist die Aussage","anker":"die-reihenfolge-ist-die-aussage","text":"Dieser Teil steht bewusst vor den Verfahren. Die drei häufigsten Gründe, aus denen ein OR-Projekt scheitert, liegen alle hier — und keiner davon ist ein Solverproblem:"},{"seite":"synthese-grundlagen.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"lp.html","titel":"Kapitel 5: Lineare Programmierung — Simplex, Dualität und Schattenpreise","anker":null,"text":""},{"seite":"lp.html","titel":"5.1 In 5 Minuten gelöst","anker":"sec:lp-schnellstart","text":"Bisher hat ein Solver Ihnen gesagt, was Sie tun sollen. Jetzt sagt er Ihnen zusätzlich, was eine zusätzliche Stunde wert wäre — und das ist die Zahl, für die Sie im Betrieb gehört "},{"seite":"lp.html","titel":"5.2 Lernziele","anker":"sec:lp-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"lp.html","titel":"5.3 Die Standardform und Schlupfvariablen","anker":"sec:lp-die-standardform-und-schlupfvariablen","text":"Lineare Programme zeichnen sich dadurch aus, dass Zielfunktion und alle Nebenbedingungen strikt linear sind — keine Produkte von Variablen, keine Quadrate, keine Logarithmen."},{"seite":"lp.html","titel":"5.4 Der Simplex-Algorithmus Schritt für Schritt","anker":"sec:lp-der-simplex-algorithmus-schritt-fuer-schritt","text":"Der von George Dantzig 1947 formulierte Simplex-Algorithmus nutzt den Fundamentalsatz aus Kapitel 2: Das Optimum liegt in einer Ecke. Statt alle Ecken aufzuzählen, wandert er von E"},{"seite":"lp.html","titel":"Der Ablauf","anker":"der-ablauf","text":""},{"seite":"lp.html","titel":"5.5 Das Simplex-Tableau in Python","anker":"sec:lp-das-simplex-tableau-in-python","text":""},{"seite":"lp.html","titel":"5.6 Dualität und Schattenpreise","anker":"sec:lp-dualitaet-und-schattenpreise","text":"Zu jedem linearen Optimierungsproblem (dem primalen Problem) existiert ein spiegelbildliches Zwillingsproblem: das duale Problem."},{"seite":"lp.html","titel":"Der starke Dualitätssatz","anker":"der-starke-dualitätssatz","text":""},{"seite":"lp.html","titel":"Der Schattenpreis als Ableitung","anker":"der-schattenpreis-als-ableitung","text":"Der Dualwert y_i^* ist die Grenzproduktivität der Ressource i:"},{"seite":"lp.html","titel":"5.7 Die Vorzeichenfalle bei Schattenpreisen","anker":"sec:lp-die-vorzeichenfalle-bei-schattenpreisen","text":"Diese Falle sollten Sie sich merken, weil sie in jedem Projekt wieder auftaucht."},{"seite":"lp.html","titel":"5.8 Praxisfall: Sensitivitätsanalyse mit korrekten Schattenpreisen","anker":"sec:lp-praxisfall-sensitivitaetsanalyse-mit-korrekten-schattenpreisen","text":"Szenario. Ein Fertigungsbetrieb stellt drei Produkte her und will wissen:"},{"seite":"lp.html","titel":"5.9 Wann Schattenpreise lügen: Entartung und Toleranzen","anker":"sec:lp-entartung","text":"Der vorige Abschnitt hat gezeigt, wie wertvoll Schattenpreise sind. Dieser zeigt die zwei Fälle, in denen sie eine Entscheidung nicht tragen — und wie man beide erkennt, bevor jema"},{"seite":"lp.html","titel":"Fall 1: Entartung","anker":"fall-1-entartung","text":"Erinnern Sie sich an Abschnitt 2.4: In zwei Dimensionen legen zwei sich schneidende Geraden eine Ecke fest, in drei Dimensionen drei Ebenen, allgemein n Restriktionen bei n Variabl"},{"seite":"lp.html","titel":"Fall 2: Toleranzen","anker":"fall-2-toleranzen","text":"Der zweite Fall ist unscheinbarer und deshalb häufiger. Wie stellt man fest, ob eine Ressource ausgelastet ist? Naheliegend wäre if schlupf == 0. Genau das ist falsch."},{"seite":"lp.html","titel":"Die ehrliche Auskunft: Schattenpreis-Spannen","anker":"die-ehrliche-auskunft-schattenpreis-spannen","text":"Was tut man also, wenn das Modell entartet ist? Man meldet keinen Einzelwert, sondern die Spanne. Die Menge aller optimalen Dualvektoren ist selbst ein Polyeder:"},{"seite":"lp.html","titel":"5.10 Übungsaufgaben","anker":"sec:lp-uebungsaufgaben","text":""},{"seite":"lp.html","titel":"5.11 Finde den Denkfehler","anker":"sec:lp-denkfehler","text":""},{"seite":"lp.html","titel":"5.12 Micro-Quiz","anker":"sec:lp-quiz","text":""},{"seite":"lp.html","titel":"5.13 Selbsttest","anker":"sec:lp-selbsttest","text":""},{"seite":"lp.html","titel":"5.14 Zusammenfassung","anker":"sec:lp-zusammenfassung","text":""},{"seite":"milp.html","titel":"Kapitel 6: Gemischt-ganzzahlige Optimierung — Diskrete Entscheidungen und Branch-and-Bound","anker":null,"text":""},{"seite":"milp.html","titel":"6.1 In 5 Minuten gelöst","anker":"sec:milp-schnellstart","text":""},{"seite":"milp.html","titel":"6.2 Lernziele","anker":"sec:milp-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"milp.html","titel":"6.3 Warum Runden fundamental scheitert","anker":"sec:milp-warum-runden-fundamental-scheitert","text":"In der realen Welt sind viele Entscheidungen nicht teilbar. Man kann nicht 0,47 Flugzeuge kaufen, keine halbe Lagerhalle bauen, keinen Mitarbeiter zu 38 % einstellen. Noch wichtige"},{"seite":"milp.html","titel":"6.4 Branch-and-Bound","anker":"sec:milp-branch-and-bound","text":"MILP-Probleme sind NP-schwer. Der Standardansatz moderner Solver (HiGHS, SCIP, Gurobi) heißt Branch-and-Cut — Branch-and-Bound plus Schnittebenen."},{"seite":"milp.html","titel":"Die drei Phasen","anker":"die-drei-phasen","text":""},{"seite":"milp.html","titel":"6.5 Modellierungstricks: Big-M und logische Bedingungen","anker":"sec:milp-modellierungstricks-big-m-und-logische-bedingungen","text":"Hier kommt das Handwerkszeug, das MILP so mächtig macht: Man übersetzt Geschäftsregeln in lineare Ungleichungen — mithilfe binärer Hilfsvariablen y \\in \\{0,1\\} und einer hinreichen"},{"seite":"milp.html","titel":"Muster 1 — Fixkosten / Aktivierungsschalter","anker":"muster-1-fixkosten-aktivierungsschalter","text":"Regel: Wird Maschine j genutzt (x_j > 0), fallen Rüstkosten F_j an."},{"seite":"milp.html","titel":"Muster 2 — Entweder-Oder (disjunctive constraints)","anker":"muster-2-entweder-oder-disjunctive-constraints","text":"Regel: Es muss entweder f(\\mathbf{x}) \\le b_1 oder g(\\mathbf{x}) \\le b_2 gelten."},{"seite":"milp.html","titel":"Muster 3 — Wenn-Dann (Implikation)","anker":"muster-3-wenn-dann-implikation","text":"Regel: Wenn y_1 = 1, dann muss auch y_2 = 1 sein."},{"seite":"milp.html","titel":"Muster 4 — Kardinalität („höchstens K aus N“)","anker":"muster-4-kardinalität-höchstens-k-aus-n","text":"\\sum_{j=1}^N y_j \\le K"},{"seite":"milp.html","titel":"Muster 5 — Semikontinuierlich („entweder 0 oder mindestens L“)","anker":"muster-5-semikontinuierlich-entweder-0-oder-mindestens-l","text":"Regel: Eine Position ist entweder gar nicht besetzt oder mit mindestens L Euro."},{"seite":"milp.html","titel":"6.6 Beispiel: Das Rucksackproblem","anker":"sec:milp-beispiel-das-rucksackproblem","text":"Bevor wir zum Portfolio kommen, das klassische Einstiegsproblem — kurz, verständlich und überall wiederzuerkennen."},{"seite":"milp.html","titel":"6.7 Praxisfall: Portfolio mit Ordergebühren und Kardinalitätsgrenze","anker":"sec:milp-praxisfall-portfolio-mit-ordergebuehren-und-kardinalitaetsgrenze","text":"Szenario. Ein Investor verteilt 100\\,000\\,\\text{€} auf sechs Anlageklassen."},{"seite":"milp.html","titel":"6.8 Wenn der Solver nicht fertig wird: Gap, Zeitlimit und Warm-Start","anker":"sec:milp-gap","text":"Bei einem LP gibt es zwei Ausgänge: eine optimale Lösung oder eine klare Absage. Bei einem MILP gibt es einen dritten, und im Betrieb ist er der häufigste:"},{"seite":"milp.html","titel":"Die zwei Zahlen, die zählen","anker":"die-zwei-zahlen-die-zählen","text":"Branch-and-Bound führt zu jedem Zeitpunkt zwei Werte mit:"},{"seite":"milp.html","titel":"Alle Statusfälle behandeln","anker":"alle-statusfälle-behandeln","text":"Der zweite Teil der Professionalität ist unspektakulär, aber entscheidend: jeden Rückgabewert auswerten, nicht nur OPTIMAL."},{"seite":"milp.html","titel":"Warm-Starts: was sie können und was nicht","anker":"warm-starts-was-sie-können-und-was-nicht","text":"Ein Warm-Start gibt dem Solver eine bekannte Lösung als Startpunkt mit. Die Idee ist verlockend: Wer schon eine brauchbare Lösung hat, muss nicht bei null anfangen."},{"seite":"milp.html","titel":"6.9 Übungsaufgaben","anker":"sec:milp-uebungsaufgaben","text":""},{"seite":"milp.html","titel":"6.10 Finde den Denkfehler","anker":"sec:milp-denkfehler","text":"Die Warnung „M so klein wie möglich“ wird meist mit der Laufzeit begründet: schwache Relaxation, mehr Knoten. Das stimmt — und ist die harmlosere Hälfte der Wahrheit."},{"seite":"milp.html","titel":"6.11 Micro-Quiz","anker":"sec:milp-quiz","text":""},{"seite":"milp.html","titel":"6.12 Selbsttest","anker":"sec:milp-selbsttest","text":""},{"seite":"milp.html","titel":"6.13 Zusammenfassung","anker":"sec:milp-zusammenfassung","text":""},{"seite":"cpsat.html","titel":"Kapitel 7: Constraint Programming mit CP-SAT — Logik, Scheduling und Zuweisung","anker":null,"text":""},{"seite":"cpsat.html","titel":"7.1 In 5 Minuten gelöst","anker":"sec:cpsat-schnellstart","text":""},{"seite":"cpsat.html","titel":"7.2 Lernziele","anker":"sec:cpsat-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"cpsat.html","titel":"7.3 Ein anderes Denkmodell","anker":"sec:cpsat-ein-anderes-denkmodell","text":"Während LP und MILP auf algebraischen Gleichungen und Simplex-Matrizen beruhen, kommt Constraint Programming (CP) aus der künstlichen Intelligenz:"},{"seite":"cpsat.html","titel":"Was Propagation leistet","anker":"was-propagation-leistet","text":""},{"seite":"cpsat.html","titel":"7.4 Globale Constraints — die Bausteine von CP-SAT","anker":"sec:cpsat-globale-constraints-die-bausteine-von-cp","text":"CP-SAT stellt mächtige Makros bereit, die in MILP hunderte Big-M-Ungleichungen erfordern würden. Jedes davon hat einen spezialisierten, hocheffizienten Propagator."},{"seite":"cpsat.html","titel":"7.5 Praxisfall: Dynamisches Vertretungssystem","anker":"sec:cpsat-praxisfall-dynamisches-vertretungssystem","text":"Problemstellung. Eine Schule muss nach spontanen Ausfällen vier Unterrichtsstunden nachbesetzen."},{"seite":"cpsat.html","titel":"7.6 Intervallvariablen: Job-Shop-Scheduling","anker":"sec:cpsat-intervallvariablen-job-shop-scheduling","text":"Die Königsdisziplin von CP-SAT sind Zeitplanungsprobleme. Intervallvariablen sind dabei das zentrale Werkzeug."},{"seite":"cpsat.html","titel":"7.7 Parallele Suche: was num_workers wirklich bewirkt","anker":"sec:cpsat-parallele-suche","text":"An mehreren Stellen dieses Buchs steht loeser.parameters.num_workers = 1, mit dem Kommentar „für eine reproduzierbare Ausgabe“. Darin stecken zwei Behauptungen: dass parallele Such"},{"seite":"cpsat.html","titel":"Was die Messung zeigt","anker":"was-die-messung-zeigt","text":"Erstens: Die Beschleunigung ist überlinear. Acht Arbeiter sind im abgedruckten Lauf nicht achtmal, sondern gut zwölfmal schneller als einer. Das sieht nach Messfehler aus, ist aber"},{"seite":"cpsat.html","titel":"Was daraus für Tests folgt","anker":"was-daraus-für-tests-folgt","text":"Der Zielwert war in allen sechzehn Läufen derselbe: 183. Die Gestalt der Lösung war es nicht. Genau daran entscheidet sich, was ein Test prüfen darf:"},{"seite":"cpsat.html","titel":"7.8 Die fünf Antworten von CP-SAT","anker":"sec:cpsat-statusfaelle","text":"Abschnitt 6.8 hat gezeigt, warum OPTIMAL bei ganzzahligen Problemen nicht der Normalfall ist. Bei CP-SAT kommt eine Besonderheit hinzu: Es gibt fünf verschiedene Antworten, und dre"},{"seite":"cpsat.html","titel":"7.9 Übungsaufgaben","anker":"sec:cpsat-uebungsaufgaben","text":""},{"seite":"cpsat.html","titel":"7.10 Finde den Denkfehler","anker":"sec:cpsat-denkfehler","text":""},{"seite":"cpsat.html","titel":"7.11 Micro-Quiz","anker":"sec:cpsat-quiz","text":""},{"seite":"cpsat.html","titel":"7.12 Selbsttest","anker":"sec:cpsat-selbsttest","text":""},{"seite":"cpsat.html","titel":"7.13 Zusammenfassung","anker":"sec:cpsat-zusammenfassung","text":""},{"seite":"graphen.html","titel":"Kapitel 8: Graphen, Flüsse und Touren — Min-Cost-Flow, Matching und VRP","anker":null,"text":""},{"seite":"graphen.html","titel":"8.1 In 5 Minuten gelöst","anker":"sec:graphen-schnellstart","text":""},{"seite":"graphen.html","titel":"8.2 Lernziele","anker":"sec:graphen-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"graphen.html","titel":"8.3 Graphen als Modellsprache","anker":"sec:graphen-graphen-als-modellsprache","text":"Viele reale Probleme in Logistik, Kommunikation und Finanzströmen sind keine flachen Ungleichungssysteme, sondern Graphen G = (V, E):"},{"seite":"graphen.html","titel":"Das Minimum-Cost-Flow-Problem (MCNFP)","anker":"das-minimum-cost-flow-problem-mcnfp","text":"Minimum-Cost Network Flow Problem — deutsch: kostenminimales Flussproblem. Es ist das mathematische Fundament für Transportketten, Liquiditätsrouting und Datenverteilung."},{"seite":"graphen.html","titel":"8.4 Bipartites Matching: das Zuordnungsproblem","anker":"sec:graphen-bipartites-matching-das-zuordnungsproblem","text":"Wenn N Aufgaben auf N Ressourcen eins zu eins verteilt werden — Orders auf Broker, Schichten auf Mitarbeitende, Aufträge auf Maschinen — spricht man von bipartitem Matching."},{"seite":"graphen.html","titel":"Der Satz von Birkhoff und von Neumann","anker":"der-satz-von-birkhoff-und-von-neumann","text":""},{"seite":"graphen.html","titel":"8.5 Das Vehicle Routing Problem mit Zeitfenstern","anker":"sec:graphen-das-vehicle-routing-problem-mit-zeitfenstern","text":"Das Traveling Salesperson Problem (TSP), deutsch Problem des Handlungsreisenden, fragt nach der kürzesten Rundreise durch N Städte. Das Capacitated Vehicle Routing Problem with Tim"},{"seite":"graphen.html","titel":"Kurzzyklen verhindern","anker":"kurzzyklen-verhindern","text":"Ein naives Modell erlaubt Subtouren: isolierte Kreise, die das Depot nie anfahren. Die klassische Gegenmaßnahme ist die MTZ-Formulierung nach Miller, Tucker und Zemlin. Man führt R"},{"seite":"graphen.html","titel":"Praxisbeispiel: Flotten-Routing","anker":"praxisbeispiel-flotten-routing","text":""},{"seite":"graphen.html","titel":"8.6 Übungsaufgaben","anker":"sec:graphen-uebungsaufgaben","text":""},{"seite":"graphen.html","titel":"8.7 Finde den Denkfehler","anker":"sec:graphen-denkfehler","text":""},{"seite":"graphen.html","titel":"8.8 Micro-Quiz","anker":"sec:graphen-quiz","text":""},{"seite":"graphen.html","titel":"8.9 Selbsttest","anker":"sec:graphen-selbsttest","text":""},{"seite":"graphen.html","titel":"8.10 Zusammenfassung","anker":"sec:graphen-zusammenfassung","text":""},{"seite":"metaheuristiken.html","titel":"Kapitel 9: Metaheuristiken — wenn der exakte Solver aussteigt","anker":null,"text":""},{"seite":"metaheuristiken.html","titel":"9.1 In 5 Minuten gelöst","anker":"sec:metaheuristiken-schnellstart","text":""},{"seite":"metaheuristiken.html","titel":"9.2 Lernziele","anker":"sec:metaheuristiken-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"metaheuristiken.html","titel":"9.3 Die Aufgabe: Rüstzeiten an der Lackieranlage","anker":"sec:metaheuristiken-aufgabe","text":"Der Schnellstart war ein Spielzeug. Die Aufgabe dieses Kapitels ist dieselbe, nur in Betriebsgröße: n Aufträge in eine Reihenfolge bringen, so dass die Summe der Rüstzeiten minimal"},{"seite":"metaheuristiken.html","titel":"Die Instanz","anker":"die-instanz","text":"Alle Programme dieses Kapitels benutzen dieselbe Aufgabe. Die Rüstzeit setzt sich aus zwei Teilen zusammen: einem unregelmäßigen Reinigungsaufwand zwischen den Produktfamilien und "},{"seite":"metaheuristiken.html","titel":"9.4 Lokale Suche: der Zug und seine Kosten","anker":"sec:metaheuristiken-lokale-suche","text":"Eine lokale Suche braucht drei Dinge: eine Startlösung, einen Zug und eine Regel, welche Züge übernommen werden."},{"seite":"metaheuristiken.html","titel":"9.5 Simulated Annealing","anker":"sec:metaheuristiken-annealing","text":"Reines Bergsteigen — nur Verbesserungen annehmen — bleibt im ersten lokalen Optimum stehen. Simulated Annealing nimmt Verschlechterungen mit einer Wahrscheinlichkeit an, die von de"},{"seite":"metaheuristiken.html","titel":"Was die Messung zeigt — und was sie nicht zeigt","anker":"was-die-messung-zeigt-und-was-sie-nicht-zeigt","text":"Erstens: Der Beitrag des Annealings ist bescheiden. Bergsteigen kommt auf 917 Minuten, Annealing auf 907 — das simple Verfahren holt 93 % des Ertrags. Das ist kein Argument gegen A"},{"seite":"metaheuristiken.html","titel":"9.6 Ab wann lohnt es sich?","anker":"sec:metaheuristiken-umschlagpunkt","text":"„Kleine Probleme exakt, große mit Metaheuristiken“ ist richtig und nutzlos, solange niemand sagt, wo groß anfängt. Diese Zahl lässt sich messen."},{"seite":"metaheuristiken.html","titel":"Die Spalte, die man nicht weglassen darf","anker":"die-spalte-die-man-nicht-weglassen-darf","text":"Bei 500 Aufträgen haben wir die CP-SAT-Lösung verworfen. Seine Schranke ist trotzdem das Wertvollste in der ganzen Tabelle."},{"seite":"metaheuristiken.html","titel":"9.7 Large Neighborhood Search","anker":"sec:metaheuristiken-lns","text":"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 j"},{"seite":"metaheuristiken.html","titel":"Das Fenster ist die eine Stellschraube","anker":"das-fenster-ist-die-eine-stellschraube","text":""},{"seite":"metaheuristiken.html","titel":"Das Gesamtbild","anker":"das-gesamtbild","text":""},{"seite":"metaheuristiken.html","titel":"9.8 Was dieses Kapitel nicht behandelt","anker":"sec:metaheuristiken-abgrenzung","text":"Damit die Landkarte vollständig ist — drei Verfahren, die in dieselbe Familie gehören und hier bewusst nur benannt werden:"},{"seite":"metaheuristiken.html","titel":"9.9 Übungsaufgaben","anker":"sec:metaheuristiken-uebungsaufgaben","text":""},{"seite":"metaheuristiken.html","titel":"9.10 Finde den Denkfehler","anker":"sec:metaheuristiken-denkfehler","text":""},{"seite":"metaheuristiken.html","titel":"9.11 Micro-Quiz","anker":"sec:metaheuristiken-quiz","text":""},{"seite":"metaheuristiken.html","titel":"9.12 Selbsttest","anker":"sec:metaheuristiken-selbsttest","text":""},{"seite":"metaheuristiken.html","titel":"9.13 Zusammenfassung","anker":"sec:metaheuristiken-zusammenfassung","text":""},{"seite":"dekomposition.html","titel":"Kapitel 10: Spaltengenerierung — das Modell umbauen statt die Lösung raten","anker":null,"text":""},{"seite":"dekomposition.html","titel":"10.1 In 5 Minuten gelöst","anker":"sec:dekomposition-schnellstart","text":""},{"seite":"dekomposition.html","titel":"10.2 Lernziele","anker":"sec:dekomposition-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"dekomposition.html","titel":"10.3 Warum das naheliegende Modell scheitert","anker":"sec:dekomposition-symmetrie","text":"Der erste Entwurf eines Zuschnittmodells sieht fast immer so aus: eine Binärvariable z_{jr} für „Stück j liegt auf Rolle r“, dazu y_r für „Rolle r wird benutzt”."},{"seite":"dekomposition.html","titel":"10.4 Rechnen mit Mustern, ohne sie aufzuschreiben","anker":"sec:dekomposition-schleife","text":"Die Idee ist alt (Gilmore und Gomory, 1961) und in einem Satz gesagt:"},{"seite":"dekomposition.html","titel":"10.5 Das Programm","anker":"sec:dekomposition-programm","text":""},{"seite":"dekomposition.html","titel":"10.6 Was die Zahlen zeigen","anker":"sec:dekomposition-befund","text":""},{"seite":"dekomposition.html","titel":"Die Musterzahl explodiert, der Bedarf nicht","anker":"die-musterzahl-explodiert-der-bedarf-nicht","text":""},{"seite":"dekomposition.html","titel":"Der unbequeme Teil: Es lohnt sich nicht immer","anker":"der-unbequeme-teil-es-lohnt-sich-nicht-immer","text":""},{"seite":"dekomposition.html","titel":"10.7 Übungsaufgaben","anker":"sec:dekomposition-uebungsaufgaben","text":""},{"seite":"dekomposition.html","titel":"10.8 Finde den Denkfehler","anker":"sec:dekomposition-denkfehler","text":""},{"seite":"dekomposition.html","titel":"10.9 Micro-Quiz","anker":"sec:dekomposition-quiz","text":""},{"seite":"dekomposition.html","titel":"10.10 Selbsttest","anker":"sec:dekomposition-selbsttest","text":""},{"seite":"dekomposition.html","titel":"10.11 Zusammenfassung","anker":"sec:dekomposition-zusammenfassung","text":""},{"seite":"synthese-kernverfahren.html","titel":"Synthese Teil II","anker":null,"text":""},{"seite":"synthese-kernverfahren.html","titel":"Die Entscheidungsmatrix","anker":"die-entscheidungsmatrix","text":""},{"seite":"synthese-kernverfahren.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-kernverfahren.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-kernverfahren.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"qp-nlp.html","titel":"Kapitel 11: Quadratische und nichtlineare Optimierung — KKT, Lagrange, Konvexität","anker":null,"text":""},{"seite":"qp-nlp.html","titel":"11.1 In 5 Minuten gelöst","anker":"sec:qp-nlp-schnellstart","text":""},{"seite":"qp-nlp.html","titel":"11.2 Lernziele","anker":"sec:qp-nlp-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"qp-nlp.html","titel":"Auffrischung: Gradient in einer Minute","anker":"auffrischung-gradient-in-einer-minute","text":"Der Gradient \\nabla f(\\mathbf{x}) ist der Vektor aller partiellen Ableitungen:"},{"seite":"qp-nlp.html","titel":"11.3 Das quadratische Programm (QP)","anker":"sec:qp-nlp-das-quadratische-programm-qp","text":"Ein quadratisches Programm hat eine quadratische Zielfunktion und lineare Nebenbedingungen:"},{"seite":"qp-nlp.html","titel":"Konvexität: die präzise Aussage","anker":"konvexität-die-präzise-aussage","text":"Eine verbreitete, aber zu stark formulierte Aussage lautet: „Wenn \\mathbf{P} positiv semi-definit ist, ist das QP streng konvex; es existiert ein eindeutiges globales Minimum.“ Kor"},{"seite":"qp-nlp.html","titel":"11.4 Die Karush-Kuhn-Tucker-Bedingungen","anker":"sec:qp-nlp-die-karush-kuhn-tucker-bedingungen","text":"Die KKT-Bedingungen verallgemeinern den Lagrange-Ansatz auf Probleme mit Ungleichungen. Sie sind notwendig für ein Optimum — und bei konvexen Problemen auch hinreichend."},{"seite":"qp-nlp.html","titel":"Die vier KKT-Bedingungen","anker":"die-vier-kkt-bedingungen","text":"Am Optimum (\\mathbf{x}^*, \\boldsymbol{\\lambda}^*, \\boldsymbol{\\nu}^*) gilt:"},{"seite":"qp-nlp.html","titel":"11.5 Nichtlineare Optimierung mit scipy.optimize.minimize","anker":"sec:qp-nlp-nichtlineare-optimierung-mit-scipy-optimize-minimize","text":"Wenn Zielfunktion oder Nebenbedingungen weder linear noch quadratisch sind — Logarithmen, Wurzeln, Exponentialfunktionen — nutzt man gradientenbasierte Verfahren wie SLSQP (Sequent"},{"seite":"qp-nlp.html","titel":"Praxisfall: Entropie-maximierte Kapitalallokation","anker":"praxisfall-entropie-maximierte-kapitalallokation","text":"Wir optimieren ein Portfolio nicht nur nach Varianz, sondern maximieren zusätzlich die Shannon-Entropie der Gewichte, um Klumpenrisiken glatt zu bestrafen:"},{"seite":"qp-nlp.html","titel":"11.6 Jenseits der Konvexität: lokale Optima, Multistart und MINLP","anker":"sec:qp-nlp-nichtkonvex","text":"Alles bisher in diesem Kapitel stand unter einer Bedingung: Konvexität. Sie ist der Grund, warum CVXPY eine Optimalitätsgarantie geben kann und warum die KKT-Bedingungen nicht nur "},{"seite":"qp-nlp.html","titel":"Woher Nicht-Konvexität im Alltag kommt","anker":"woher-nicht-konvexität-im-alltag-kommt","text":"Nicht aus exotischer Mathematik, sondern aus ganz gewöhnlichen betriebswirtschaftlichen Effekten:"},{"seite":"qp-nlp.html","titel":"Was ein lokales Optimum praktisch bedeutet","anker":"was-ein-lokales-optimum-praktisch-bedeutet","text":"scipy.optimize.minimize verweigert nichts. Es rechnet, meldet success: True und liefert eine Zahl. Diese Meldung heißt aber nicht „das ist das Optimum“, sondern nur:"},{"seite":"qp-nlp.html","titel":"Die Zahlen im Klartext","anker":"die-zahlen-im-klartext","text":""},{"seite":"qp-nlp.html","titel":"Ausblick: MINLP und globale Solver","anker":"ausblick-minlp-und-globale-solver","text":"Wird zusätzlich noch ganzzahlig entschieden — „welche Anlage läuft überhaupt“ und „wie stark“ —, entsteht ein MINLP (Mixed-Integer Nonlinear Program), die schwierigste der in diese"},{"seite":"qp-nlp.html","titel":"11.7 Übungsaufgaben","anker":"sec:qp-nlp-uebungsaufgaben","text":""},{"seite":"qp-nlp.html","titel":"11.8 Finde den Denkfehler","anker":"sec:qp-nlp-denkfehler","text":""},{"seite":"qp-nlp.html","titel":"11.9 Micro-Quiz","anker":"sec:qp-nlp-quiz","text":""},{"seite":"qp-nlp.html","titel":"11.10 Selbsttest","anker":"sec:qp-nlp-selbsttest","text":""},{"seite":"qp-nlp.html","titel":"11.11 Zusammenfassung","anker":"sec:qp-nlp-zusammenfassung","text":""},{"seite":"unsicherheit.html","titel":"Kapitel 12: Optimierung unter Unsicherheit — Monte-Carlo, Stochastik, Robustheit","anker":null,"text":""},{"seite":"unsicherheit.html","titel":"12.1 In 5 Minuten gelöst","anker":"sec:unsicherheit-schnellstart","text":""},{"seite":"unsicherheit.html","titel":"12.2 Lernziele","anker":"sec:unsicherheit-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"unsicherheit.html","titel":"12.3 Der Fluch des Durchschnitts","anker":"sec:unsicherheit-der-fluch-des-durchschnitts","text":"Der naheliegende Umgang mit Unsicherheit lautet: „Wir setzen den Erwartungswert ein und rechnen deterministisch.“ Das ist fast immer falsch — und zwar nicht ungenau, sondern system"},{"seite":"unsicherheit.html","titel":"Die vier Ansätze im Überblick","anker":"die-vier-ansätze-im-überblick","text":""},{"seite":"unsicherheit.html","titel":"12.4 Monte-Carlo-Simulation","anker":"sec:unsicherheit-monte-carlo-simulation","text":"Monte-Carlo heißt schlicht: Ziehe sehr viele Zufallsszenarien, werte für jedes den Plan aus, und betrachte die Verteilung der Ergebnisse statt eines einzigen Werts."},{"seite":"unsicherheit.html","titel":"12.5 Zweistufige stochastische Programmierung","anker":"sec:unsicherheit-zweistufige-stochastische-programmierung","text":"Das zweistufige Modell mit Recourse bildet ab, dass Entscheidungen zeitlich gestaffelt sind:"},{"seite":"unsicherheit.html","titel":"12.6 Robuste Optimierung: gegen den Worst Case absichern","anker":"sec:unsicherheit-robuste-optimierung-gegen-den-worst-case","text":"Wenn Wahrscheinlichkeiten unbekannt oder instabil sind — Marktcrashs, Lieferkettenabrisse, Pandemien —, hilft die robuste Optimierung. Sie fragt nicht nach dem Mittel, sondern nach"},{"seite":"unsicherheit.html","titel":"12.7 Wahrscheinlichkeitsbeschränkungen: „mit 95 % Sicherheit“","anker":"sec:unsicherheit-chance-constraints","text":"Die drei bisherigen Ansätze beantworten Fragen, die im Sitzungssaal selten so gestellt werden. „Was ist im Mittel am besten?“ hört ein Vorstand als Ausflucht; „was hält auch im sch"},{"seite":"unsicherheit.html","titel":"Weg 1: Normalverteilung — die Bedingung wird ein Kegel","anker":"weg-1-normalverteilung-die-bedingung-wird-ein-kegel","text":"Ist \\mathbf{a} \\sim \\mathcal{N}(\\hat{\\mathbf{a}}, \\boldsymbol{\\Sigma}), dann ist \\mathbf{a}^\\top\\mathbf{x} für festes \\mathbf{x} selbst normalverteilt, mit Erwartungswert \\hat{\\mat"},{"seite":"unsicherheit.html","titel":"Weg 2: Szenarien — Big-M ohne Verteilungsannahme","anker":"weg-2-szenarien-big-m-ohne-verteilungsannahme","text":"Liegen statt einer Verteilung nur S beobachtete Szenarien vor, bekommt jedes eine Binärvariable z_s, die sagt, ob es verletzt werden darf:"},{"seite":"unsicherheit.html","titel":"Der Fall: ein Kraftwerkspark mit 500 MW Zusage","anker":"der-fall-ein-kraftwerkspark-mit-500-mw-zusage","text":""},{"seite":"unsicherheit.html","titel":"12.8 Übungsaufgaben","anker":"sec:unsicherheit-uebungsaufgaben","text":""},{"seite":"unsicherheit.html","titel":"12.9 Finde den Denkfehler","anker":"sec:unsicherheit-denkfehler","text":""},{"seite":"unsicherheit.html","titel":"12.10 Micro-Quiz","anker":"sec:unsicherheit-quiz","text":""},{"seite":"unsicherheit.html","titel":"12.11 Selbsttest","anker":"sec:unsicherheit-selbsttest","text":""},{"seite":"unsicherheit.html","titel":"12.12 Zusammenfassung","anker":"sec:unsicherheit-zusammenfassung","text":""},{"seite":"dynamische-programmierung.html","titel":"Kapitel 13: Dynamische Programmierung — Die Bellman-Gleichung und Order-Execution","anker":null,"text":""},{"seite":"dynamische-programmierung.html","titel":"13.1 In 5 Minuten gelöst","anker":"sec:dynamische-programmierung-schnellstart","text":""},{"seite":"dynamische-programmierung.html","titel":"13.2 Lernziele","anker":"sec:dynamische-programmierung-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"dynamische-programmierung.html","titel":"13.3 Das Bellmansche Optimalitätsprinzip","anker":"sec:dynamische-programmierung-das-bellmansche-optimalitaetsprinzip","text":"Richard Bellman formulierte 1957 das Grundprinzip der Dynamischen Programmierung (DP):"},{"seite":"dynamische-programmierung.html","titel":"Die vier Bausteine eines DP-Modells","anker":"die-vier-bausteine-eines-dp-modells","text":""},{"seite":"dynamische-programmierung.html","titel":"Die Bellman-Gleichung","anker":"die-bellman-gleichung","text":"V_t(S_t) = \\min_{a_t\\in\\mathcal{A}(S_t)}\\Big\\{\\,C(S_t,a_t) \\;+\\; \\gamma\\cdot\\mathbb{E}\\big[V_{t+1}(S_{t+1})\\mid S_t,a_t\\big]\\Big\\}"},{"seite":"dynamische-programmierung.html","titel":"13.4 Das Almgren-Chriss-Problem: optimale Orderausführung","anker":"sec:dynamische-programmierung-das-almgren-chriss-problem-optimale-orderausfuehrung","text":"Ein klassisches OR-Problem an Börsen: Ein institutioneller Händler muss X_0 = 100\\,000 Aktien innerhalb von T Handelsperioden verkaufen."},{"seite":"dynamische-programmierung.html","titel":"13.5 Der Fluch der Dimensionalität","anker":"sec:dynamische-programmierung-der-fluch-der-dimensionalitaet","text":"DP ist mächtig, aber es hat eine harte Grenze. Der Aufwand der Rückwärtsinduktion ist"},{"seite":"dynamische-programmierung.html","titel":"13.6 Übungsaufgaben","anker":"sec:dynamische-programmierung-uebungsaufgaben","text":""},{"seite":"dynamische-programmierung.html","titel":"13.7 Finde den Denkfehler","anker":"sec:dynamische-programmierung-denkfehler","text":"Bei dynamischer Programmierung entscheidet eine einzige Frage über Erfolg oder Misserfolg: Was gehört in den Zustand? Ist er zu klein, rechnet das Verfahren völlig korrekt — nur eb"},{"seite":"dynamische-programmierung.html","titel":"13.8 Micro-Quiz","anker":"sec:dynamische-programmierung-quiz","text":""},{"seite":"dynamische-programmierung.html","titel":"13.9 Selbsttest","anker":"sec:dynamische-programmierung-selbsttest","text":""},{"seite":"dynamische-programmierung.html","titel":"13.10 Zusammenfassung","anker":"sec:dynamische-programmierung-zusammenfassung","text":""},{"seite":"mehrziel.html","titel":"Kapitel 14: Mehrere Ziele — Pareto-Fronten statt Gewichte","anker":null,"text":""},{"seite":"mehrziel.html","titel":"14.1 In 5 Minuten gelöst","anker":"sec:mehrziel-schnellstart","text":""},{"seite":"mehrziel.html","titel":"14.2 Lernziele","anker":"sec:mehrziel-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"mehrziel.html","titel":"14.3 Wann ein Kompromiss gut ist","anker":"sec:mehrziel-dominanz","text":"Bei einem Ziel ist „besser” eindeutig. Bei zwei Zielen nicht mehr: Ein Plan kann billiger und schmutziger sein als ein anderer, und dann ist keiner von beiden besser."},{"seite":"mehrziel.html","titel":"14.4 Der Reflex: alles in ein Ziel rühren","anker":"sec:mehrziel-skalarisierung","text":"Der naheliegende Weg, zwei Ziele zu einem zu machen, ist die gewichtete Summe:"},{"seite":"mehrziel.html","titel":"14.5 Das Programm","anker":"sec:mehrziel-programm","text":"Zwölf Sendungen, drei Verkehrsträger, fünf freie Bahntrassen. Der Zielkonflikt entsteht nicht zwischen den Trägern — die Bahn ist immer billiger und sauberer als der LKW —, sondern"},{"seite":"mehrziel.html","titel":"14.6 Was die gewichtete Summe nicht sieht","anker":"sec:mehrziel-luecke","text":"Die Front hat zehn Punkte. Ein Raster aus 1 401 Gewichten findet sechs davon. Vier Kompromisse sind für kein Gewicht erreichbar — und das ist keine Frage der Rasterweite."},{"seite":"mehrziel.html","titel":"Das Gewicht ist keine Feineinstellung","anker":"das-gewicht-ist-keine-feineinstellung","text":"Die zweite Beobachtung aus derselben Tabelle: 1 401 Gewichte erzeugen sechs verschiedene Pläne. Weite Gewichtsbereiche liefern dasselbe Ergebnis, und dazwischen springt es."},{"seite":"mehrziel.html","titel":"14.7 Das ε-Constraint-Verfahren","anker":"sec:mehrziel-epsilon","text":"Der Ausweg ist unspektakulär: Man macht aus dem zweiten Ziel eine Nebenbedingung."},{"seite":"mehrziel.html","titel":"Wenn es eine klare Rangfolge gibt: lexikografisch","anker":"wenn-es-eine-klare-rangfolge-gibt-lexikografisch","text":"Manchmal ist ein Ziel wirklich vorrangig. Dann optimiert man lexikografisch: erst das erste Ziel, dann das zweite unter der Bedingung, dass das erste (fast) erhalten bleibt."},{"seite":"mehrziel.html","titel":"14.8 Wie man die Front vorlegt","anker":"sec:mehrziel-vorlegen","text":"Eine Front mit zehn Punkten ist kein Ergebnis, sondern eine Speisekarte. Damit sie entscheidbar wird, gehört eine Spalte dazu, die im Programm EUR je kg heißt:"},{"seite":"mehrziel.html","titel":"14.9 Übungsaufgaben","anker":"sec:mehrziel-uebungsaufgaben","text":""},{"seite":"mehrziel.html","titel":"14.10 Finde den Denkfehler","anker":"sec:mehrziel-denkfehler","text":""},{"seite":"mehrziel.html","titel":"14.11 Micro-Quiz","anker":"sec:mehrziel-quiz","text":""},{"seite":"mehrziel.html","titel":"14.12 Selbsttest","anker":"sec:mehrziel-selbsttest","text":""},{"seite":"mehrziel.html","titel":"14.13 Zusammenfassung","anker":"sec:mehrziel-zusammenfassung","text":""},{"seite":"prognose.html","titel":"Kapitel 15: Predict-then-Optimize — die bessere Prognose, die schlechtere Entscheidung","anker":null,"text":""},{"seite":"prognose.html","titel":"15.1 In 5 Minuten gelöst","anker":"sec:prognose-schnellstart","text":""},{"seite":"prognose.html","titel":"15.2 Lernziele","anker":"sec:prognose-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"prognose.html","titel":"15.3 Die Naht zwischen zwei Abteilungen","anker":"sec:prognose-naht","text":"In fast jedem Unternehmen sieht der Ablauf so aus:"},{"seite":"prognose.html","titel":"15.4 Das Programm","anker":"sec:prognose-programm","text":"Dieselbe Bäckerei, aber mit Merkmalen: Wochentag, Temperatur, Aktionstage. Die Nachfrage muss jetzt modelliert werden."},{"seite":"prognose.html","titel":"15.5 Der Befund","anker":"sec:prognose-befund","text":""},{"seite":"prognose.html","titel":"Warum ein pauschaler Zuschlag zu kurz greift","anker":"warum-ein-pauschaler-zuschlag-zu-kurz-greift","text":"Die zweite Zeile der Tabelle ist die verbreitete Praxis: Punktprognose plus Sicherheitsbestand. Sie hilft (−7,3 %), bleibt aber hinter der Quantilregression zurück. Das Programm re"},{"seite":"prognose.html","titel":"15.6 Eine Messfalle, in die der Autor selbst getappt ist","anker":"sec:prognose-messfalle","text":"Der erste Entwurf dieses Programms bewertete auf 230 Testtagen — ein realistischer Zeitraum, gut sieben Monate. Dort hatte die Quantilregression den besseren MSE, und die ganze Aus"},{"seite":"prognose.html","titel":"15.7 Wie weit das Verfahren reicht","anker":"sec:prognose-ausblick","text":"Die dritte Zeile der Ergebnistabelle — „Zuschlag auf Kosten trainiert” — ist die einfachste denkbare Form einer Idee, die derzeit erforscht wird: das Prognosemodell direkt auf die "},{"seite":"prognose.html","titel":"15.8 Übungsaufgaben","anker":"sec:prognose-uebungsaufgaben","text":""},{"seite":"prognose.html","titel":"15.9 Finde den Denkfehler","anker":"sec:prognose-denkfehler","text":""},{"seite":"prognose.html","titel":"15.10 Micro-Quiz","anker":"sec:prognose-quiz","text":""},{"seite":"prognose.html","titel":"15.11 Selbsttest","anker":"sec:prognose-selbsttest","text":""},{"seite":"prognose.html","titel":"15.12 Zusammenfassung","anker":"sec:prognose-zusammenfassung","text":""},{"seite":"synthese-nichtlinear.html","titel":"Synthese Teil III","anker":null,"text":""},{"seite":"synthese-nichtlinear.html","titel":"Welche Annahme fällt weg?","anker":"welche-annahme-fällt-weg","text":""},{"seite":"synthese-nichtlinear.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-nichtlinear.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-nichtlinear.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"bruecke.html","titel":"Kapitel 16: Die Strukturbrücke — dieselbe Mathematik, zwei Welten","anker":null,"text":""},{"seite":"bruecke.html","titel":"16.1 In 5 Minuten gelöst","anker":"sec:bruecke-schnellstart","text":""},{"seite":"bruecke.html","titel":"16.2 Lernziele","anker":"sec:bruecke-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"bruecke.html","titel":"16.3 Das Programm","anker":"sec:bruecke-programm","text":""},{"seite":"bruecke.html","titel":"16.4 Die zwei Brücken im Einzelnen","anker":"sec:bruecke-einzelnen","text":""},{"seite":"bruecke.html","titel":"Erste Brücke: Allokation","anker":"erste-brücke-allokation","text":""},{"seite":"bruecke.html","titel":"Zweite Brücke: Absicherung gegen den schlechtesten Fall","anker":"zweite-brücke-absicherung-gegen-den-schlechtesten-fall","text":"Hier ist die Übereinstimmung noch enger, weil sie nicht nur die Struktur betrifft, sondern die Formel. Die Rockafellar-Uryasev-Formulierung aus Kapitel 20"},{"seite":"bruecke.html","titel":"Wo die Lösungen sich unterscheiden","anker":"wo-die-lösungen-sich-unterscheiden","text":"Der Vergleich fördert nebenbei einen Unterschied zutage, den man nicht erwartet: Die Streuungsgrenze von 40 % bindet nur im Einkauf, nicht im Depot."},{"seite":"bruecke.html","titel":"16.5 Wo die Brücke endet","anker":"sec:bruecke-grenzen","text":"Eine Analogie ist nur so nützlich wie die Grenzen, die man ihr zieht. Drei Dinge wandern nicht mit:"},{"seite":"bruecke.html","titel":"16.6 Übungsaufgaben","anker":"sec:bruecke-uebungsaufgaben","text":""},{"seite":"bruecke.html","titel":"16.7 Finde den Denkfehler","anker":"sec:bruecke-denkfehler","text":""},{"seite":"bruecke.html","titel":"16.8 Micro-Quiz","anker":"sec:bruecke-quiz","text":""},{"seite":"bruecke.html","titel":"16.9 Selbsttest","anker":"sec:bruecke-selbsttest","text":""},{"seite":"bruecke.html","titel":"16.10 Zusammenfassung","anker":"sec:bruecke-zusammenfassung","text":""},{"seite":"supplychain.html","titel":"Kapitel 17: Supply-Chain und Energieeinsatz unter Unsicherheit","anker":null,"text":""},{"seite":"supplychain.html","titel":"17.1 In 5 Minuten gelöst","anker":"sec:supplychain-schnellstart","text":""},{"seite":"supplychain.html","titel":"17.2 Lernziele","anker":"sec:supplychain-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"supplychain.html","titel":"17.3 Die Aufgabe","anker":"sec:supplychain-aufgabe","text":"Fünf Blöcke, 24 Stunden, eine Last zwischen 270 und 804 MW. Dazu Windeinspeisung, die niemand am Vorabend kennt."},{"seite":"supplychain.html","titel":"Die Zeitstruktur der Entscheidung","anker":"die-zeitstruktur-der-entscheidung","text":"Hier geht das Kapitel über Abschnitt 12.5 hinaus:"},{"seite":"supplychain.html","titel":"17.4 Das Programm","anker":"sec:supplychain-programm","text":""},{"seite":"supplychain.html","titel":"17.5 Der Befund","anker":"sec:supplychain-befund","text":""},{"seite":"supplychain.html","titel":"17.6 Was Versorgungssicherheit kostet","anker":"sec:supplychain-sicherheit","text":"Der dritte Plan legt eine CVaR-Schranke auf die nicht gedeckte Energie: Im Mittel der schlechtesten 10 % der Szenarien darf nichts fehlen. Dieselbe Rockafellar-Uryasev-Konstruktion"},{"seite":"supplychain.html","titel":"17.7 Übungsaufgaben","anker":"sec:supplychain-uebungsaufgaben","text":""},{"seite":"supplychain.html","titel":"17.8 Finde den Denkfehler","anker":"sec:supplychain-denkfehler","text":""},{"seite":"supplychain.html","titel":"17.9 Micro-Quiz","anker":"sec:supplychain-quiz","text":""},{"seite":"supplychain.html","titel":"17.10 Selbsttest","anker":"sec:supplychain-selbsttest","text":""},{"seite":"supplychain.html","titel":"17.11 Zusammenfassung","anker":"sec:supplychain-zusammenfassung","text":""},{"seite":"finanzdaten.html","titel":"Kapitel 18: Finanzdaten-Modellierung — Renditen, Kovarianz und Shrinkage","anker":null,"text":""},{"seite":"finanzdaten.html","titel":"18.1 In 5 Minuten gelöst","anker":"sec:finanzdaten-schnellstart","text":""},{"seite":"finanzdaten.html","titel":"18.2 Lernziele","anker":"sec:finanzdaten-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"finanzdaten.html","titel":"18.3 Diskrete und logarithmische Renditen","anker":"sec:finanzdaten-diskrete-und-logarithmische-renditen","text":"Sei P_{i,t} der bereinigte Schlusskurs (adjusted close) von Titel i zum Zeitpunkt t. „Bereinigt“ heißt: um Dividenden und Aktiensplits korrigiert — sonst erscheint jede Dividendenz"},{"seite":"finanzdaten.html","titel":"Diskrete Rendite","anker":"diskrete-rendite","text":"R_{i,t} = \\frac{P_{i,t} - P_{i,t-1}}{P_{i,t-1}} = \\frac{P_{i,t}}{P_{i,t-1}} - 1"},{"seite":"finanzdaten.html","titel":"Logarithmische Rendite","anker":"logarithmische-rendite","text":"r_{i,t} = \\ln\\!\\left(\\frac{P_{i,t}}{P_{i,t-1}}\\right) = \\ln P_{i,t} - \\ln P_{i,t-1}"},{"seite":"finanzdaten.html","titel":"18.4 Das Schätzfehler-Problem","anker":"sec:finanzdaten-das-schaetzfehler-problem","text":"Sei \\mathbf{X}\\in\\mathbb{R}^{T\\times N} die Matrix zentrierter Renditen von N Titeln über T Handelstage. Die Stichproben-Kovarianzmatrix lautet:"},{"seite":"finanzdaten.html","titel":"18.5 Ledoit-Wolf-Shrinkage","anker":"sec:finanzdaten-ledoit-wolf-shrinkage","text":"Olivier Ledoit und Michael Wolf lösten das Dilemma durch lineare Schrumpfung:"},{"seite":"finanzdaten.html","titel":"Welches Ziel \\mathbf{F}?","anker":"welches-ziel-mathbff","text":"Ein häufiges Missverständnis: Es gibt nämlich mehrere Ledoit-Wolf-Varianten, und Text und Code müssen sich konsistent auf dieselbe beziehen:"},{"seite":"finanzdaten.html","titel":"18.6 Praxis: Datenpipeline mit korrekter Spaltenreihenfolge","anker":"sec:finanzdaten-praxis-datenpipeline-mit-korrekter-spaltenreihenfolge","text":""},{"seite":"finanzdaten.html","titel":"18.7 Übungsaufgaben","anker":"sec:finanzdaten-uebungsaufgaben","text":""},{"seite":"finanzdaten.html","titel":"18.8 Finde den Denkfehler","anker":"sec:finanzdaten-denkfehler","text":""},{"seite":"finanzdaten.html","titel":"18.9 Micro-Quiz","anker":"sec:finanzdaten-quiz","text":""},{"seite":"finanzdaten.html","titel":"18.10 Selbsttest","anker":"sec:finanzdaten-selbsttest","text":""},{"seite":"finanzdaten.html","titel":"18.11 Zusammenfassung","anker":"sec:finanzdaten-zusammenfassung","text":""},{"seite":"markowitz.html","titel":"Kapitel 19: Die moderne Portfoliotheorie nach Markowitz","anker":null,"text":""},{"seite":"markowitz.html","titel":"19.1 In 5 Minuten gelöst","anker":"sec:markowitz-schnellstart","text":""},{"seite":"markowitz.html","titel":"19.2 Lernziele","anker":"sec:markowitz-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"markowitz.html","titel":"19.3 Warum Diversifikation funktioniert","anker":"sec:markowitz-warum-diversifikation-funktioniert","text":"Harry Markowitz’ zentrale Einsicht von 1952: Das Risiko eines Portfolios ist nicht die Summe der Einzelrisiken. Es hängt davon ab, wie die Titel zusammenspielen."},{"seite":"markowitz.html","titel":"19.4 Das Mean-Variance-Modell","anker":"sec:markowitz-das-mean-variance-modell","text":"Sei \\mathbf{w} = (w_1,\\dots,w_n)^\\top der Vektor der Portfoliogewichte:"},{"seite":"markowitz.html","titel":"Die Effizienzgrenze und das Tangentialportfolio","anker":"die-effizienzgrenze-und-das-tangentialportfolio","text":"Die Effizienzgrenze (efficient frontier) ist die Kurve aller Portfolios, die zu jedem Risikoniveau die höchstmögliche Rendite liefern."},{"seite":"markowitz.html","titel":"Die Korn-Transformation","anker":"die-korn-transformation","text":"Die Sharpe Ratio ist ein Bruch — und damit nicht konvex. CVXPY würde sie ablehnen. Der Ausweg ist ein eleganter Trick, der die Homogenität des Problems ausnutzt:"},{"seite":"markowitz.html","titel":"19.5 Institutionelle Nebenbedingungen","anker":"sec:markowitz-institutionelle-nebenbedingungen","text":"In der Praxis gelten regulatorische und interne Regeln:"},{"seite":"markowitz.html","titel":"Was diese Regeln kosten","anker":"was-diese-regeln-kosten","text":"Jede Regel schneidet etwas vom Erreichbaren ab. Wie viel, lässt sich ausrechnen — man legt die Effizienzlinie ohne und mit Beschränkungen übereinander:"},{"seite":"markowitz.html","titel":"19.6 Vollimplementierung mit CVXPY","anker":"sec:markowitz-vollimplementierung-mit-cvxpy","text":""},{"seite":"markowitz.html","titel":"19.7 Übungsaufgaben","anker":"sec:markowitz-uebungsaufgaben","text":""},{"seite":"markowitz.html","titel":"19.8 Finde den Denkfehler","anker":"sec:markowitz-denkfehler","text":"Kapitel 18 hat gezeigt, was eine schlecht geschätzte Kovarianzmatrix anrichtet. Bei den erwarteten Renditen ist es schlimmer — und weil sie in der Zielfunktion stehen statt in der "},{"seite":"markowitz.html","titel":"19.9 Micro-Quiz","anker":"sec:markowitz-quiz","text":""},{"seite":"markowitz.html","titel":"19.10 Selbsttest","anker":"sec:markowitz-selbsttest","text":""},{"seite":"markowitz.html","titel":"19.11 Zusammenfassung","anker":"sec:markowitz-zusammenfassung","text":""},{"seite":"cvar.html","titel":"Kapitel 20: Tail-Risiko, CVaR und Transaktionskosten","anker":null,"text":""},{"seite":"cvar.html","titel":"20.1 In 5 Minuten gelöst","anker":"sec:cvar-schnellstart","text":""},{"seite":"cvar.html","titel":"20.2 Lernziele","anker":"sec:cvar-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"cvar.html","titel":"20.3 Die zwei Schwächen des Markowitz-Modells","anker":"sec:cvar-die-zwei-schwaechen-des-markowitz-modells","text":"Erstens: die Normalverteilungs-Illusion. Die Varianz behandelt Aufwärts- und Abwärtsschwankungen gleich und unterstellt implizit symmetrische, dünn auslaufende Verteilungen. Reale "},{"seite":"cvar.html","titel":"20.4 Value at Risk und Conditional Value at Risk","anker":"sec:cvar-value-at-risk-und-conditional-value","text":""},{"seite":"cvar.html","titel":"Das Rockafellar-Uryasev-Theorem (2000)","anker":"das-rockafellar-uryasev-theorem-2000","text":"Rockafellar und Uryasev zeigten, dass sich der CVaR über S Szenarien exakt als lineares Programm formulieren lässt:"},{"seite":"cvar.html","titel":"20.5 Transaktionskosten über die L_1-Norm","anker":"sec:cvar-transaktionskosten-ueber-die-l-1-norm","text":"Sei \\mathbf{w}_{\\text{alt}} das bestehende Portfolio und \\mathbf{w} das neue Ziel. Der Umschlag (turnover) ist:"},{"seite":"cvar.html","titel":"20.6 Implementierung: CVaR-Portfolio mit Reibung","anker":"sec:cvar-implementierung-cvar-portfolio-mit-reibung","text":""},{"seite":"cvar.html","titel":"20.7 Übungsaufgaben","anker":"sec:cvar-uebungsaufgaben","text":""},{"seite":"cvar.html","titel":"20.8 Finde den Denkfehler","anker":"sec:cvar-denkfehler","text":""},{"seite":"cvar.html","titel":"20.9 Micro-Quiz","anker":"sec:cvar-quiz","text":""},{"seite":"cvar.html","titel":"20.10 Selbsttest","anker":"sec:cvar-selbsttest","text":""},{"seite":"cvar.html","titel":"20.11 Zusammenfassung","anker":"sec:cvar-zusammenfassung","text":""},{"seite":"handelsmaschine.html","titel":"Kapitel 21: Die vollständige quantitative Handelsmaschine","anker":null,"text":""},{"seite":"handelsmaschine.html","titel":"21.1 In 5 Minuten gelöst","anker":"sec:handelsmaschine-schnellstart","text":""},{"seite":"handelsmaschine.html","titel":"21.2 Lernziele","anker":"sec:handelsmaschine-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"handelsmaschine.html","titel":"21.3 Die Architektur","anker":"sec:handelsmaschine-die-architektur","text":""},{"seite":"handelsmaschine.html","titel":"21.4 Rebalancing-Termine richtig bestimmen","anker":"sec:handelsmaschine-rebalancing-termine-richtig-bestimmen","text":""},{"seite":"handelsmaschine.html","titel":"21.5 Die Engine","anker":"sec:handelsmaschine-die-engine","text":""},{"seite":"handelsmaschine.html","titel":"21.6 Die fünf Selbsttäuschungen des Backtestens","anker":"sec:handelsmaschine-die-fuenf-selbsttaeuschungen-des-backtestens","text":""},{"seite":"handelsmaschine.html","titel":"21.7 Vom Backtest zum Betrieb","anker":"sec:handelsmaschine-vom-backtest-zum-betrieb","text":"Ein guter Backtest ist eine notwendige, keine hinreichende Bedingung. Was zwischen Backtest und echtem Einsatz liegt:"},{"seite":"handelsmaschine.html","titel":"21.8 Übungsaufgaben","anker":"sec:handelsmaschine-uebungsaufgaben","text":""},{"seite":"handelsmaschine.html","titel":"21.9 Finde den Denkfehler","anker":"sec:handelsmaschine-denkfehler","text":"Backtest_Fallen.py zeigt drei Fehler, die im Backtest stecken: Lookahead, Survivorship, vergessene Kosten. Alle drei kann man einem Programm ansehen, wenn man es liest."},{"seite":"handelsmaschine.html","titel":"21.10 Micro-Quiz","anker":"sec:handelsmaschine-quiz","text":""},{"seite":"handelsmaschine.html","titel":"21.11 Selbsttest","anker":"sec:handelsmaschine-selbsttest","text":""},{"seite":"handelsmaschine.html","titel":"21.12 Zusammenfassung","anker":"sec:handelsmaschine-zusammenfassung","text":""},{"seite":"synthese-anwendungen.html","titel":"Synthese Teil IV","anker":null,"text":""},{"seite":"synthese-anwendungen.html","titel":"Dieselbe Struktur, andere Namen","anker":"dieselbe-struktur-andere-namen","text":""},{"seite":"synthese-anwendungen.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-anwendungen.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-anwendungen.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"praxisfallen.html","titel":"Kapitel 22: Praxisfallen und der Weg zum produktiven Einsatz","anker":null,"text":""},{"seite":"praxisfallen.html","titel":"22.1 In 5 Minuten gelöst","anker":"sec:praxisfallen-schnellstart","text":"Die vorangegangenen vierzehn Kapitel enden fast alle mit derselben Empfehlung: Prüfen Sie das Ergebnis gegen die Wirklichkeit. Dieses Kapitel beginnt damit, diese Prüfung als wiede"},{"seite":"praxisfallen.html","titel":"22.2 Lernziele","anker":"sec:praxisfallen-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"praxisfallen.html","titel":"22.3 Die fünf typischen Praxisfallen","anker":"sec:praxisfallen-die-fuenf-typischen-praxisfallen","text":""},{"seite":"praxisfallen.html","titel":"Falle 1 — Infeasibility","anker":"falle-1-infeasibility","text":"Wenn Parameter unglücklich zusammentreffen — drei Mitarbeitende gleichzeitig krank, kein qualifizierter Ersatz —, meldet der Solver schlicht INFEASIBLE."},{"seite":"praxisfallen.html","titel":"Falle 2 — Der Black-Box-Effekt","anker":"falle-2-der-black-box-effekt","text":"Ein Planer oder Trader lehnt ein System ab, wenn er die Zuweisungen nicht nachvollziehen kann. Akzeptanz ist keine Nebensache, sondern Voraussetzung für den Betrieb."},{"seite":"praxisfallen.html","titel":"Falle 3 — Regimewechsel und Schätzfehler","anker":"falle-3-regimewechsel-und-schätzfehler","text":"Ein Modell, das auf einer mehrjährigen Aufwärtsphase kalibriert wurde, kennt keine Liquiditätskrise und keine Zinswende."},{"seite":"praxisfallen.html","titel":"Falle 4 — Lookahead- und Survivorship-Bias","anker":"falle-4-lookahead--und-survivorship-bias","text":"Ausführlich in Kapitel 21 behandelt. Die Kurzfassung: Beide Fehler machen Backtests systematisch zu gut, ohne eine Fehlermeldung zu erzeugen. Der Lookahead-Selbsttest aus Abschnitt"},{"seite":"praxisfallen.html","titel":"Falle 5 — Laufzeitexplosion","anker":"falle-5-laufzeitexplosion","text":"Exakte Optimalität kann bei MILP oder CP-SAT Minuten bis Stunden dauern — und die Laufzeit wächst nicht linear mit der Problemgröße."},{"seite":"praxisfallen.html","titel":"22.4 Constraint Attribution: welche Bedingung kostet wie viel?","anker":"sec:praxisfallen-attribution","text":"Der Constraint-Trace beantwortet „warum diese Zuweisung?“. Der Deletion Filter in Anhang C beantwortet „warum geht es gar nicht?“. Der häufigste Fall in der Praxis liegt dazwischen"},{"seite":"praxisfallen.html","titel":"Drei Befunde, und keiner steht im Solverergebnis","anker":"drei-befunde-und-keiner-steht-im-solverergebnis","text":"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 —"},{"seite":"praxisfallen.html","titel":"Vom Zahlenwerk zur Vorlage","anker":"vom-zahlenwerk-zur-vorlage","text":"Alle drei Antworten stehen bis hierhin in Tabellen. Tabellen liest niemand in einer Abteilungsleiterrunde. Teil (4) des Programms baut aus denselben Zahlen einen Text — und das ist"},{"seite":"praxisfallen.html","titel":"22.5 Architektur einer produktionsreifen OR-Plattform","anker":"sec:praxisfallen-architektur-einer-produktionsreifen-or-plattform","text":""},{"seite":"praxisfallen.html","titel":"22.6 Der gemeinsame Unterbau: or_kern.py","anker":"sec:praxisfallen-or-kern","text":"Die fünf Prinzipien oben beschreiben eine Plattform. Der Weg dorthin beginnt aber viel kleiner — mit der Frage, welche Teile eines Optimierungsprogramms immer dieselben sind."},{"seite":"praxisfallen.html","titel":"Die vier Schichten","anker":"die-vier-schichten","text":"\\underbrace{\\text{Rohdaten}}_{\\text{Excel, CSV, ERP}}\n\\;\\longrightarrow\\;\n\\underbrace{\\text{Domänenmodell}}_{\\text{geprüft, solverfrei}}\n\\;\\longrightarrow\\;\n\\underbrace{\\text{Model"},{"seite":"praxisfallen.html","titel":"Ein Enum für fünf Bibliotheken","anker":"ein-enum-für-fünf-bibliotheken","text":"Der unscheinbarste, aber wirksamste Teil ist die Statusübersetzung. Dieselbe Aussage heißt in den fünf im Buch verwendeten Bibliotheken:"},{"seite":"praxisfallen.html","titel":"22.7 Der Solverwechsel in der Praxis","anker":"sec:praxisfallen-solverwechsel","text":"Der vorige Abschnitt endet mit einer Behauptung: Ein Solverwechsel betreffe genau einen Baustein. Das ist die Art Satz, die in jedem Architekturvortrag vorkommt und die man deshalb"},{"seite":"praxisfallen.html","titel":"22.8 Eine Checkliste vor dem Produktivgang","anker":"sec:praxisfallen-eine-checkliste-vor-dem-produktivgang","text":"Arbeiten Sie diese Liste ab, bevor ein OR-System in Betrieb geht:"},{"seite":"praxisfallen.html","titel":"22.9 Weiterführende Literatur und Roadmap","anker":"sec:praxisfallen-weiterfuehrende-literatur-und-roadmap","text":"Grundlagen und lineare/ganzzahlige Optimierung * Bertsimas & Tsitsiklis: Introduction to Linear Optimization — Standardwerk zu Simplex, Dualität, Polyedertheorie. * Wolsey: Int"},{"seite":"praxisfallen.html","titel":"22.10 Übungsaufgaben","anker":"sec:praxisfallen-uebungsaufgaben","text":""},{"seite":"praxisfallen.html","titel":"22.11 Finde den Denkfehler","anker":"sec:praxisfallen-denkfehler","text":"Falle 5 — die Laufzeitexplosion — zeigt sich im Betrieb selten als Absturz. Sie zeigt sich als gar nichts."},{"seite":"praxisfallen.html","titel":"22.12 Micro-Quiz","anker":"sec:praxisfallen-quiz","text":""},{"seite":"praxisfallen.html","titel":"22.13 Selbsttest","anker":"sec:praxisfallen-selbsttest","text":""},{"seite":"praxisfallen.html","titel":"22.14 Zusammenfassung","anker":"sec:praxisfallen-zusammenfassung","text":""},{"seite":"testing.html","titel":"Kapitel 23: Testen, Messen, Ausliefern","anker":null,"text":""},{"seite":"testing.html","titel":"23.1 In 5 Minuten gelöst","anker":"sec:testing-schnellstart","text":""},{"seite":"testing.html","titel":"23.2 Lernziele","anker":"sec:testing-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"testing.html","titel":"23.3 Warum Optimierungsmodelle schwer zu testen sind","anker":"sec:testing-warum-schwer","text":"Bei einer gewöhnlichen Funktion schreibt man den erwarteten Wert hin:"},{"seite":"testing.html","titel":"23.4 Die Testsuite","anker":"sec:testing-suite","text":""},{"seite":"testing.html","titel":"23.5 Wer testet die Tests?","anker":"sec:testing-mutation","text":"33 grüne Tests. Das ist noch kein Ergebnis."},{"seite":"testing.html","titel":"Der erste Lauf fand zwei Lücken","anker":"der-erste-lauf-fand-zwei-lücken","text":"Die Suite hatte zunächst 31 Tests. Der Mutationstest sagte dazu:"},{"seite":"testing.html","titel":"23.6 Ein Vergleich, dem man glauben kann","anker":"sec:testing-benchmark","text":"Solververgleiche stehen in jedem Blog, und die meisten sind wertlos. Nicht, weil falsch gemessen wurde, sondern weil zu wenig dazugesagt wird."},{"seite":"testing.html","titel":"Die interessanteste Spalte heißt „Anteil”","anker":"die-interessanteste-spalte-heißt-anteil","text":"Sie sagt, wie viel der Zeit in den Aufbau des Modells geht statt ins Lösen — und die Zahlen sind unbequem:"},{"seite":"testing.html","titel":"23.7 Das Modell als Dienst","anker":"sec:testing-dienst","text":"Ein Modell hinter eine HTTP-Schnittstelle zu hängen sieht nach einer Fingerübung aus. Es gibt aber einen Unterschied, der die ganze Bauform bestimmt:"},{"seite":"testing.html","titel":"Threads oder Prozesse? Eine Messung, keine Meinung","anker":"threads-oder-prozesse-eine-messung-keine-meinung","text":"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 w"},{"seite":"testing.html","titel":"Was im echten Betrieb dazukommt","anker":"was-im-echten-betrieb-dazukommt","text":"Das Beispiel hält das Auftragsbuch in einem dict und rechnet in Threads desselben Prozesses. Für einen einzelnen Rechner reicht das; darüber hinaus nicht:"},{"seite":"testing.html","titel":"23.8 Übungsaufgaben","anker":"sec:testing-uebungsaufgaben","text":""},{"seite":"testing.html","titel":"23.9 Finde den Denkfehler","anker":"sec:testing-denkfehler","text":""},{"seite":"testing.html","titel":"23.10 Micro-Quiz","anker":"sec:testing-quiz","text":""},{"seite":"testing.html","titel":"23.11 Selbsttest","anker":"sec:testing-selbsttest","text":""},{"seite":"testing.html","titel":"23.12 Zusammenfassung","anker":"sec:testing-zusammenfassung","text":""},{"seite":"synthese-praxis.html","titel":"Synthese Teil V","anker":null,"text":""},{"seite":"synthese-praxis.html","titel":"Was schiefgeht, und was dagegen hilft","anker":"was-schiefgeht-und-was-dagegen-hilft","text":""},{"seite":"synthese-praxis.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-praxis.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-praxis.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"projektwerkstatt.html","titel":"Projektwerkstatt","anker":null,"text":""},{"seite":"projektwerkstatt.html","titel":"Wie Sie ein Projekt bearbeiten","anker":"wie-sie-ein-projekt-bearbeiten","text":"Halten Sie sich an diese Reihenfolge — sie ist aus vielen gescheiterten und einigen gelungenen Projekten destilliert:"},{"seite":"projektwerkstatt.html","titel":"P1 — Vertretungsplaner für eine Schule","anker":"p1-vertretungsplaner-für-eine-schule","text":""},{"seite":"projektwerkstatt.html","titel":"P2 — Schichtplanung für ein Pflegeteam","anker":"p2-schichtplanung-für-ein-pflegeteam","text":""},{"seite":"projektwerkstatt.html","titel":"P3 — Tourenplanung für einen Lieferdienst","anker":"p3-tourenplanung-für-einen-lieferdienst","text":""},{"seite":"projektwerkstatt.html","titel":"P4 — Standort- und Lagernetzplanung","anker":"p4-standort--und-lagernetzplanung","text":""},{"seite":"projektwerkstatt.html","titel":"P5 — Produktionsplanung mit Rüstkosten","anker":"p5-produktionsplanung-mit-rüstkosten","text":""},{"seite":"projektwerkstatt.html","titel":"P6 — Portfolio-Rebalancer für ein Privatdepot","anker":"p6-portfolio-rebalancer-für-ein-privatdepot","text":""},{"seite":"projektwerkstatt.html","titel":"P7 — Risikoreport mit CVaR und Stresstests","anker":"p7-risikoreport-mit-cvar-und-stresstests","text":""},{"seite":"projektwerkstatt.html","titel":"P9 — Wenn der Solver aussteigt: Tourenplanung in Echtgröße","anker":"p9-wenn-der-solver-aussteigt-tourenplanung-in-echtgröße","text":""},{"seite":"projektwerkstatt.html","titel":"P10 — Zwei Ziele, eine Entscheidung: Kosten gegen CO₂","anker":"p10-zwei-ziele-eine-entscheidung-kosten-gegen-co₂","text":""},{"seite":"projektwerkstatt.html","titel":"P11 — Vom Skript zum Dienst: das Modell übergeben","anker":"p11-vom-skript-zum-dienst-das-modell-übergeben","text":""},{"seite":"projektwerkstatt.html","titel":"P8 — Freies Projekt aus Ihrem eigenen Umfeld","anker":"p8-freies-projekt-aus-ihrem-eigenen-umfeld","text":""},{"seite":"projektwerkstatt.html","titel":"Eine Bitte zum Schluss","anker":"eine-bitte-zum-schluss","text":"Wenn Sie ein Projekt fertig haben, machen Sie zwei Dinge:"},{"seite":"anhang-loesungen.html","titel":"Anhang A: Lösungen zu allen Übungsaufgaben","anker":null,"text":""},{"seite":"anhang-loesungen.html","titel":"A.1 Lösungen zu Kapitel „Einführung in Operations Research — Vom Ursprung zur mathematischen Entscheidungsfindung“","anker":"sec:loesungen-einfuehrung","text":"1.1 — Analytik-Stufen. (a) deskriptiv (Vergangenheit beschreiben). (b) prädiktiv (Prognose). (c) präskriptiv (Handlungsanweisung unter Restriktionen). (d) prädiktiv (Klassifikation"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Schreinerei verdoppelt ihren Gewinn","anker":"finde-den-denkfehler-die-schreinerei-verdoppelt-ihren-gewinn","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-einfuehrung","text":"1 — (c) präskriptiv. Die Frage lautet „was tun“, und es gibt eine Restriktion (das Restbudget). Dass man für die Bewertung eine Prognose braucht, macht die Frage nicht prädiktiv — "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-einfuehrung","text":""},{"seite":"anhang-loesungen.html","titel":"A.2 Lösungen zu Kapitel „Das mathematische Fundament — Vektoren, Matrizen, Konvexität“","anker":"sec:loesungen-fundament","text":"2.1 — Matrixform lesen. \\max 4x_1 + x_2 + 6x_3 u. d. N. x_1 + 2x_2 \\le 10, x_2 + 3x_3 \\le 12, x \\ge 0. 3 Variablen, 2 Nebenbedingungen (plus Nichtnegativität)."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die unauffällige Transposition","anker":"finde-den-denkfehler-die-unauffällige-transposition","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-fundament","text":"1 — (b). Der Fundamentalsatz sagt nur, dass ein Optimum in einer Ecke angenommen wird. (a) ist falsch, weil es mehrere optimale Ecken geben kann (wenn die Zielfunktion parallel zu "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-fundament","text":""},{"seite":"anhang-loesungen.html","titel":"A.3 Lösungen zu Kapitel „Das Python-Ökosystem für OR — Solver, Bindings und Modellierungsschichten“","anker":"sec:loesungen-oekosystem","text":"3.1 — Solverwahl. (a) CP-SAT (diskrete Zuordnung mit Zeitfenstern). (b) scipy.optimize.linprog (klassisches Mischungs-LP, klein). (c) CVXPY (konvexes QP). (d) MIQP — CVXPY mit Binä"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Der Solver, der angeblich dreimal schneller ist","anker":"finde-den-denkfehler-der-solver-der-angeblich-dreimal-schneller-ist","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-oekosystem","text":"1 — (b) CP-SAT. Es geht um diskrete Zuweisung mit logischen Regeln („nicht gleichzeitig“) — CP-SATs Kerngebiet, und Regeln dieser Art formuliert man dort direkt statt über Big-M-Um"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-oekosystem","text":""},{"seite":"anhang-loesungen.html","titel":"A.4 Lösungen zu Kapitel „Vom Management-Wunsch zum Modell“","anker":"sec:loesungen-modellierung","text":"4.1 — Die fehlende Lesart. Eine dritte Lesart: „Der Umsatzanteil der Stammkunden darf nicht unter 30 % fallen.” Sie zielt weder auf einzelne Aufträge noch auf einzelne Kunden, sond"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Die Engpassmaschine soll zu mindestens 92 % ausgelastet sein“","anker":"denkfehler-loesung-modellierung","text":"Fehler 1: Auslastung ist ein Ergebnis, keine Anforderung."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-modellierung","text":"1. b) Die Zielfunktion ist eine vollständige Aussage darüber, was zählt. Was nicht darin steht, ist für das Modell nicht „weniger wichtig”, sondern wertlos. (a) und (c) sind frei e"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-modellierung","text":""},{"seite":"anhang-loesungen.html","titel":"A.5 Lösungen zu Kapitel „Lineare Programmierung — Simplex, Dualität und Schattenpreise“","anker":"sec:loesungen-lp","text":"5.1 — Schlupf deuten. (a) Ressourcen 1 und 3 (Schlupf 0). (b) Ja: Überall ist s_i \\cdot y_i = 0. (c) In Ressource 3 — der höchste Schattenpreis (9,8) bedeutet den größten Grenznutz"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die 380 000-Euro-Maschine","anker":"finde-den-denkfehler-die-380-000-euro-maschine","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-lp","text":"1 — (b). Genau der Satz vom komplementären Schlupf: s_i \\cdot y_i = 0. Ist Schlupf vorhanden, muss der Dualwert null sein. (a) hat die Aussage in ihr Gegenteil verkehrt; (c) verwec"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-lp","text":""},{"seite":"anhang-loesungen.html","titel":"A.6 Lösungen zu Kapitel „Gemischt-ganzzahlige Optimierung — Diskrete Entscheidungen und Branch-and-Bound“","anker":"sec:loesungen-milp","text":"6.1 — Runden widerlegen. Beispiel: \\max x_1 + x_2 u. d. N. 10x_1 + 10x_2 \\le 15, ganzzahlig. LP-Optimum Z = 1{,}5; Abrunden ergibt (0,0) mit Z = 0 — 100 % Verlust. Das ganzzahlige "},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Elf Lager, die keine Fixkosten kosten","anker":"finde-den-denkfehler-elf-lager-die-keine-fixkosten-kosten","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-milp","text":"1 — (b). Der Gap (48\\,200 - 47\\,100)/48\\,200 = 2{,}3\\,\\% ist eine Garantie, keine Schätzung: Besser als 47 100 € kann es nachweislich nicht werden, also ist der vorliegende Plan hö"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-milp","text":""},{"seite":"anhang-loesungen.html","titel":"A.7 Lösungen zu Kapitel „Constraint Programming mit CP-SAT — Logik, Scheduling und Zuweisung“","anker":"sec:loesungen-cpsat","text":"7.1 — Propagation. Aus x_1 + x_2 = 8 und x_1 < x_2 folgt x_1 < 4, also x_1 \\in \\{2,3\\} (denn x_2 = 8-x_1 \\le 6 verlangt x_1 \\ge 2) und entsprechend x_2 \\in \\{5,6\\}. Aus 36 Ko"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Betriebsvereinbarung, die niemanden interessiert","anker":"finde-den-denkfehler-die-betriebsvereinbarung-die-niemanden-interessiert","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-cpsat","text":"1 — (b) wirkungslos. INFEASIBLE ist kein Abbruch, sondern ein Beweis: CP-SAT hat gezeigt, dass keine zulässige Lösung existiert. Mehr Zeit (a) oder mehr Arbeiter (c) ändern daran n"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-cpsat","text":""},{"seite":"anhang-loesungen.html","titel":"A.8 Lösungen zu Kapitel „Graphen, Flüsse und Touren — Min-Cost-Flow, Matching und VRP“","anker":"sec:loesungen-graphen","text":"8.1 — Flusserhaltung. b_i = (15+3) - (12+8) = -2 → Senke (Nettobedarf 2)."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die vergessene Dimension","anker":"finde-den-denkfehler-die-vergessene-dimension","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-graphen","text":"1 — (b) totale Unimodularität. Jede quadratische Teilmatrix hat Determinante 0, +1 oder -1; bei ganzzahliger rechter Seite sind deshalb alle Ecken des zulässigen Bereichs ganzzahli"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-graphen","text":""},{"seite":"anhang-loesungen.html","titel":"A.9 Lösungen zu Kapitel „Metaheuristiken — wenn der exakte Solver aussteigt“","anker":"sec:loesungen-metaheuristiken","text":"9.1 — Die Kurzsichtigkeit von Hand. Ab Schwarz wählt die Faustregel: Schwarz → Dunkelrot (26) → Rot (5) → … und muss dann in die helle Gruppe: Rot → Weiß (50) → Elfenbein (2) → Bei"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Unsere Heuristik ist 6 % besser“","anker":"denkfehler-loesung-metaheuristiken","text":"Es fehlt die Schranke."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-metaheuristiken","text":"1. b) Eine lokale Suche lebt von der Zahl geprüfter Züge. Die volle Summe kostet O(n) statt O(1) — bei 500 Aufträgen zwei Größenordnungen weniger Züge im selben Zeitbudget. Numeris"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-metaheuristiken","text":""},{"seite":"anhang-loesungen.html","titel":"A.10 Lösungen zu Kapitel „Spaltengenerierung“","anker":"sec:loesungen-dekomposition","text":"10.1 — Das Abbruchkriterium. Die Eins ist der Zielfunktionskoeffizient eines Musters: Jedes geschnittene Muster verbraucht genau eine Mutterrolle, und die Zielfunktion lautet \\min "},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Die LP-Lösung sagt 72,92 — also runden wir auf“","anker":"denkfehler-loesung-dekomposition","text":"Das Aufrunden kostet sechs Rollen — acht Prozent."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-dekomposition","text":"1. b) Das Mustermodell kennt keine einzelnen Rollen und damit keine austauschbaren Objekte — die Symmetrie verschwindet. (a) trifft zufällig auch zu, ist aber nicht der Grund; (c) "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-dekomposition","text":""},{"seite":"anhang-loesungen.html","titel":"A.11 Lösungen zu Kapitel „Quadratische und nichtlineare Optimierung — KKT, Lagrange, Konvexität“","anker":"sec:loesungen-qp-nlp","text":"11.1 — Konvexität einordnen. PSD (alle \\ge 0) → konvex, aber nicht streng konvex; die Lösung ist nicht notwendig eindeutig. Der Eigenwert 0 bedeutet eine flache Richtung: Entlang d"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Kovarianzmatrix aus dem Controlling","anker":"finde-den-denkfehler-die-kovarianzmatrix-aus-dem-controlling","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-qp-nlp","text":"1 — (b). Der DCPError ist eine inhaltliche Aussage: Für diese Formulierung kann es keine Optimalitätsgarantie geben. Auf scipy auszuweichen (a) beseitigt die Meldung, nicht die Urs"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-qp-nlp","text":""},{"seite":"anhang-loesungen.html","titel":"A.12 Lösungen zu Kapitel „Optimierung unter Unsicherheit — Monte-Carlo, Stochastik, Robustheit“","anker":"sec:loesungen-unsicherheit","text":"12.1 — Fluch des Durchschnitts. Weil sich Verzögerungen fortpflanzen und die Verteilung rechtsschief ist: Ein Gewerk, das früher fertig wird, beschleunigt selten den Gesamtablauf ("},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Warum jedes Projekt zu spät fertig wird","anker":"finde-den-denkfehler-warum-jedes-projekt-zu-spät-fertig-wird","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-unsicherheit","text":"1 — (b). Das kritische Verhältnis 1400/(1400+120) = 0{,}921 gibt an, wie weit man sich auf die günstigere Fehlerseite stellen soll: Bestellt wird das 92,1-%-Quantil des Bedarfs, hi"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-unsicherheit","text":""},{"seite":"anhang-loesungen.html","titel":"A.13 Lösungen zu Kapitel „Dynamische Programmierung — Die Bellman-Gleichung und Order-Execution“","anker":"sec:loesungen-dynamische-programmierung","text":"13.1 — Bausteine. Stufe = Tag 1–5; Zustand = verbleibende Distanz (ggf. plus Erschöpfungsgrad); Aktion = heutige Tagesetappe; Wertfunktion = minimale Restanstrengung. Nicht in den "},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Der Zustand, der zu wenig weiß","anker":"finde-den-denkfehler-der-zustand-der-zu-wenig-weiß","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-dynamische-programmierung","text":"1 — (b). V_t setzt V_{t+1} voraus: Eine Entscheidung lässt sich erst bewerten, wenn feststeht, was sie für die Zukunft bedeutet. Am Ende ist dieser Wert bekannt (V_T = g), deshalb "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-dynamische-programmierung","text":""},{"seite":"anhang-loesungen.html","titel":"A.14 Lösungen zu Kapitel „Mehrere Ziele — Pareto-Fronten statt Gewichte“","anker":"sec:loesungen-mehrziel","text":"14.1 — Dominanz prüfen. P (14 000 €, 6 000 kg) und Q (13 800 €, 6 100 kg): keiner dominiert den anderen. Q ist billiger, P ist sauberer — beide sind pareto-optimal, die Wahl ist ei"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Wir haben die Gewichte sauber kalibriert“","anker":"denkfehler-loesung-mehrziel","text":"Der Lösungsraum wurde nicht vollständig abgetastet — und zwar aus prinzipiellen Gründen."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-mehrziel","text":"1. b) Geometrisch heißt „gewichtete Summe minimieren“: eine Gerade von links unten an die Punktwolke schieben. Sie berührt immer einen Eckpunkt der unteren konvexen Hülle; Punkte d"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-mehrziel","text":""},{"seite":"anhang-loesungen.html","titel":"A.15 Lösungen zu Kapitel „Predict-then-Optimize“","anker":"sec:loesungen-prognose","text":"15.1 — Andere Preise. Der Überhang kostet nur noch 1,50 €, die Fehlmenge weiterhin 6 €. Das kritische Verhältnis steigt von 6/9 = 0{,}667 auf 6/7{,}5 = 0{,}80. Die Bestellmenge ver"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Wir haben die Prognose um 18 % verbessert“","anker":"denkfehler-loesung-prognose","text":"Der Sicherheitszuschlag stammt aus den Residuen des alten Modells."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-prognose","text":"1. b) Die Kostenasymmetrie verschiebt das Optimum vom Erwartungswert zum kritischen Quantil. (a) und (c) sind reale Probleme, aber nicht dieses: Selbst bei perfekt bekannter, norma"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-prognose","text":""},{"seite":"anhang-loesungen.html","titel":"A.16 Lösungen zu Kapitel „Die Strukturbrücke — dieselbe Mathematik, zwei Welten“","anker":"sec:loesungen-bruecke","text":"16.1 — Die dritte Ressource. „Liquidität” — wie schnell sich eine Position ohne Kursabschlag verkaufen lässt — entspricht in der Werkstatt der Umrüstbarkeit oder der Vorlaufzeit: W"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Das ist doch dasselbe Problem“","anker":"denkfehler-loesung-bruecke","text":"Fehler 1: Varianz ist hier das falsche Risikomaß — genau der Fall, für den es CVaR gibt."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-bruecke","text":"1. b) Beide Probleme haben dieselbe Struktur: knappe Größen auf konkurrierende Verwendungen verteilen. (a) ist falsch — Produktionsproblem ist streng typisiert und validiert beim E"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-bruecke","text":""},{"seite":"anhang-loesungen.html","titel":"A.17 Lösungen zu Kapitel „Supply-Chain und Energieeinsatz unter Unsicherheit“","anker":"sec:loesungen-supplychain","text":"17.1 — Der Umschlagpunkt. Bei 60 MW statt 120 MW halbiert sich die Grenzkostendifferenz je Stunde (83 €/MWh × 60 MW = 4 980 €/h). Der Umschlagpunkt verdoppelt sich auf 7,7 Stunden."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Wir rechnen mit dem P50-Szenario“","anker":"denkfehler-loesung-supplychain","text":"Fehler 1: Der Median ist keine Absicherung, sondern eine Wette auf die Hälfte der Fälle."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-supplychain","text":"1. b) Anfahrkosten und Mindestlaufzeiten koppeln die Stunden. Die Merit-Order ist eine Sortierung und kennt keine Kopplung über die Zeit; sie ist für einen einzelnen Zeitpunkt rich"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-supplychain","text":""},{"seite":"anhang-loesungen.html","titel":"A.18 Lösungen zu Kapitel „Finanzdaten-Modellierung — Renditen, Kovarianz und Shrinkage“","anker":"sec:loesungen-finanzdaten","text":"18.1 — Renditeart. (a) diskret. (b) logarithmisch. (c) logarithmisch (bzw. diskret kumuliert über Produkt). (d) logarithmisch (statistische Eigenschaften)."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Das risikofreie Portfolio","anker":"finde-den-denkfehler-das-risikofreie-portfolio","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-finanzdaten","text":"1 — (b) bei 75 %. 1{,}0 \\cdot 0{,}5 \\cdot 1{,}5 = 0{,}75. Prozentuale Änderungen verknüpfen sich multiplikativ; ein Verlust wiegt schwerer als ein gleich großer Gewinn, weil er von"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-finanzdaten","text":""},{"seite":"anhang-loesungen.html","titel":"A.19 Lösungen zu Kapitel „Die moderne Portfoliotheorie nach Markowitz“","anker":"sec:loesungen-markowitz","text":"19.1 — Diversifikationseffekt."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Zwölf gleiche Anlagen, ein sehr ungleiches Portfolio","anker":"finde-den-denkfehler-zwölf-gleiche-anlagen-ein-sehr-ungleiches-portfolio","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-markowitz","text":"1 — (b). Das renditestärkste Portfolio auf der Effizienzlinie hat notwendig das schlechteste Rendite-Risiko-Verhältnis (im Kapitelbeispiel 0,44 gegenüber 0,75 beim Optimum) und bes"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-markowitz","text":""},{"seite":"anhang-loesungen.html","titel":"A.20 Lösungen zu Kapitel „Tail-Risiko, CVaR und Transaktionskosten“","anker":"sec:loesungen-cvar","text":"20.1 — VaR 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{"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Das Risikobudget, das durch Diversifikation stieg","anker":"finde-den-denkfehler-das-risikobudget-das-durch-diversifikation-stieg","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-cvar","text":"1 — (b) nichts. Der VaR ist ein Quantil: Er markiert die Schwelle und sagt nichts über den Bereich dahinter. Genau das zeigt der Schnellstart dieses Kapitels — zwei Anlagen mit ide"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-cvar","text":""},{"seite":"anhang-loesungen.html","titel":"A.21 Lösungen zu Kapitel „Die vollständige quantitative Handelsmaschine“","anker":"sec:loesungen-handelsmaschine","text":"21.1 — Lookahead erkennen. (a) sauber (:heute). (b) Lookahead — gesamter Zeitraum. (c) Lookahead — Volatilität über den ganzen Zeitraum enthält Zukunft. (d) sauber — Gewichte aus D"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Strategie mit dem hochsignifikanten Ergebnis","anker":"finde-den-denkfehler-die-strategie-mit-dem-hochsignifikanten-ergebnis","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-handelsmaschine","text":"1 — (b) nichts. Beide Kennzahlen sind Mittelwerte über die Zeit und blind für die Reihenfolge. Der Schnellstart dieses Kapitels zeigt es an denselben Tagesrenditen, nur anders ange"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-handelsmaschine","text":""},{"seite":"anhang-loesungen.html","titel":"A.22 Lösungen zu Kapitel „Praxisfallen und der Weg zum produktiven Einsatz“","anker":"sec:loesungen-praxisfallen","text":"22.1 — Hart oder weich, revisited. (a) hart: gesetzliche Ruhezeit, Qualifikationspflicht. (b) weich: individuelle Wunschtage, Vermeidung von Freistunden. (c) diskutabel: Höchstzahl"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Das Modell, das seit einem Jahr nicht mehr optimiert","anker":"finde-den-denkfehler-das-modell-das-seit-einem-jahr-nicht-mehr-optimiert","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-praxisfallen","text":"1 — (b) das Zeitlimit greift. Eine Laufzeit, die exakt dem Limit entspricht und über Monate konstant bleibt, ist kein Stabilitätsbeleg, sondern zeigt, dass der Solver jedes Mal abg"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-praxisfallen","text":""},{"seite":"anhang-loesungen.html","titel":"A.23 Lösungen zu Kapitel „Testen, Messen, Ausliefern“","anker":"sec:loesungen-testing","text":"23.1 — Den Schnellstart reparieren. Zwei Wege: (a) Abrunden statt runden — np.floor statt np.round. Das ist immer zulässig, weil weniger produzieren nie eine Kapazität sprengt, kos"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Die Suite ist grün, das Modell stimmt”","anker":"denkfehler-loesung-testing","text":"Alle Prüfungen benutzen dieselbe falsche Zahl."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-testing","text":"1. b) Es gibt keine unabhängige Quelle für die richtige Antwort — sonst bräuchte man den Solver nicht. (a) ist bei festgelegtem Seed und Zeitlimit meist beherrschbar; (c) löst man "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-testing","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"Anhang B: Katalog der Modellierungsmuster","anker":null,"text":""},{"seite":"anhang-modellierungsmuster.html","titel":"Übersicht","anker":"übersicht","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"Logische Schalter","anker":"logische-schalter","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B1 — Aktivierungsschalter (Fixkosten)","anker":"b1-aktivierungsschalter-fixkosten","text":"Regel. „Wenn überhaupt etwas produziert wird, fallen Rüstkosten F an.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B2 — Semikontinuierliche Variable","anker":"b2-semikontinuierliche-variable","text":"Regel. „Entweder gar nicht oder mindestens L (und höchstens U).“"},{"seite":"anhang-modellierungsmuster.html","titel":"B3 — Implikation","anker":"b3-implikation","text":"Regel. „Wenn A gewählt wird, muss auch B gewählt werden.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B4 — Entweder-Oder (disjunktive Bedingung)","anker":"b4-entweder-oder-disjunktive-bedingung","text":"Regel. „Es muss f(\\mathbf{x}) \\le b_1 oder g(\\mathbf{x}) \\le b_2 gelten.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B5 — Exklusiv-Oder","anker":"b5-exklusiv-oder","text":"Regel. „Genau eine der Optionen wird gewählt.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B6 — Kardinalität","anker":"b6-kardinalität","text":"Regel. „Höchstens (mindestens, genau) K von N.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B7 — Bedingte Kopplung (Konjunktion)","anker":"b7-bedingte-kopplung-konjunktion","text":"Regel. „Wenn A und B, dann auch C.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Mengen und Grenzen","anker":"mengen-und-grenzen","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B8 — Weiche Grenze mit Strafkosten","anker":"b8-weiche-grenze-mit-strafkosten","text":"Regel. „Möglichst nicht über b — wenn doch, kostet es.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B9 — Gestaffelte Preise (stückweise linear)","anker":"b9-gestaffelte-preise-stückweise-linear","text":"Regel. „Die ersten 100 Stück kosten 5 €, danach 8 €.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B10 — Absolutbetrag / Abweichung","anker":"b10-absolutbetrag-abweichung","text":"Regel. „Die Abweichung vom Zielwert soll klein sein, egal in welche Richtung.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B11 — Min/Max in der Zielfunktion","anker":"b11-minmax-in-der-zielfunktion","text":"Regel. „Der am schlechtesten gestellte Beteiligte soll möglichst gut dastehen“ (Maximin/Fairness)."},{"seite":"anhang-modellierungsmuster.html","titel":"B12 — Verhältnis-Bedingung","anker":"b12-verhältnis-bedingung","text":"Regel. „Der Anteil von Gruppe G soll mindestens 30 % betragen.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B25 — Mindestabnahmemenge über einen Zeitraum","anker":"b25-mindestabnahmemenge-über-einen-zeitraum","text":"Regel. „Entweder wir arbeiten mit diesem Lieferanten gar nicht, oder wir nehmen ihm im Jahr mindestens 500 Einheiten ab.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B27 — Budgetlimit","anker":"b27-budgetlimit","text":"Regel. „Alle Maßnahmen zusammen dürfen 2 Mio. € nicht überschreiten.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Zeit und Reihenfolge","anker":"zeit-und-reihenfolge","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B13 — Vorrangbeziehung","anker":"b13-vorrangbeziehung","text":"Regel. „Arbeitsgang B darf erst beginnen, wenn A fertig ist.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B14 — Nichtüberlappung","anker":"b14-nichtüberlappung","text":"Regel. „Eine Maschine bearbeitet nur einen Job gleichzeitig.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B15 — Kumulative Ressource","anker":"b15-kumulative-ressource","text":"Regel. „Zu keinem Zeitpunkt dürfen mehr als 3 Arbeiten gleichzeitig laufen“ bzw. „die Stromlast darf 500 kW nie übersteigen“."},{"seite":"anhang-modellierungsmuster.html","titel":"B16 — Gleitendes Fenster","anker":"b16-gleitendes-fenster","text":"Regel. „Höchstens 5 Arbeitstage in Folge“ / „mindestens 2 freie Tage je Woche“."},{"seite":"anhang-modellierungsmuster.html","titel":"B17 — Umrüst- bzw. Wechselkosten","anker":"b17-umrüst--bzw.-wechselkosten","text":"Regel. „Ein Produktwechsel kostet Rüstzeit.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B26 — Rüstzeit als Kapazitätsverbrauch","anker":"b26-rüstzeit-als-kapazitätsverbrauch","text":"Regel. „Das Umrüsten kostet nicht nur Geld, es kostet Maschinenstunden — und die fehlen dann für die Produktion.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Robustheit und Diagnose","anker":"robustheit-und-diagnose","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B18 — Schlupfvariablen gegen Unlösbarkeit","anker":"b18-schlupfvariablen-gegen-unlösbarkeit","text":"Das wichtigste Muster für den Produktivbetrieb."},{"seite":"anhang-modellierungsmuster.html","titel":"B19 — Hierarchische Ziele (lexikografisch)","anker":"b19-hierarchische-ziele-lexikografisch","text":"Regel. „Erst die Besetzung sicherstellen, dann die Fairness optimieren.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B20 — Symmetriebrechung","anker":"b20-symmetriebrechung","text":"Regel. „Drei identische Maschinen — der Solver soll nicht alle Vertauschungen durchprobieren.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B21 — Worst-Case-Abzug (robuste Formulierung)","anker":"b21-worst-case-abzug-robuste-formulierung","text":"Regel. „Rechne nicht mit dem geschätzten Wert, sondern mit dem ungünstigsten plausiblen.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Netzwerke","anker":"netzwerke","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B22 — Flusserhaltung","anker":"b22-flusserhaltung","text":"\\sum_{j:(i,j)\\in E} x_{ij} - \\sum_{k:(k,i)\\in E} x_{ki} = b_i \\qquad \\forall i"},{"seite":"anhang-modellierungsmuster.html","titel":"B23 — Zuordnung 1:1","anker":"b23-zuordnung-11","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B24 — Subtour-Eliminierung","anker":"b24-subtour-eliminierung","text":"MTZ (einfach, aber schwach): u_i - u_j + C x_{ij} \\le C - d_j \\qquad \\forall i\\ne j"},{"seite":"anhang-modellierungsmuster.html","titel":"Ein Wort zur Auswahl","anker":"ein-wort-zur-auswahl","text":"Wenn mehrere Muster passen, entscheiden Sie nach dieser Reihenfolge:"},{"seite":"anhang-fehlerdiagnose.html","titel":"Anhang C: Fehlerdiagnose-Handbuch","anker":null,"text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"Symptom-Schnellübersicht","anker":"symptom-schnellübersicht","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C1 — INFEASIBLE","anker":"c1-infeasible","text":"Bedeutung. Es gibt keinen einzigen Punkt, der alle Bedingungen gleichzeitig erfüllt. Das ist eine Aussage über Ihr Modell, nicht über den Solver."},{"seite":"anhang-fehlerdiagnose.html","titel":"Diagnose in fünf Schritten","anker":"diagnose-in-fünf-schritten","text":"Schritt 1 — Trivialprüfungen von Hand. Rechnen Sie die offensichtlichen Bilanzen nach, bevor Sie den Solver befragen:"},{"seite":"anhang-fehlerdiagnose.html","titel":"Wenn die fünf Schritte nicht reichen: den Konflikt einkreisen","anker":"wenn-die-fünf-schritte-nicht-reichen-den-konflikt-einkreisen","text":"Warum Schritt 2 so oft ins Leere läuft. Bedingungen einzeln abzuschalten funktioniert nur, solange es einen Schuldigen gibt. Überlagern sich zwei unabhängige Widersprüche, bleibt d"},{"seite":"anhang-fehlerdiagnose.html","titel":"C2 — UNBOUNDED","anker":"c2-unbounded","text":"Bedeutung. Die Zielfunktion lässt sich unbegrenzt verbessern."},{"seite":"anhang-fehlerdiagnose.html","titel":"C3 — Zu langsam","anker":"c3-zu-langsam","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"Diagnosereihenfolge","anker":"diagnosereihenfolge","text":"1. Ist es überhaupt das Lösen?"},{"seite":"anhang-fehlerdiagnose.html","titel":"C4 — Unsinniges Ergebnis","anker":"c4-unsinniges-ergebnis","text":"Der Solver hat immer recht — bezogen auf das Modell, das Sie ihm gegeben haben. Wenn das Ergebnis unsinnig ist, beschreibt Ihr Modell nicht das Problem, das Sie meinen."},{"seite":"anhang-fehlerdiagnose.html","titel":"Checkliste","anker":"checkliste","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"Die wirksamste Gegenmaßnahme","anker":"die-wirksamste-gegenmaßnahme","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C5 — Instabile Lösung","anker":"c5-instabile-lösung","text":"Symptom. Ein zusätzlicher Handelstag, und das Portfolio sieht völlig anders aus."},{"seite":"anhang-fehlerdiagnose.html","titel":"Derselbe Fehler außerhalb der Finanzwelt","anker":"derselbe-fehler-außerhalb-der-finanzwelt","text":"Instabilität ist kein Portfolioproblem, sondern ein Skalierungsproblem — und es trifft jedes Modell, in dem Größen sehr verschiedener Ordnung nebeneinanderstehen. Euro-Beträge (10^"},{"seite":"anhang-fehlerdiagnose.html","titel":"C6 — Falsche Dualwerte","anker":"c6-falsche-dualwerte","text":"Symptom. Schattenpreise sind negativ, wo sie positiv sein sollten — oder null bei einer offensichtlich knappen Ressource."},{"seite":"anhang-fehlerdiagnose.html","titel":"Die drei Prüfungen","anker":"die-drei-prüfungen","text":"1. Vorzeichenkonvention. Haben Sie zur Maximierung negiert?"},{"seite":"anhang-fehlerdiagnose.html","titel":"C7 — Widersprüchliche Solver","anker":"c7-widersprüchliche-solver","text":"Symptom. linprog sagt 530, CVXPY sagt 529,8."},{"seite":"anhang-fehlerdiagnose.html","titel":"C8 — DCPError","anker":"c8-dcperror","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C9 — Importfehler","anker":"c9-importfehler","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C10 — Verdächtig guter Backtest","anker":"c10-verdächtig-guter-backtest","text":"Faustregel: Eine Sharpe Ratio über 2 bei einer einfachen Strategie ist fast immer ein Fehler, kein Fund."},{"seite":"anhang-fehlerdiagnose.html","titel":"Prüfreihenfolge","anker":"prüfreihenfolge","text":"1. Lookahead-Selbsttest."},{"seite":"anhang-fehlerdiagnose.html","titel":"C11 — Vertauschte Spalten","anker":"c11-vertauschte-spalten","text":"Symptom. Ergebnisse sind plausibel, aber falsch beschriftet — oder eine Sektorgrenze greift auf die falschen Titel."},{"seite":"anhang-fehlerdiagnose.html","titel":"Die goldene Diagnoseregel","anker":"die-goldene-diagnoseregel","text":""},{"seite":"anhang-spickzettel.html","titel":"Anhang D: Spickzettel der Solver","anker":null,"text":""},{"seite":"anhang-spickzettel.html","titel":"D1 — SciPy: linprog und milp","anker":"d1-scipy-linprog-und-milp","text":"Wofür. Die Einstiegsschicht: keine zusätzliche Installation, HiGHS als Unterbau, ideal für lineare und gemischt-ganzzahlige Probleme in Matrixform. Wofür nicht: alles, was sich nic"},{"seite":"anhang-spickzettel.html","titel":"Lineares Programm","anker":"lineares-programm","text":""},{"seite":"anhang-spickzettel.html","titel":"Ganzzahlig: milp","anker":"ganzzahlig-milp","text":""},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine","text":""},{"seite":"anhang-spickzettel.html","titel":"D2 — HiGHS über highspy","anker":"d2-highs-über-highspy","text":"Wofür. Derselbe Solver wie unter SciPy, aber direkt gesteuert: Optionen, Warm-Starts, inkrementelles Ändern eines bestehenden Modells. Wofür nicht: schnelles Hinschreiben — die CSR"},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-1","text":""},{"seite":"anhang-spickzettel.html","titel":"D3 — OR-Tools: pywraplp","anker":"d3-or-tools-pywraplp","text":"Wofür. Bequeme algebraische Schreibweise für LP und MILP mit umschaltbarem Backend (GLOP, SCIP, CBC, SAT). Wofür nicht: Scheduling und kombinatorische Bedingungen — dafür ist CP-SA"},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-2","text":""},{"seite":"anhang-spickzettel.html","titel":"D4 — CP-SAT: cp_model","anker":"d4-cp-sat-cp_model","text":"Wofür. Scheduling, Zuordnung, Reihenfolgen, alles Kombinatorische mit globalen Bedingungen. Wofür nicht: stetige Größen — CP-SAT rechnet ausschließlich ganzzahlig. Wer Nachkommaste"},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-3","text":""},{"seite":"anhang-spickzettel.html","titel":"D5 — CVXPY","anker":"d5-cvxpy","text":"Wofür. Konvexe Probleme: quadratische Ziele, Normen, CVaR, alles mit Regularisierungstermen. Wofür nicht: große kombinatorische Modelle — der Aufbau der Ausdrücke wird dann selbst "},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-4","text":""},{"seite":"anhang-spickzettel.html","titel":"D6 — Modellierungssprachen: Pyomo und Linopy","anker":"d6-modellierungssprachen-pyomo-und-linopy","text":"Wofür. Beide trennen Modell von Solver: dasselbe Modell läuft ohne Änderung unter HiGHS, CBC, Gurobi. Pyomo denkt in Mengen und Indizes wie eine mathematische Formulierung; Linopy "},{"seite":"anhang-spickzettel.html","titel":"Pyomo","anker":"pyomo","text":""},{"seite":"anhang-spickzettel.html","titel":"Linopy","anker":"linopy","text":""},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-5","text":""},{"seite":"anhang-spickzettel.html","titel":"Die gemeinsame Regel","anker":"die-gemeinsame-regel","text":"Alle sechs Seiten haben denselben längsten Abschnitt: die Statusauswertung. Das ist kein Zufall. Ein Solveraufruf hat nie zwei Ausgänge, sondern mindestens fünf — optimal, zulässig"},{"seite":"anhang-glossar.html","titel":"Anhang E: Glossar","anker":null,"text":""},{"seite":"anhang-literatur.html","titel":"Anhang F: Literaturverzeichnis","anker":null,"text":""},{"seite":"anhang-literatur.html","titel":"Grundlagen und Standardwerke des Operations Research","anker":"grundlagen-und-standardwerke-des-operations-research","text":"Zu Kapitel 1 und Kapitel 2."},{"seite":"anhang-literatur.html","titel":"Modellierung in Python: Bibliotheken und Modellierungsschichten","anker":"modellierung-in-python-bibliotheken-und-modellierungsschichten","text":"Zu Kapitel 3."},{"seite":"anhang-literatur.html","titel":"Lineare und ganzzahlige Optimierung","anker":"lineare-und-ganzzahlige-optimierung","text":"Zu Kapitel 5 und Kapitel 6."},{"seite":"anhang-literatur.html","titel":"Moderne Solver: Implementierung, Vergleich und Benchmarks","anker":"moderne-solver-implementierung-vergleich-und-benchmarks","text":"Zu Kapitel 3 und Anhang D. Neuer Abschnitt: Das Buch vergleicht durchgehend Solver, die Literatur dazu stand bisher verstreut."},{"seite":"anhang-literatur.html","titel":"Constraint Programming und Scheduling","anker":"constraint-programming-und-scheduling","text":"Zu Kapitel 7."},{"seite":"anhang-literatur.html","titel":"Graphen, Flüsse und Tourenplanung","anker":"graphen-flüsse-und-tourenplanung","text":"Zu Kapitel 8. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Metaheuristiken","anker":"metaheuristiken","text":"Zu Kapitel 9. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Spaltengenerierung und Dekomposition","anker":"spaltengenerierung-und-dekomposition","text":"Zu Kapitel 10. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Konvexe und nichtlineare Optimierung","anker":"konvexe-und-nichtlineare-optimierung","text":"Zu Kapitel 11."},{"seite":"anhang-literatur.html","titel":"Optimierung unter Unsicherheit: stochastisch, robust, Chance Constraints","anker":"optimierung-unter-unsicherheit-stochastisch-robust-chance-constraints","text":"Zu Kapitel 12 und Kapitel 17. Aus dem früheren Block „Konvexe, nichtlineare und robuste Optimierung” herausgelöst und erweitert."},{"seite":"anhang-literatur.html","titel":"Dynamische Programmierung und sequenzielle Entscheidungen","anker":"dynamische-programmierung-und-sequenzielle-entscheidungen","text":"Zu Kapitel 13. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Mehrkriterielle Optimierung","anker":"mehrkriterielle-optimierung","text":"Zu Kapitel 14. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Lernbasierte Optimierung: maschinelles Lernen und OR","anker":"lernbasierte-optimierung-maschinelles-lernen-und-or","text":"Zu Kapitel 15. Neuer Abschnitt — im Buch als eigenes Kapitel behandelt, in der Literaturliste bisher gar nicht vertreten."},{"seite":"anhang-literatur.html","titel":"Supply Chain, Energie und Produktionsplanung","anker":"supply-chain-energie-und-produktionsplanung","text":"Zu Kapitel 16 und Kapitel 17. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Quantitative Finanzmathematik","anker":"quantitative-finanzmathematik","text":"Zu Kapitel 18, Kapitel 19, Kapitel 20 und Kapitel 21."},{"seite":"anhang-literatur.html","titel":"Praxis: Betrieb, Test und Auslieferung von Optimierungsmodellen","anker":"praxis-betrieb-test-und-auslieferung-von-optimierungsmodellen","text":"Zu Kapitel 22 und Kapitel 23. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Software, Dokumentation und Datenquellen","anker":"software-dokumentation-und-datenquellen","text":""},{"seite":"anhang-literatur.html","titel":"Verbände, Normen und Regulierung","anker":"verbände-normen-und-regulierung","text":""},{"seite":"anhang-literatur.html","titel":"Änderungsprotokoll","anker":"änderungsprotokoll","text":"Stand: September 2026. Überarbeitung des Literaturverzeichnisses gegenüber der Vorgängerfassung."},{"seite":"anhang-literatur.html","titel":"Prüfung gegen Crossref","anker":"prüfung-gegen-crossref","text":"Alle Einträge wurden einzeln gegen die Crossref-API geprüft — bei einem Literaturverzeichnis ist eine erfundene oder falsch zitierte Quelle der schwerste Fehler, weil der Leser sie"}];
+window.OR_SEARCH_INDEX = [{"seite":"vorwort.html","titel":"Vorwort & Lesehilfe","anker":null,"text":""},{"seite":"notation.html","titel":"Notation & Abkürzungen","anker":null,"text":""},{"seite":"notation.html","titel":"1. Die Symbole der Optimierung","anker":"die-symbole-der-optimierung","text":""},{"seite":"notation.html","titel":"1.1 Grundgrößen jedes Modells","anker":"grundgrößen-jedes-modells","text":""},{"seite":"notation.html","titel":"1.2 Mengen und Zahlbereiche","anker":"mengen-und-zahlbereiche","text":""},{"seite":"notation.html","titel":"1.3 Operatoren und Schreibweisen","anker":"operatoren-und-schreibweisen","text":""},{"seite":"notation.html","titel":"1.4 Symbole der Finanzkapitel (Teil IV)","anker":"symbole-der-finanzkapitel-teil-iv","text":""},{"seite":"notation.html","titel":"1.5 Symbole der Verfahrenskapitel (Teil II und III)","anker":"symbole-der-verfahrenskapitel-teil-ii-und-iii","text":"Diese Zeichen kommen erst in den Kapiteln vor, die über das klassische LP hinausgehen."},{"seite":"notation.html","titel":"2. Abkürzungen — vollständig ausgeschrieben","anker":"abkürzungen-vollständig-ausgeschrieben","text":""},{"seite":"notation.html","titel":"2.1 Problemklassen und Verfahren","anker":"problemklassen-und-verfahren","text":""},{"seite":"notation.html","titel":"2.2 Probleme mit Eigennamen","anker":"probleme-mit-eigennamen","text":""},{"seite":"notation.html","titel":"2.3 Finanz- und Risikokennzahlen","anker":"finanz--und-risikokennzahlen","text":""},{"seite":"notation.html","titel":"2.4 Software, Solver und Schnittstellen","anker":"software-solver-und-schnittstellen","text":""},{"seite":"notation.html","titel":"2.5 Begriffe aus dem Solver-Alltag","anker":"begriffe-aus-dem-solver-alltag","text":""},{"seite":"notation.html","titel":"3. Konventionen in diesem Buch","anker":"konventionen-in-diesem-buch","text":"Vektoren sind grundsätzlich Spaltenvektoren und werden fett gesetzt: \\mathbf{x}. Ein transponierter Vektor \\mathbf{x}^\\top ist eine Zeile. Skalare bleiben mager: n, Z."},{"seite":"einfuehrung.html","titel":"Kapitel 1: Einführung in Operations Research — Vom Ursprung zur mathematischen Entscheidungsfindung","anker":null,"text":""},{"seite":"einfuehrung.html","titel":"1.1 In 5 Minuten gelöst","anker":"sec:einfuehrung-schnellstart","text":"Bevor wir über Theorie sprechen, lösen Sie ein echtes Problem. Kopieren Sie den folgenden Block, führen Sie ihn aus, sehen Sie das Ergebnis — die Erklärung kommt danach."},{"seite":"einfuehrung.html","titel":"1.2 Lernziele","anker":"sec:einfuehrung-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"einfuehrung.html","titel":"1.3 Was ist Operations Research wirklich?","anker":"sec:einfuehrung-was-ist-operations-research-wirklich","text":"Im Alltag lösen wir Probleme intuitiv: durch Ausprobieren, Daumenregeln, Erfahrung. Das funktioniert erstaunlich gut — bis eine bestimmte Schwelle überschritten wird. Dann bricht d"},{"seite":"einfuehrung.html","titel":"Die drei Stufen der Analytik","anker":"die-drei-stufen-der-analytik","text":"OR beantwortet nicht die beschreibende Frage „Was ist passiert?“ und nicht die vorhersagende Frage „Was wird passieren?“, sondern die vorschreibende (präskriptive) Kernfrage:"},{"seite":"einfuehrung.html","titel":"1.4 Warum Ausprobieren scheitert — mit eigener Rechnung","anker":"sec:einfuehrung-warum-ausprobieren-scheitert-mit-eigener-rechnung","text":"Die Behauptung „vollständiges Durchprobieren ist unmöglich“ wird oft aufgestellt und selten belegt. Rechnen wir sie einmal selbst nach — das Ergebnis prägt sich besser ein als jede"},{"seite":"einfuehrung.html","titel":"1.5 Historischer Kontext und Evolution","anker":"sec:einfuehrung-historischer-kontext-und-evolution","text":"Der Begriff entstand im Vorfeld des Zweiten Weltkriegs in Großbritannien. Militärische Führungsstäbe standen vor neuartigen logistischen und strategischen Fragen: Wie platziert man"},{"seite":"einfuehrung.html","titel":"1.6 Die vier universellen Bausteine jedes OR-Problems","anker":"sec:einfuehrung-die-vier-universellen-bausteine-jedes-or","text":"Dies ist der wichtigste Abschnitt des Kapitels. Jedes Optimierungsproblem der Welt lässt sich — unabhängig von der Branche — auf vier Elemente reduzieren. Wenn Sie später vor einem"},{"seite":"einfuehrung.html","titel":"Baustein 1 — Entscheidungsvariablen (x)","anker":"baustein-1-entscheidungsvariablen-x","text":"Die Stellschrauben des Modells: Werte, die der Algorithmus aktiv festlegen darf."},{"seite":"einfuehrung.html","titel":"Baustein 2 — Parameter / Eingabedaten (c, A, b)","anker":"baustein-2-parameter-eingabedaten-c-a-b","text":"Die unveränderlichen Fakten der Realität: historische Renditen, Maschinenstundensätze, Lagerkapazitäten, Steuerquoten, Entfernungen, Qualifikationen."},{"seite":"einfuehrung.html","titel":"Baustein 3 — Zielfunktion (f(x))","anker":"baustein-3-zielfunktion-fx","text":"Ein mathematischer Ausdruck, der die Güte einer Lösung zu einer einzigen Zahl verdichtet:"},{"seite":"einfuehrung.html","titel":"Baustein 4 — Nebenbedingungen (Constraints)","anker":"baustein-4-nebenbedingungen-constraints","text":"Regeln, die den Raum der erlaubten Lösungen einschränken:"},{"seite":"einfuehrung.html","titel":"Die vier Bausteine als eine Formel","anker":"die-vier-bausteine-als-eine-formel","text":"Setzt man die vier Bausteine zusammen, entsteht die Standardform, in der Ihnen jedes Optimierungsmodell dieses Buches begegnen wird. Sie sieht auf den ersten Blick sperrig aus — de"},{"seite":"einfuehrung.html","titel":"Die Bausteine in der Praxis: eine Vorlage","anker":"die-bausteine-in-der-praxis-eine-vorlage","text":"Damit die Zerlegung zur Gewohnheit wird, hier eine Vorlage, die Sie bei jedem neuen Problem ausfüllen können — vor der ersten Codezeile."},{"seite":"einfuehrung.html","titel":"1.7 Erstes Python-Vollbeispiel: Ressourcenallokation im Rechenzentrum","anker":"sec:einfuehrung-erstes-python-vollbeispiel-ressourcenallokation-im-rechenzentrum","text":""},{"seite":"einfuehrung.html","titel":"Szenario","anker":"szenario","text":"Ein quantitatives Handelshaus betreibt Serverkapazitäten für zwei Algorithmentypen:"},{"seite":"einfuehrung.html","titel":"Mathematische Formulierung","anker":"mathematische-formulierung","text":"Entscheidungsvariablen:"},{"seite":"einfuehrung.html","titel":"Umsetzung mit Google OR-Tools","anker":"umsetzung-mit-google-or-tools","text":""},{"seite":"einfuehrung.html","titel":"1.8 Von Excel zu Python: Ihre Daten liegen schon da","anker":"sec:einfuehrung-excel-bruecke","text":"In den allermeisten Betrieben liegen die Zahlen, die ein Optimierungsmodell braucht, nicht in einer Datenbank, sondern in einer Tabellenkalkulation. Und viele Leserinnen und Leser "},{"seite":"einfuehrung.html","titel":"1.9 Übungsaufgaben","anker":"sec:einfuehrung-uebungsaufgaben","text":""},{"seite":"einfuehrung.html","titel":"1.10 Finde den Denkfehler","anker":"sec:einfuehrung-denkfehler","text":"Ein Programm, das abstürzt, ist harmlos — Sie sehen sofort, dass etwas nicht stimmt. Gefährlich sind Programme, die fehlerfrei durchlaufen, einen Status OPTIMAL melden und eine Zah"},{"seite":"einfuehrung.html","titel":"1.11 Micro-Quiz","anker":"sec:einfuehrung-quiz","text":""},{"seite":"einfuehrung.html","titel":"1.12 Selbsttest","anker":"sec:einfuehrung-selbsttest","text":""},{"seite":"einfuehrung.html","titel":"1.13 Zusammenfassung","anker":"sec:einfuehrung-zusammenfassung","text":""},{"seite":"fundament.html","titel":"Kapitel 2: Das mathematische Fundament — Vektoren, Matrizen, Konvexität","anker":null,"text":""},{"seite":"fundament.html","titel":"2.1 In 5 Minuten gelöst","anker":"sec:fundament-schnellstart","text":"Dieses Kapitel handelt von Geometrie. Bevor wir Vektoren und Matrizen einführen, sehen Sie die zentrale Einsicht in Aktion — ganz ohne Solver, mit acht Zeilen NumPy."},{"seite":"fundament.html","titel":"2.2 Lernziele","anker":"sec:fundament-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"fundament.html","titel":"2.3 Warum überhaupt Vektoren und Matrizen?","anker":"sec:fundament-warum-ueberhaupt-vektoren-und-matrizen","text":"In Kapitel 1 hatten wir zwei Variablen und drei Nebenbedingungen. Das ließ sich bequem ausschreiben. Reale Modelle haben hunderte bis hunderttausende Variablen — dort wäre Ausschre"},{"seite":"fundament.html","titel":"Die Bausteine","anker":"die-bausteine","text":"Sei n die Anzahl der Entscheidungsvariablen und m die Anzahl der Nebenbedingungen."},{"seite":"fundament.html","titel":"Die kanonische Standardform","anker":"die-kanonische-standardform","text":"Damit lässt sich jedes lineare Programm in drei Zeilen schreiben:"},{"seite":"fundament.html","titel":"Dasselbe in Python","anker":"dasselbe-in-python","text":""},{"seite":"fundament.html","titel":"2.4 Der zulässige Lösungsraum und das Polyeder","anker":"sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder","text":"Jede lineare Ungleichung a_{i1}x_1 + a_{i2}x_2 \\le b_i definiert geometrisch eine Halbebene (im \\mathbb{R}^2) bzw. einen Halbraum (im \\mathbb{R}^n): Die zugehörige Gleichung ist ei"},{"seite":"fundament.html","titel":"Der Fundamentalsatz der linearen Optimierung","anker":"der-fundamentalsatz-der-linearen-optimierung","text":""},{"seite":"fundament.html","titel":"2.5 Konvexität: die Grenze zwischen leicht und schwer","anker":"sec:fundament-konvexitaet-die-grenze-zwischen-leicht-und","text":"Hier kommt die vielleicht wichtigste Einsicht des ganzen Buches. In der Optimierungstheorie verläuft die Trennlinie zwischen „zuverlässig lösbar“ und „im Allgemeinen hoffnungslos“ "},{"seite":"fundament.html","titel":"Konvexe Menge","anker":"konvexe-menge","text":"Eine Menge \\mathcal{C} \\subseteq \\mathbb{R}^n heißt konvex, wenn für alle Punkte \\mathbf{x}, \\mathbf{y} \\in \\mathcal{C} und jedes \\theta \\in [0,1] gilt:"},{"seite":"fundament.html","titel":"Konvexe Funktion","anker":"konvexe-funktion","text":"Eine Funktion f: \\mathcal{C} \\to \\mathbb{R} heißt konvex, wenn für alle \\mathbf{x}, \\mathbf{y} \\in \\mathcal{C} und \\theta \\in [0,1] gilt:"},{"seite":"fundament.html","titel":"Der zentrale Satz","anker":"der-zentrale-satz","text":""},{"seite":"fundament.html","titel":"Was ist konvex, was nicht?","anker":"was-ist-konvex-was-nicht","text":""},{"seite":"fundament.html","titel":"Konvexität sichtbar machen","anker":"konvexität-sichtbar-machen","text":""},{"seite":"fundament.html","titel":"2.6 Geometrische Visualisierung des Lösungsraums","anker":"sec:fundament-geometrische-visualisierung-des-loesungsraums","text":"Wir zeichnen nun den Lösungsraum aus Kapitel 1 und lesen das Optimum ab. Zweidimensionale Bilder sind der schnellste Weg, Intuition für höhere Dimensionen aufzubauen — auch wenn ma"},{"seite":"fundament.html","titel":"2.7 Wenn die Zahlen nicht zusammenpassen: Kondition und Skalierung","anker":"sec:fundament-kondition","text":"Bis hierher war die lineare Algebra exakt. Ein Rechner rechnet aber nicht exakt, sondern mit rund 16 signifikanten Stellen — und Ihre Betriebsdaten sind ohnehin nur auf wenige Stel"},{"seite":"fundament.html","titel":"Die geometrische Vorstellung: zwei fast parallele Linien","anker":"die-geometrische-vorstellung-zwei-fast-parallele-linien","text":"Zwei Nebenbedingungen legen im Zweidimensionalen einen Schnittpunkt fest. Stehen die zugehörigen Geraden kreuzweise aufeinander, ist der Schnittpunkt robust: Verschiebt man eine Ge"},{"seite":"fundament.html","titel":"Woher schlechte Kondition im Alltag kommt","anker":"woher-schlechte-kondition-im-alltag-kommt","text":"Fast nie aus exotischer Mathematik — fast immer aus Einheiten:"},{"seite":"fundament.html","titel":"Ruiz-Equilibrierung: das Modell gesundrechnen","anker":"ruiz-equilibrierung-das-modell-gesundrechnen","text":"Die Gegenmaßnahme ist erstaunlich schlicht. Man multipliziert jede Zeile und jede Spalte der Matrix mit einem Faktor, sodass die Beträge überall in derselben Größenordnung landen:"},{"seite":"fundament.html","titel":"Das Experiment","anker":"das-experiment","text":"Das folgende Programm führt beides vor — die Fehlerverstärkung und ihre Behebung — und schließt mit der praktischen Konsequenz, die Sie in Kapitel 6 wieder brauchen werden: warum e"},{"seite":"fundament.html","titel":"2.8 Übungsaufgaben","anker":"sec:fundament-uebungsaufgaben","text":""},{"seite":"fundament.html","titel":"2.9 Finde den Denkfehler","anker":"sec:fundament-denkfehler","text":""},{"seite":"fundament.html","titel":"2.10 Micro-Quiz","anker":"sec:fundament-quiz","text":""},{"seite":"fundament.html","titel":"2.11 Selbsttest","anker":"sec:fundament-selbsttest","text":""},{"seite":"fundament.html","titel":"2.12 Zusammenfassung","anker":"sec:fundament-zusammenfassung","text":""},{"seite":"oekosystem.html","titel":"Kapitel 3: Das Python-Ökosystem für OR — Solver, Bindings und Modellierungsschichten","anker":null,"text":""},{"seite":"oekosystem.html","titel":"3.1 In 5 Minuten gelöst","anker":"sec:oekosystem-schnellstart","text":""},{"seite":"oekosystem.html","titel":"3.2 Lernziele","anker":"sec:oekosystem-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"oekosystem.html","titel":"3.3 Die Zwei-Schichten-Architektur","anker":"sec:oekosystem-die-zwei-schichten-architektur","text":"Im modernen Operations Research schreibt man Optimierungsalgorithmen nicht selbst. Man nutzt eine zweischichtige Architektur:"},{"seite":"oekosystem.html","titel":"3.4 Die Werkzeuge im Vergleich","anker":"sec:oekosystem-die-werkzeuge-im-vergleich","text":""},{"seite":"oekosystem.html","titel":"Die Entscheidung in drei Fragen","anker":"die-entscheidung-in-drei-fragen","text":"Statt die Tabelle auswendig zu lernen, beantworten Sie drei Fragen:"},{"seite":"oekosystem.html","titel":"3.5 Ein System — vier Programmieransätze","anker":"sec:oekosystem-ein-system-vier-programmieransaetze","text":"Nichts macht die Unterschiede so deutlich wie dasselbe Problem, viermal gelöst. Wir nehmen:"},{"seite":"oekosystem.html","titel":"Wie die Isolation aussieht, wenn sie tragen soll","anker":"wie-die-isolation-aussieht-wenn-sie-tragen-soll","text":"„Eigener Prozess” ist schnell gesagt. Die naheliegende Umsetzung — ein Codeschnipsel als Zeichenkette an python -c übergeben — funktioniert und ist trotzdem die schlechteste: Der S"},{"seite":"oekosystem.html","titel":"Was das CSR-Format bedeutet","anker":"was-das-csr-format-bedeutet","text":"highspy erwartet die Nebenbedingungsmatrix im CSR-Format (Compressed Sparse Row, komprimierte Zeilendarstellung). Statt der vollen Matrix speichert man nur die Einträge ungleich nu"},{"seite":"oekosystem.html","titel":"3.6 Wann lohnt sich welche Ebene?","anker":"sec:oekosystem-wann-lohnt-sich-welche-ebene","text":""},{"seite":"oekosystem.html","titel":"3.7 Modellierungsschichten für große Modelle: Pyomo und Linopy","anker":"sec:oekosystem-pyomo-linopy","text":"Die vier Bibliotheken aus dem Vierfach-Vergleich decken den Alltag weitgehend ab. Sobald Modelle industrielle Größe erreichen — zehntausende Variablen, Daten aus mehreren Systemen,"},{"seite":"oekosystem.html","titel":"Pyomo: die algebraische Denkweise","anker":"pyomo-die-algebraische-denkweise","text":"Pyomo ist im deutschsprachigen Raum der De-facto-Standard für große LP- und MILP-Modelle in Energiewirtschaft, Chemie und Logistik. Sein Kennzeichen: Es denkt in Mengen und Indizes"},{"seite":"oekosystem.html","titel":"Linopy: eine Zeile, zehntausend Nebenbedingungen","anker":"linopy-eine-zeile-zehntausend-nebenbedingungen","text":"Linopy verfolgt einen anderen Ansatz: Variablen sind beschriftete Arrays (xarray), keine indizierten Einzelobjekte. Damit wird aus"},{"seite":"oekosystem.html","titel":"Die Schichten im Überblick","anker":"die-schichten-im-überblick","text":""},{"seite":"oekosystem.html","titel":"3.8 Wo die Zeit wirklich hingeht: vektorisierte Modellgenerierung","anker":"sec:oekosystem-vektorisierung","text":"Eine der hartnäckigsten Fehlannahmen in Optimierungsprojekten lautet: „Wenn es zu langsam ist, brauchen wir einen besseren Solver.“ Messen Sie erst — oft stimmt das nicht."},{"seite":"oekosystem.html","titel":"Vier Stufen an einem Transportproblem","anker":"vier-stufen-an-einem-transportproblem","text":"Wir bauen dasselbe Transportproblem (m Werke, n Kunden, m \\cdot n Variablen) auf vier Arten auf:"},{"seite":"oekosystem.html","titel":"3.9 Übungsaufgaben","anker":"sec:oekosystem-uebungsaufgaben","text":""},{"seite":"oekosystem.html","titel":"3.10 Finde den Denkfehler","anker":"sec:oekosystem-denkfehler","text":""},{"seite":"oekosystem.html","titel":"3.11 Micro-Quiz","anker":"sec:oekosystem-quiz","text":""},{"seite":"oekosystem.html","titel":"3.12 Selbsttest","anker":"sec:oekosystem-selbsttest","text":""},{"seite":"oekosystem.html","titel":"3.13 Zusammenfassung","anker":"sec:oekosystem-zusammenfassung","text":""},{"seite":"modellierung.html","titel":"Kapitel 4: Vom Management-Wunsch zum Modell","anker":null,"text":""},{"seite":"modellierung.html","titel":"4.1 In 5 Minuten gelöst","anker":"sec:modellierung-schnellstart","text":""},{"seite":"modellierung.html","titel":"4.2 Lernziele","anker":"sec:modellierung-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"modellierung.html","titel":"4.3 Ein Satz ist noch kein Modell","anker":"sec:modellierung-vier-fragen","text":"Was aus einer Besprechung mitkommt, klingt meist so:"},{"seite":"modellierung.html","titel":"4.4 Derselbe Datensatz, fünf Modelle","anker":"sec:modellierung-fuenf-modelle","text":"Das Programm dieses Kapitels arbeitet die vier Fragen an einer Auftragsannahme ab: 14 Anfragen verlangen 800 Maschinenstunden, verfügbar sind 300."},{"seite":"modellierung.html","titel":"Teil 2: Ein Satz, drei Lesarten","anker":"teil-2-ein-satz-drei-lesarten","text":"„Stammkunden dürfen wir nicht verlieren.” Jeder im Raum nickt. Niemand merkt, dass drei verschiedene Modelle gemeint sein können:"},{"seite":"modellierung.html","titel":"Teil 3: Hart oder weich","anker":"teil-3-hart-oder-weich","text":"Dieselbe Regel als Strafkosten je abgelehntem Stammkundenauftrag:"},{"seite":"modellierung.html","titel":"Teil 4: Ein Quartal später","anker":"teil-4-ein-quartal-später","text":"Die harte Lesart A wurde eingebaut, alles lief drei Monate lang. Dann fragt Weber einen Auftrag über 320 Maschinenstunden an — mehr, als der ganze Zeitraum hergibt."},{"seite":"modellierung.html","titel":"4.5 Der Gesprächsleitfaden","anker":"sec:modellierung-leitfaden","text":"Was aus den vier Teilen als Handwerkszeug bleibt — Fragen, die man in der ersten Besprechung stellt, bevor eine Zeile Code entsteht:"},{"seite":"modellierung.html","titel":"4.6 Deutsch — OR: ein Übersetzungslexikon","anker":"sec:modellierung-glossar","text":"Die zwölf Fragen liefern Sätze. Sätze sind noch kein Modell — aber die meisten von ihnen haben eine Standardübersetzung, und wer sie kennt, spart sich das Nachdenken für die Fälle,"},{"seite":"modellierung.html","titel":"Fünf Wendungen, bei denen die Übersetzung eine Entscheidung erzwingt","anker":"fünf-wendungen-bei-denen-die-übersetzung-eine-entscheidung-erzwingt","text":"Die Tabelle oben tut so, als sei die Zuordnung eindeutig. Bei den folgenden fünf ist sie es nicht — und das Nachfragen ist die eigentliche Modellierungsarbeit:"},{"seite":"modellierung.html","titel":"Und die Gegenrichtung: OR — Deutsch","anker":"und-die-gegenrichtung-or-deutsch","text":"Dieselbe Barriere gibt es rückwärts. Diese Sätze haben sich bewährt, wenn ein Ergebnis jemandem erklärt werden muss, der das Modell nicht kennt:"},{"seite":"modellierung.html","titel":"4.7 Übungsaufgaben","anker":"sec:modellierung-uebungsaufgaben","text":""},{"seite":"modellierung.html","titel":"4.8 Finde den Denkfehler","anker":"sec:modellierung-denkfehler","text":""},{"seite":"modellierung.html","titel":"4.9 Micro-Quiz","anker":"sec:modellierung-quiz","text":""},{"seite":"modellierung.html","titel":"4.10 Selbsttest","anker":"sec:modellierung-selbsttest","text":""},{"seite":"modellierung.html","titel":"4.11 Zusammenfassung","anker":"sec:modellierung-zusammenfassung","text":""},{"seite":"synthese-grundlagen.html","titel":"Synthese Teil I","anker":null,"text":""},{"seite":"synthese-grundlagen.html","titel":"Was welches Kapitel klärt","anker":"was-welches-kapitel-klärt","text":""},{"seite":"synthese-grundlagen.html","titel":"Die Reihenfolge ist die Aussage","anker":"die-reihenfolge-ist-die-aussage","text":"Dieser Teil steht bewusst vor den Verfahren. Die drei häufigsten Gründe, aus denen ein OR-Projekt scheitert, liegen alle hier — und keiner davon ist ein Solverproblem:"},{"seite":"synthese-grundlagen.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"lp.html","titel":"Kapitel 5: Lineare Programmierung — Simplex, Dualität und Schattenpreise","anker":null,"text":""},{"seite":"lp.html","titel":"5.1 In 5 Minuten gelöst","anker":"sec:lp-schnellstart","text":"Bisher hat ein Solver Ihnen gesagt, was Sie tun sollen. Jetzt sagt er Ihnen zusätzlich, was eine zusätzliche Stunde wert wäre — und das ist die Zahl, für die Sie im Betrieb gehört "},{"seite":"lp.html","titel":"5.2 Lernziele","anker":"sec:lp-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"lp.html","titel":"5.3 Die Standardform und Schlupfvariablen","anker":"sec:lp-die-standardform-und-schlupfvariablen","text":"Lineare Programme zeichnen sich dadurch aus, dass Zielfunktion und alle Nebenbedingungen strikt linear sind — keine Produkte von Variablen, keine Quadrate, keine Logarithmen."},{"seite":"lp.html","titel":"5.4 Der Simplex-Algorithmus Schritt für Schritt","anker":"sec:lp-der-simplex-algorithmus-schritt-fuer-schritt","text":"Der von George Dantzig 1947 formulierte Simplex-Algorithmus nutzt den Fundamentalsatz aus Kapitel 2: Das Optimum liegt in einer Ecke. Statt alle Ecken aufzuzählen, wandert er von E"},{"seite":"lp.html","titel":"Der Ablauf","anker":"der-ablauf","text":""},{"seite":"lp.html","titel":"5.5 Das Simplex-Tableau in Python","anker":"sec:lp-das-simplex-tableau-in-python","text":""},{"seite":"lp.html","titel":"5.6 Dualität und Schattenpreise","anker":"sec:lp-dualitaet-und-schattenpreise","text":"Zu jedem linearen Optimierungsproblem (dem primalen Problem) existiert ein spiegelbildliches Zwillingsproblem: das duale Problem."},{"seite":"lp.html","titel":"Der starke Dualitätssatz","anker":"der-starke-dualitätssatz","text":""},{"seite":"lp.html","titel":"Der Schattenpreis als Ableitung","anker":"der-schattenpreis-als-ableitung","text":"Der Dualwert y_i^* ist die Grenzproduktivität der Ressource i:"},{"seite":"lp.html","titel":"5.7 Die Vorzeichenfalle bei Schattenpreisen","anker":"sec:lp-die-vorzeichenfalle-bei-schattenpreisen","text":"Diese Falle sollten Sie sich merken, weil sie in jedem Projekt wieder auftaucht."},{"seite":"lp.html","titel":"5.8 Praxisfall: Sensitivitätsanalyse mit korrekten Schattenpreisen","anker":"sec:lp-praxisfall-sensitivitaetsanalyse-mit-korrekten-schattenpreisen","text":"Szenario. Ein Fertigungsbetrieb stellt drei Produkte her und will wissen:"},{"seite":"lp.html","titel":"5.9 Wann Schattenpreise lügen: Entartung und Toleranzen","anker":"sec:lp-entartung","text":"Der vorige Abschnitt hat gezeigt, wie wertvoll Schattenpreise sind. Dieser zeigt die zwei Fälle, in denen sie eine Entscheidung nicht tragen — und wie man beide erkennt, bevor jema"},{"seite":"lp.html","titel":"Fall 1: Entartung","anker":"fall-1-entartung","text":"Erinnern Sie sich an Abschnitt 2.4: In zwei Dimensionen legen zwei sich schneidende Geraden eine Ecke fest, in drei Dimensionen drei Ebenen, allgemein n Restriktionen bei n Variabl"},{"seite":"lp.html","titel":"Fall 2: Toleranzen","anker":"fall-2-toleranzen","text":"Der zweite Fall ist unscheinbarer und deshalb häufiger. Wie stellt man fest, ob eine Ressource ausgelastet ist? Naheliegend wäre if schlupf == 0. Genau das ist falsch."},{"seite":"lp.html","titel":"Die ehrliche Auskunft: Schattenpreis-Spannen","anker":"die-ehrliche-auskunft-schattenpreis-spannen","text":"Was tut man also, wenn das Modell entartet ist? Man meldet keinen Einzelwert, sondern die Spanne. Die Menge aller optimalen Dualvektoren ist selbst ein Polyeder:"},{"seite":"lp.html","titel":"5.10 Übungsaufgaben","anker":"sec:lp-uebungsaufgaben","text":""},{"seite":"lp.html","titel":"5.11 Finde den Denkfehler","anker":"sec:lp-denkfehler","text":""},{"seite":"lp.html","titel":"5.12 Micro-Quiz","anker":"sec:lp-quiz","text":""},{"seite":"lp.html","titel":"5.13 Selbsttest","anker":"sec:lp-selbsttest","text":""},{"seite":"lp.html","titel":"5.14 Zusammenfassung","anker":"sec:lp-zusammenfassung","text":""},{"seite":"milp.html","titel":"Kapitel 6: Gemischt-ganzzahlige Optimierung — Diskrete Entscheidungen und Branch-and-Bound","anker":null,"text":""},{"seite":"milp.html","titel":"6.1 In 5 Minuten gelöst","anker":"sec:milp-schnellstart","text":""},{"seite":"milp.html","titel":"6.2 Lernziele","anker":"sec:milp-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"milp.html","titel":"6.3 Warum Runden fundamental scheitert","anker":"sec:milp-warum-runden-fundamental-scheitert","text":"In der realen Welt sind viele Entscheidungen nicht teilbar. Man kann nicht 0,47 Flugzeuge kaufen, keine halbe Lagerhalle bauen, keinen Mitarbeiter zu 38 % einstellen. Noch wichtige"},{"seite":"milp.html","titel":"6.4 Branch-and-Bound","anker":"sec:milp-branch-and-bound","text":"MILP-Probleme sind NP-schwer. Der Standardansatz moderner Solver (HiGHS, SCIP, Gurobi) heißt Branch-and-Cut — Branch-and-Bound plus Schnittebenen."},{"seite":"milp.html","titel":"Die drei Phasen","anker":"die-drei-phasen","text":""},{"seite":"milp.html","titel":"6.5 Modellierungstricks: Big-M und logische Bedingungen","anker":"sec:milp-modellierungstricks-big-m-und-logische-bedingungen","text":"Hier kommt das Handwerkszeug, das MILP so mächtig macht: Man übersetzt Geschäftsregeln in lineare Ungleichungen — mithilfe binärer Hilfsvariablen y \\in \\{0,1\\} und einer hinreichen"},{"seite":"milp.html","titel":"Muster 1 — Fixkosten / Aktivierungsschalter","anker":"muster-1-fixkosten-aktivierungsschalter","text":"Regel: Wird Maschine j genutzt (x_j > 0), fallen Rüstkosten F_j an."},{"seite":"milp.html","titel":"Muster 2 — Entweder-Oder (disjunctive constraints)","anker":"muster-2-entweder-oder-disjunctive-constraints","text":"Regel: Es muss entweder f(\\mathbf{x}) \\le b_1 oder g(\\mathbf{x}) \\le b_2 gelten."},{"seite":"milp.html","titel":"Muster 3 — Wenn-Dann (Implikation)","anker":"muster-3-wenn-dann-implikation","text":"Regel: Wenn y_1 = 1, dann muss auch y_2 = 1 sein."},{"seite":"milp.html","titel":"Muster 4 — Kardinalität („höchstens K aus N“)","anker":"muster-4-kardinalität-höchstens-k-aus-n","text":"\\sum_{j=1}^N y_j \\le K"},{"seite":"milp.html","titel":"Muster 5 — Semikontinuierlich („entweder 0 oder mindestens L“)","anker":"muster-5-semikontinuierlich-entweder-0-oder-mindestens-l","text":"Regel: Eine Position ist entweder gar nicht besetzt oder mit mindestens L Euro."},{"seite":"milp.html","titel":"6.6 Beispiel: Das Rucksackproblem","anker":"sec:milp-beispiel-das-rucksackproblem","text":"Bevor wir zum Portfolio kommen, das klassische Einstiegsproblem — kurz, verständlich und überall wiederzuerkennen."},{"seite":"milp.html","titel":"6.7 Praxisfall: Portfolio mit Ordergebühren und Kardinalitätsgrenze","anker":"sec:milp-praxisfall-portfolio-mit-ordergebuehren-und-kardinalitaetsgrenze","text":"Szenario. Ein Investor verteilt 100\\,000\\,\\text{€} auf sechs Anlageklassen."},{"seite":"milp.html","titel":"6.8 Wenn der Solver nicht fertig wird: Gap, Zeitlimit und Warm-Start","anker":"sec:milp-gap","text":"Bei einem LP gibt es zwei Ausgänge: eine optimale Lösung oder eine klare Absage. Bei einem MILP gibt es einen dritten, und im Betrieb ist er der häufigste:"},{"seite":"milp.html","titel":"Die zwei Zahlen, die zählen","anker":"die-zwei-zahlen-die-zählen","text":"Branch-and-Bound führt zu jedem Zeitpunkt zwei Werte mit:"},{"seite":"milp.html","titel":"Alle Statusfälle behandeln","anker":"alle-statusfälle-behandeln","text":"Der zweite Teil der Professionalität ist unspektakulär, aber entscheidend: jeden Rückgabewert auswerten, nicht nur OPTIMAL."},{"seite":"milp.html","titel":"Warm-Starts: was sie können und was nicht","anker":"warm-starts-was-sie-können-und-was-nicht","text":"Ein Warm-Start gibt dem Solver eine bekannte Lösung als Startpunkt mit. Die Idee ist verlockend: Wer schon eine brauchbare Lösung hat, muss nicht bei null anfangen."},{"seite":"milp.html","titel":"6.9 Übungsaufgaben","anker":"sec:milp-uebungsaufgaben","text":""},{"seite":"milp.html","titel":"6.10 Finde den Denkfehler","anker":"sec:milp-denkfehler","text":"Die Warnung „M so klein wie möglich“ wird meist mit der Laufzeit begründet: schwache Relaxation, mehr Knoten. Das stimmt — und ist die harmlosere Hälfte der Wahrheit."},{"seite":"milp.html","titel":"6.11 Micro-Quiz","anker":"sec:milp-quiz","text":""},{"seite":"milp.html","titel":"6.12 Selbsttest","anker":"sec:milp-selbsttest","text":""},{"seite":"milp.html","titel":"6.13 Zusammenfassung","anker":"sec:milp-zusammenfassung","text":""},{"seite":"cpsat.html","titel":"Kapitel 7: Constraint Programming mit CP-SAT — Logik, Scheduling und Zuweisung","anker":null,"text":""},{"seite":"cpsat.html","titel":"7.1 In 5 Minuten gelöst","anker":"sec:cpsat-schnellstart","text":""},{"seite":"cpsat.html","titel":"7.2 Lernziele","anker":"sec:cpsat-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"cpsat.html","titel":"7.3 Ein anderes Denkmodell","anker":"sec:cpsat-ein-anderes-denkmodell","text":"Während LP und MILP auf algebraischen Gleichungen und Simplex-Matrizen beruhen, kommt Constraint Programming (CP) aus der künstlichen Intelligenz:"},{"seite":"cpsat.html","titel":"Was Propagation leistet","anker":"was-propagation-leistet","text":""},{"seite":"cpsat.html","titel":"7.4 Globale Constraints — die Bausteine von CP-SAT","anker":"sec:cpsat-globale-constraints-die-bausteine-von-cp","text":"CP-SAT stellt mächtige Makros bereit, die in MILP hunderte Big-M-Ungleichungen erfordern würden. Jedes davon hat einen spezialisierten, hocheffizienten Propagator."},{"seite":"cpsat.html","titel":"7.5 Praxisfall: Dynamisches Vertretungssystem","anker":"sec:cpsat-praxisfall-dynamisches-vertretungssystem","text":"Problemstellung. Eine Schule muss nach spontanen Ausfällen vier Unterrichtsstunden nachbesetzen."},{"seite":"cpsat.html","titel":"7.6 Intervallvariablen: Job-Shop-Scheduling","anker":"sec:cpsat-intervallvariablen-job-shop-scheduling","text":"Die Königsdisziplin von CP-SAT sind Zeitplanungsprobleme. Intervallvariablen sind dabei das zentrale Werkzeug."},{"seite":"cpsat.html","titel":"7.7 Parallele Suche: was num_workers wirklich bewirkt","anker":"sec:cpsat-parallele-suche","text":"An mehreren Stellen dieses Buchs steht loeser.parameters.num_workers = 1, mit dem Kommentar „für eine reproduzierbare Ausgabe“. Darin stecken zwei Behauptungen: dass parallele Such"},{"seite":"cpsat.html","titel":"Was die Messung zeigt","anker":"was-die-messung-zeigt","text":"Erstens: Die Beschleunigung ist überlinear. Acht Arbeiter sind im abgedruckten Lauf nicht achtmal, sondern gut zwölfmal schneller als einer. Das sieht nach Messfehler aus, ist aber"},{"seite":"cpsat.html","titel":"Was daraus für Tests folgt","anker":"was-daraus-für-tests-folgt","text":"Der Zielwert war in allen sechzehn Läufen derselbe: 183. Die Gestalt der Lösung war es nicht. Genau daran entscheidet sich, was ein Test prüfen darf:"},{"seite":"cpsat.html","titel":"7.8 Die fünf Antworten von CP-SAT","anker":"sec:cpsat-statusfaelle","text":"Abschnitt 6.8 hat gezeigt, warum OPTIMAL bei ganzzahligen Problemen nicht der Normalfall ist. Bei CP-SAT kommt eine Besonderheit hinzu: Es gibt fünf verschiedene Antworten, und dre"},{"seite":"cpsat.html","titel":"7.9 Übungsaufgaben","anker":"sec:cpsat-uebungsaufgaben","text":""},{"seite":"cpsat.html","titel":"7.10 Finde den Denkfehler","anker":"sec:cpsat-denkfehler","text":""},{"seite":"cpsat.html","titel":"7.11 Micro-Quiz","anker":"sec:cpsat-quiz","text":""},{"seite":"cpsat.html","titel":"7.12 Selbsttest","anker":"sec:cpsat-selbsttest","text":""},{"seite":"cpsat.html","titel":"7.13 Zusammenfassung","anker":"sec:cpsat-zusammenfassung","text":""},{"seite":"graphen.html","titel":"Kapitel 8: Graphen, Flüsse und Touren — Min-Cost-Flow, Matching und VRP","anker":null,"text":""},{"seite":"graphen.html","titel":"8.1 In 5 Minuten gelöst","anker":"sec:graphen-schnellstart","text":""},{"seite":"graphen.html","titel":"8.2 Lernziele","anker":"sec:graphen-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"graphen.html","titel":"8.3 Graphen als Modellsprache","anker":"sec:graphen-graphen-als-modellsprache","text":"Viele reale Probleme in Logistik, Kommunikation und Finanzströmen sind keine flachen Ungleichungssysteme, sondern Graphen G = (V, E):"},{"seite":"graphen.html","titel":"Das Minimum-Cost-Flow-Problem (MCNFP)","anker":"das-minimum-cost-flow-problem-mcnfp","text":"Minimum-Cost Network Flow Problem — deutsch: kostenminimales Flussproblem. Es ist das mathematische Fundament für Transportketten, Liquiditätsrouting und Datenverteilung."},{"seite":"graphen.html","titel":"8.4 Bipartites Matching: das Zuordnungsproblem","anker":"sec:graphen-bipartites-matching-das-zuordnungsproblem","text":"Wenn N Aufgaben auf N Ressourcen eins zu eins verteilt werden — Orders auf Broker, Schichten auf Mitarbeitende, Aufträge auf Maschinen — spricht man von bipartitem Matching."},{"seite":"graphen.html","titel":"Der Satz von Birkhoff und von Neumann","anker":"der-satz-von-birkhoff-und-von-neumann","text":""},{"seite":"graphen.html","titel":"8.5 Das Vehicle Routing Problem mit Zeitfenstern","anker":"sec:graphen-das-vehicle-routing-problem-mit-zeitfenstern","text":"Das Traveling Salesperson Problem (TSP), deutsch Problem des Handlungsreisenden, fragt nach der kürzesten Rundreise durch N Städte. Das Capacitated Vehicle Routing Problem with Tim"},{"seite":"graphen.html","titel":"Kurzzyklen verhindern","anker":"kurzzyklen-verhindern","text":"Ein naives Modell erlaubt Subtouren: isolierte Kreise, die das Depot nie anfahren. Die klassische Gegenmaßnahme ist die MTZ-Formulierung nach Miller, Tucker und Zemlin. Man führt R"},{"seite":"graphen.html","titel":"Praxisbeispiel: Flotten-Routing","anker":"praxisbeispiel-flotten-routing","text":""},{"seite":"graphen.html","titel":"8.6 Übungsaufgaben","anker":"sec:graphen-uebungsaufgaben","text":""},{"seite":"graphen.html","titel":"8.7 Finde den Denkfehler","anker":"sec:graphen-denkfehler","text":""},{"seite":"graphen.html","titel":"8.8 Micro-Quiz","anker":"sec:graphen-quiz","text":""},{"seite":"graphen.html","titel":"8.9 Selbsttest","anker":"sec:graphen-selbsttest","text":""},{"seite":"graphen.html","titel":"8.10 Zusammenfassung","anker":"sec:graphen-zusammenfassung","text":""},{"seite":"metaheuristiken.html","titel":"Kapitel 9: Metaheuristiken — wenn der exakte Solver aussteigt","anker":null,"text":""},{"seite":"metaheuristiken.html","titel":"9.1 In 5 Minuten gelöst","anker":"sec:metaheuristiken-schnellstart","text":""},{"seite":"metaheuristiken.html","titel":"9.2 Lernziele","anker":"sec:metaheuristiken-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"metaheuristiken.html","titel":"9.3 Die Aufgabe: Rüstzeiten an der Lackieranlage","anker":"sec:metaheuristiken-aufgabe","text":"Der Schnellstart war ein Spielzeug. Die Aufgabe dieses Kapitels ist dieselbe, nur in Betriebsgröße: n Aufträge in eine Reihenfolge bringen, so dass die Summe der Rüstzeiten minimal"},{"seite":"metaheuristiken.html","titel":"Die Instanz","anker":"die-instanz","text":"Alle Programme dieses Kapitels benutzen dieselbe Aufgabe. Die Rüstzeit setzt sich aus zwei Teilen zusammen: einem unregelmäßigen Reinigungsaufwand zwischen den Produktfamilien und "},{"seite":"metaheuristiken.html","titel":"9.4 Lokale Suche: der Zug und seine Kosten","anker":"sec:metaheuristiken-lokale-suche","text":"Eine lokale Suche braucht drei Dinge: eine Startlösung, einen Zug und eine Regel, welche Züge übernommen werden."},{"seite":"metaheuristiken.html","titel":"9.5 Simulated Annealing","anker":"sec:metaheuristiken-annealing","text":"Reines Bergsteigen — nur Verbesserungen annehmen — bleibt im ersten lokalen Optimum stehen. Simulated Annealing nimmt Verschlechterungen mit einer Wahrscheinlichkeit an, die von de"},{"seite":"metaheuristiken.html","titel":"Was die Messung zeigt — und was sie nicht zeigt","anker":"was-die-messung-zeigt-und-was-sie-nicht-zeigt","text":"Erstens: Der Beitrag des Annealings ist bescheiden. Bergsteigen kommt auf 917 Minuten, Annealing auf 907 — das simple Verfahren holt 93 % des Ertrags. Das ist kein Argument gegen A"},{"seite":"metaheuristiken.html","titel":"9.6 Ab wann lohnt es sich?","anker":"sec:metaheuristiken-umschlagpunkt","text":"„Kleine Probleme exakt, große mit Metaheuristiken“ ist richtig und nutzlos, solange niemand sagt, wo groß anfängt. Diese Zahl lässt sich messen."},{"seite":"metaheuristiken.html","titel":"Die Spalte, die man nicht weglassen darf","anker":"die-spalte-die-man-nicht-weglassen-darf","text":"Bei 500 Aufträgen haben wir die CP-SAT-Lösung verworfen. Seine Schranke ist trotzdem das Wertvollste in der ganzen Tabelle."},{"seite":"metaheuristiken.html","titel":"9.7 Large Neighborhood Search","anker":"sec:metaheuristiken-lns","text":"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 j"},{"seite":"metaheuristiken.html","titel":"Das Fenster ist die eine Stellschraube","anker":"das-fenster-ist-die-eine-stellschraube","text":""},{"seite":"metaheuristiken.html","titel":"Das Gesamtbild","anker":"das-gesamtbild","text":""},{"seite":"metaheuristiken.html","titel":"9.8 Was dieses Kapitel nicht behandelt","anker":"sec:metaheuristiken-abgrenzung","text":"Damit die Landkarte vollständig ist — drei Verfahren, die in dieselbe Familie gehören und hier bewusst nur benannt werden:"},{"seite":"metaheuristiken.html","titel":"9.9 Übungsaufgaben","anker":"sec:metaheuristiken-uebungsaufgaben","text":""},{"seite":"metaheuristiken.html","titel":"9.10 Finde den Denkfehler","anker":"sec:metaheuristiken-denkfehler","text":""},{"seite":"metaheuristiken.html","titel":"9.11 Micro-Quiz","anker":"sec:metaheuristiken-quiz","text":""},{"seite":"metaheuristiken.html","titel":"9.12 Selbsttest","anker":"sec:metaheuristiken-selbsttest","text":""},{"seite":"metaheuristiken.html","titel":"9.13 Zusammenfassung","anker":"sec:metaheuristiken-zusammenfassung","text":""},{"seite":"dekomposition.html","titel":"Kapitel 10: Spaltengenerierung — das Modell umbauen statt die Lösung raten","anker":null,"text":""},{"seite":"dekomposition.html","titel":"10.1 In 5 Minuten gelöst","anker":"sec:dekomposition-schnellstart","text":""},{"seite":"dekomposition.html","titel":"10.2 Lernziele","anker":"sec:dekomposition-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"dekomposition.html","titel":"10.3 Warum das naheliegende Modell scheitert","anker":"sec:dekomposition-symmetrie","text":"Der erste Entwurf eines Zuschnittmodells sieht fast immer so aus: eine Binärvariable z_{jr} für „Stück j liegt auf Rolle r“, dazu y_r für „Rolle r wird benutzt”."},{"seite":"dekomposition.html","titel":"10.4 Rechnen mit Mustern, ohne sie aufzuschreiben","anker":"sec:dekomposition-schleife","text":"Die Idee ist alt (Gilmore und Gomory, 1961) und in einem Satz gesagt:"},{"seite":"dekomposition.html","titel":"10.5 Das Programm","anker":"sec:dekomposition-programm","text":""},{"seite":"dekomposition.html","titel":"10.6 Was die Zahlen zeigen","anker":"sec:dekomposition-befund","text":""},{"seite":"dekomposition.html","titel":"Die Musterzahl explodiert, der Bedarf nicht","anker":"die-musterzahl-explodiert-der-bedarf-nicht","text":""},{"seite":"dekomposition.html","titel":"Der unbequeme Teil: Es lohnt sich nicht immer","anker":"der-unbequeme-teil-es-lohnt-sich-nicht-immer","text":""},{"seite":"dekomposition.html","titel":"10.7 Übungsaufgaben","anker":"sec:dekomposition-uebungsaufgaben","text":""},{"seite":"dekomposition.html","titel":"10.8 Finde den Denkfehler","anker":"sec:dekomposition-denkfehler","text":""},{"seite":"dekomposition.html","titel":"10.9 Micro-Quiz","anker":"sec:dekomposition-quiz","text":""},{"seite":"dekomposition.html","titel":"10.10 Selbsttest","anker":"sec:dekomposition-selbsttest","text":""},{"seite":"dekomposition.html","titel":"10.11 Zusammenfassung","anker":"sec:dekomposition-zusammenfassung","text":""},{"seite":"synthese-kernverfahren.html","titel":"Synthese Teil II","anker":null,"text":""},{"seite":"synthese-kernverfahren.html","titel":"Die Entscheidungsmatrix","anker":"die-entscheidungsmatrix","text":""},{"seite":"synthese-kernverfahren.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-kernverfahren.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-kernverfahren.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"qp-nlp.html","titel":"Kapitel 11: Quadratische und nichtlineare Optimierung — KKT, Lagrange, Konvexität","anker":null,"text":""},{"seite":"qp-nlp.html","titel":"11.1 In 5 Minuten gelöst","anker":"sec:qp-nlp-schnellstart","text":""},{"seite":"qp-nlp.html","titel":"11.2 Lernziele","anker":"sec:qp-nlp-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"qp-nlp.html","titel":"Auffrischung: Gradient in einer Minute","anker":"auffrischung-gradient-in-einer-minute","text":"Der Gradient \\nabla f(\\mathbf{x}) ist der Vektor aller partiellen Ableitungen:"},{"seite":"qp-nlp.html","titel":"11.3 Das quadratische Programm (QP)","anker":"sec:qp-nlp-das-quadratische-programm-qp","text":"Ein quadratisches Programm hat eine quadratische Zielfunktion und lineare Nebenbedingungen:"},{"seite":"qp-nlp.html","titel":"Konvexität: die präzise Aussage","anker":"konvexität-die-präzise-aussage","text":"Eine verbreitete, aber zu stark formulierte Aussage lautet: „Wenn \\mathbf{P} positiv semi-definit ist, ist das QP streng konvex; es existiert ein eindeutiges globales Minimum.“ Kor"},{"seite":"qp-nlp.html","titel":"11.4 Die Karush-Kuhn-Tucker-Bedingungen","anker":"sec:qp-nlp-die-karush-kuhn-tucker-bedingungen","text":"Die KKT-Bedingungen verallgemeinern den Lagrange-Ansatz auf Probleme mit Ungleichungen. Sie sind notwendig für ein Optimum — und bei konvexen Problemen auch hinreichend."},{"seite":"qp-nlp.html","titel":"Die vier KKT-Bedingungen","anker":"die-vier-kkt-bedingungen","text":"Am Optimum (\\mathbf{x}^*, \\boldsymbol{\\lambda}^*, \\boldsymbol{\\nu}^*) gilt:"},{"seite":"qp-nlp.html","titel":"11.5 Nichtlineare Optimierung mit scipy.optimize.minimize","anker":"sec:qp-nlp-nichtlineare-optimierung-mit-scipy-optimize-minimize","text":"Wenn Zielfunktion oder Nebenbedingungen weder linear noch quadratisch sind — Logarithmen, Wurzeln, Exponentialfunktionen — nutzt man gradientenbasierte Verfahren wie SLSQP (Sequent"},{"seite":"qp-nlp.html","titel":"Praxisfall: Entropie-maximierte Kapitalallokation","anker":"praxisfall-entropie-maximierte-kapitalallokation","text":"Wir optimieren ein Portfolio nicht nur nach Varianz, sondern maximieren zusätzlich die Shannon-Entropie der Gewichte, um Klumpenrisiken glatt zu bestrafen:"},{"seite":"qp-nlp.html","titel":"11.6 Jenseits der Konvexität: lokale Optima, Multistart und MINLP","anker":"sec:qp-nlp-nichtkonvex","text":"Alles bisher in diesem Kapitel stand unter einer Bedingung: Konvexität. Sie ist der Grund, warum CVXPY eine Optimalitätsgarantie geben kann und warum die KKT-Bedingungen nicht nur "},{"seite":"qp-nlp.html","titel":"Woher Nicht-Konvexität im Alltag kommt","anker":"woher-nicht-konvexität-im-alltag-kommt","text":"Nicht aus exotischer Mathematik, sondern aus ganz gewöhnlichen betriebswirtschaftlichen Effekten:"},{"seite":"qp-nlp.html","titel":"Was ein lokales Optimum praktisch bedeutet","anker":"was-ein-lokales-optimum-praktisch-bedeutet","text":"scipy.optimize.minimize verweigert nichts. Es rechnet, meldet success: True und liefert eine Zahl. Diese Meldung heißt aber nicht „das ist das Optimum“, sondern nur:"},{"seite":"qp-nlp.html","titel":"Die Zahlen im Klartext","anker":"die-zahlen-im-klartext","text":""},{"seite":"qp-nlp.html","titel":"Ausblick: MINLP und globale Solver","anker":"ausblick-minlp-und-globale-solver","text":"Wird zusätzlich noch ganzzahlig entschieden — „welche Anlage läuft überhaupt“ und „wie stark“ —, entsteht ein MINLP (Mixed-Integer Nonlinear Program), die schwierigste der in diese"},{"seite":"qp-nlp.html","titel":"11.7 Übungsaufgaben","anker":"sec:qp-nlp-uebungsaufgaben","text":""},{"seite":"qp-nlp.html","titel":"11.8 Finde den Denkfehler","anker":"sec:qp-nlp-denkfehler","text":""},{"seite":"qp-nlp.html","titel":"11.9 Micro-Quiz","anker":"sec:qp-nlp-quiz","text":""},{"seite":"qp-nlp.html","titel":"11.10 Selbsttest","anker":"sec:qp-nlp-selbsttest","text":""},{"seite":"qp-nlp.html","titel":"11.11 Zusammenfassung","anker":"sec:qp-nlp-zusammenfassung","text":""},{"seite":"unsicherheit.html","titel":"Kapitel 12: Optimierung unter Unsicherheit — Monte-Carlo, Stochastik, Robustheit","anker":null,"text":""},{"seite":"unsicherheit.html","titel":"12.1 In 5 Minuten gelöst","anker":"sec:unsicherheit-schnellstart","text":""},{"seite":"unsicherheit.html","titel":"12.2 Lernziele","anker":"sec:unsicherheit-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"unsicherheit.html","titel":"12.3 Der Fluch des Durchschnitts","anker":"sec:unsicherheit-der-fluch-des-durchschnitts","text":"Der naheliegende Umgang mit Unsicherheit lautet: „Wir setzen den Erwartungswert ein und rechnen deterministisch.“ Das ist fast immer falsch — und zwar nicht ungenau, sondern system"},{"seite":"unsicherheit.html","titel":"Die vier Ansätze im Überblick","anker":"die-vier-ansätze-im-überblick","text":""},{"seite":"unsicherheit.html","titel":"12.4 Monte-Carlo-Simulation","anker":"sec:unsicherheit-monte-carlo-simulation","text":"Monte-Carlo heißt schlicht: Ziehe sehr viele Zufallsszenarien, werte für jedes den Plan aus, und betrachte die Verteilung der Ergebnisse statt eines einzigen Werts."},{"seite":"unsicherheit.html","titel":"12.5 Zweistufige stochastische Programmierung","anker":"sec:unsicherheit-zweistufige-stochastische-programmierung","text":"Das zweistufige Modell mit Recourse bildet ab, dass Entscheidungen zeitlich gestaffelt sind:"},{"seite":"unsicherheit.html","titel":"12.6 Robuste Optimierung: gegen den Worst Case absichern","anker":"sec:unsicherheit-robuste-optimierung-gegen-den-worst-case","text":"Wenn Wahrscheinlichkeiten unbekannt oder instabil sind — Marktcrashs, Lieferkettenabrisse, Pandemien —, hilft die robuste Optimierung. Sie fragt nicht nach dem Mittel, sondern nach"},{"seite":"unsicherheit.html","titel":"12.7 Wahrscheinlichkeitsbeschränkungen: „mit 95 % Sicherheit“","anker":"sec:unsicherheit-chance-constraints","text":"Die drei bisherigen Ansätze beantworten Fragen, die im Sitzungssaal selten so gestellt werden. „Was ist im Mittel am besten?“ hört ein Vorstand als Ausflucht; „was hält auch im sch"},{"seite":"unsicherheit.html","titel":"Weg 1: Normalverteilung — die Bedingung wird ein Kegel","anker":"weg-1-normalverteilung-die-bedingung-wird-ein-kegel","text":"Ist \\mathbf{a} \\sim \\mathcal{N}(\\hat{\\mathbf{a}}, \\boldsymbol{\\Sigma}), dann ist \\mathbf{a}^\\top\\mathbf{x} für festes \\mathbf{x} selbst normalverteilt, mit Erwartungswert \\hat{\\mat"},{"seite":"unsicherheit.html","titel":"Weg 2: Szenarien — Big-M ohne Verteilungsannahme","anker":"weg-2-szenarien-big-m-ohne-verteilungsannahme","text":"Liegen statt einer Verteilung nur S beobachtete Szenarien vor, bekommt jedes eine Binärvariable z_s, die sagt, ob es verletzt werden darf:"},{"seite":"unsicherheit.html","titel":"Der Fall: ein Kraftwerkspark mit 500 MW Zusage","anker":"der-fall-ein-kraftwerkspark-mit-500-mw-zusage","text":""},{"seite":"unsicherheit.html","titel":"12.8 Übungsaufgaben","anker":"sec:unsicherheit-uebungsaufgaben","text":""},{"seite":"unsicherheit.html","titel":"12.9 Finde den Denkfehler","anker":"sec:unsicherheit-denkfehler","text":""},{"seite":"unsicherheit.html","titel":"12.10 Micro-Quiz","anker":"sec:unsicherheit-quiz","text":""},{"seite":"unsicherheit.html","titel":"12.11 Selbsttest","anker":"sec:unsicherheit-selbsttest","text":""},{"seite":"unsicherheit.html","titel":"12.12 Zusammenfassung","anker":"sec:unsicherheit-zusammenfassung","text":""},{"seite":"dynamische-programmierung.html","titel":"Kapitel 13: Dynamische Programmierung — Die Bellman-Gleichung und Order-Execution","anker":null,"text":""},{"seite":"dynamische-programmierung.html","titel":"13.1 In 5 Minuten gelöst","anker":"sec:dynamische-programmierung-schnellstart","text":""},{"seite":"dynamische-programmierung.html","titel":"13.2 Lernziele","anker":"sec:dynamische-programmierung-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"dynamische-programmierung.html","titel":"13.3 Das Bellmansche Optimalitätsprinzip","anker":"sec:dynamische-programmierung-das-bellmansche-optimalitaetsprinzip","text":"Richard Bellman formulierte 1957 das Grundprinzip der Dynamischen Programmierung (DP):"},{"seite":"dynamische-programmierung.html","titel":"Die vier Bausteine eines DP-Modells","anker":"die-vier-bausteine-eines-dp-modells","text":""},{"seite":"dynamische-programmierung.html","titel":"Die Bellman-Gleichung","anker":"die-bellman-gleichung","text":"V_t(S_t) = \\min_{a_t\\in\\mathcal{A}(S_t)}\\Big\\{\\,C(S_t,a_t) \\;+\\; \\gamma\\cdot\\mathbb{E}\\big[V_{t+1}(S_{t+1})\\mid S_t,a_t\\big]\\Big\\}"},{"seite":"dynamische-programmierung.html","titel":"13.4 Das Almgren-Chriss-Problem: optimale Orderausführung","anker":"sec:dynamische-programmierung-das-almgren-chriss-problem-optimale-orderausfuehrung","text":"Ein klassisches OR-Problem an Börsen: Ein institutioneller Händler muss X_0 = 100\\,000 Aktien innerhalb von T Handelsperioden verkaufen."},{"seite":"dynamische-programmierung.html","titel":"13.5 Der Fluch der Dimensionalität","anker":"sec:dynamische-programmierung-der-fluch-der-dimensionalitaet","text":"DP ist mächtig, aber es hat eine harte Grenze. Der Aufwand der Rückwärtsinduktion ist"},{"seite":"dynamische-programmierung.html","titel":"13.6 Übungsaufgaben","anker":"sec:dynamische-programmierung-uebungsaufgaben","text":""},{"seite":"dynamische-programmierung.html","titel":"13.7 Finde den Denkfehler","anker":"sec:dynamische-programmierung-denkfehler","text":"Bei dynamischer Programmierung entscheidet eine einzige Frage über Erfolg oder Misserfolg: Was gehört in den Zustand? Ist er zu klein, rechnet das Verfahren völlig korrekt — nur eb"},{"seite":"dynamische-programmierung.html","titel":"13.8 Micro-Quiz","anker":"sec:dynamische-programmierung-quiz","text":""},{"seite":"dynamische-programmierung.html","titel":"13.9 Selbsttest","anker":"sec:dynamische-programmierung-selbsttest","text":""},{"seite":"dynamische-programmierung.html","titel":"13.10 Zusammenfassung","anker":"sec:dynamische-programmierung-zusammenfassung","text":""},{"seite":"mehrziel.html","titel":"Kapitel 14: Mehrere Ziele — Pareto-Fronten statt Gewichte","anker":null,"text":""},{"seite":"mehrziel.html","titel":"14.1 In 5 Minuten gelöst","anker":"sec:mehrziel-schnellstart","text":""},{"seite":"mehrziel.html","titel":"14.2 Lernziele","anker":"sec:mehrziel-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"mehrziel.html","titel":"14.3 Wann ein Kompromiss gut ist","anker":"sec:mehrziel-dominanz","text":"Bei einem Ziel ist „besser” eindeutig. Bei zwei Zielen nicht mehr: Ein Plan kann billiger und schmutziger sein als ein anderer, und dann ist keiner von beiden besser."},{"seite":"mehrziel.html","titel":"14.4 Der Reflex: alles in ein Ziel rühren","anker":"sec:mehrziel-skalarisierung","text":"Der naheliegende Weg, zwei Ziele zu einem zu machen, ist die gewichtete Summe:"},{"seite":"mehrziel.html","titel":"14.5 Das Programm","anker":"sec:mehrziel-programm","text":"Zwölf Sendungen, drei Verkehrsträger, fünf freie Bahntrassen. Der Zielkonflikt entsteht nicht zwischen den Trägern — die Bahn ist immer billiger und sauberer als der LKW —, sondern"},{"seite":"mehrziel.html","titel":"14.6 Was die gewichtete Summe nicht sieht","anker":"sec:mehrziel-luecke","text":"Die Front hat zehn Punkte. Ein Raster aus 1 401 Gewichten findet sechs davon. Vier Kompromisse sind für kein Gewicht erreichbar — und das ist keine Frage der Rasterweite."},{"seite":"mehrziel.html","titel":"Das Gewicht ist keine Feineinstellung","anker":"das-gewicht-ist-keine-feineinstellung","text":"Die zweite Beobachtung aus derselben Tabelle: 1 401 Gewichte erzeugen sechs verschiedene Pläne. Weite Gewichtsbereiche liefern dasselbe Ergebnis, und dazwischen springt es."},{"seite":"mehrziel.html","titel":"14.7 Das ε-Constraint-Verfahren","anker":"sec:mehrziel-epsilon","text":"Der Ausweg ist unspektakulär: Man macht aus dem zweiten Ziel eine Nebenbedingung."},{"seite":"mehrziel.html","titel":"Wenn es eine klare Rangfolge gibt: lexikografisch","anker":"wenn-es-eine-klare-rangfolge-gibt-lexikografisch","text":"Manchmal ist ein Ziel wirklich vorrangig. Dann optimiert man lexikografisch: erst das erste Ziel, dann das zweite unter der Bedingung, dass das erste (fast) erhalten bleibt."},{"seite":"mehrziel.html","titel":"14.8 Wie man die Front vorlegt","anker":"sec:mehrziel-vorlegen","text":"Eine Front mit zehn Punkten ist kein Ergebnis, sondern eine Speisekarte. Damit sie entscheidbar wird, gehört eine Spalte dazu, die im Programm EUR je kg heißt:"},{"seite":"mehrziel.html","titel":"14.9 Übungsaufgaben","anker":"sec:mehrziel-uebungsaufgaben","text":""},{"seite":"mehrziel.html","titel":"14.10 Finde den Denkfehler","anker":"sec:mehrziel-denkfehler","text":""},{"seite":"mehrziel.html","titel":"14.11 Micro-Quiz","anker":"sec:mehrziel-quiz","text":""},{"seite":"mehrziel.html","titel":"14.12 Selbsttest","anker":"sec:mehrziel-selbsttest","text":""},{"seite":"mehrziel.html","titel":"14.13 Zusammenfassung","anker":"sec:mehrziel-zusammenfassung","text":""},{"seite":"prognose.html","titel":"Kapitel 15: Predict-then-Optimize — die bessere Prognose, die schlechtere Entscheidung","anker":null,"text":""},{"seite":"prognose.html","titel":"15.1 In 5 Minuten gelöst","anker":"sec:prognose-schnellstart","text":""},{"seite":"prognose.html","titel":"15.2 Lernziele","anker":"sec:prognose-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"prognose.html","titel":"15.3 Die Naht zwischen zwei Abteilungen","anker":"sec:prognose-naht","text":"In fast jedem Unternehmen sieht der Ablauf so aus:"},{"seite":"prognose.html","titel":"15.4 Das Programm","anker":"sec:prognose-programm","text":"Dieselbe Bäckerei, aber mit Merkmalen: Wochentag, Temperatur, Aktionstage. Die Nachfrage muss jetzt modelliert werden."},{"seite":"prognose.html","titel":"Was Sie in der Abbildung sehen. Links und rechts gewinnt nicht dasselbe Verfahren. Die Punktprognose hat den besten Prognosefehler und die höchsten Kosten — beide Maßstäbe messen etwas anderes, und nur einer davon steht am Ende in der Bilanz.","anker":"was-sie-in-der-abbildung-sehen.-links-und-rechts-gewinnt-nicht-dasselbe-verfahren.-die-punktprognose-hat-den-besten-prognosefehler-und-die-höchsten-kosten-beide-maßstäbe-messen-etwas-anderes-und-nur-einer-davon-steht-am-ende-in-der-bilanz.","text":""},{"seite":"prognose.html","titel":"15.5 Der Befund","anker":"sec:prognose-befund","text":""},{"seite":"prognose.html","titel":"Warum ein pauschaler Zuschlag zu kurz greift","anker":"warum-ein-pauschaler-zuschlag-zu-kurz-greift","text":"Die zweite Zeile der Tabelle ist die verbreitete Praxis: Punktprognose plus Sicherheitsbestand. Sie hilft (−7,3 %), bleibt aber hinter der Quantilregression zurück. Das Programm re"},{"seite":"prognose.html","titel":"15.6 Eine Messfalle, in die der Autor selbst getappt ist","anker":"sec:prognose-messfalle","text":"Der erste Entwurf dieses Programms bewertete auf 230 Testtagen — ein realistischer Zeitraum, gut sieben Monate. Dort hatte die Quantilregression den besseren MSE, und die ganze Aus"},{"seite":"prognose.html","titel":"15.7 Wie weit das Verfahren reicht","anker":"sec:prognose-ausblick","text":"Die dritte Zeile der Ergebnistabelle — „Zuschlag auf Kosten trainiert” — ist die einfachste denkbare Form einer Idee, die derzeit erforscht wird: das Prognosemodell direkt auf die "},{"seite":"prognose.html","titel":"15.8 Übungsaufgaben","anker":"sec:prognose-uebungsaufgaben","text":""},{"seite":"prognose.html","titel":"15.9 Finde den Denkfehler","anker":"sec:prognose-denkfehler","text":""},{"seite":"prognose.html","titel":"15.10 Micro-Quiz","anker":"sec:prognose-quiz","text":""},{"seite":"prognose.html","titel":"15.11 Selbsttest","anker":"sec:prognose-selbsttest","text":""},{"seite":"prognose.html","titel":"15.12 Zusammenfassung","anker":"sec:prognose-zusammenfassung","text":""},{"seite":"synthese-nichtlinear.html","titel":"Synthese Teil III","anker":null,"text":""},{"seite":"synthese-nichtlinear.html","titel":"Welche Annahme fällt weg?","anker":"welche-annahme-fällt-weg","text":""},{"seite":"synthese-nichtlinear.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-nichtlinear.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-nichtlinear.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"bruecke.html","titel":"Kapitel 16: Die Strukturbrücke — dieselbe Mathematik, zwei Welten","anker":null,"text":""},{"seite":"bruecke.html","titel":"16.1 In 5 Minuten gelöst","anker":"sec:bruecke-schnellstart","text":""},{"seite":"bruecke.html","titel":"16.2 Lernziele","anker":"sec:bruecke-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"bruecke.html","titel":"16.3 Das Programm","anker":"sec:bruecke-programm","text":""},{"seite":"bruecke.html","titel":"16.4 Die zwei Brücken im Einzelnen","anker":"sec:bruecke-einzelnen","text":""},{"seite":"bruecke.html","titel":"Erste Brücke: Allokation","anker":"erste-brücke-allokation","text":""},{"seite":"bruecke.html","titel":"Zweite Brücke: Absicherung gegen den schlechtesten Fall","anker":"zweite-brücke-absicherung-gegen-den-schlechtesten-fall","text":"Hier ist die Übereinstimmung noch enger, weil sie nicht nur die Struktur betrifft, sondern die Formel. Die Rockafellar-Uryasev-Formulierung aus Kapitel 20"},{"seite":"bruecke.html","titel":"Wo die Lösungen sich unterscheiden","anker":"wo-die-lösungen-sich-unterscheiden","text":"Der Vergleich fördert nebenbei einen Unterschied zutage, den man nicht erwartet: Die Streuungsgrenze von 40 % bindet nur im Einkauf, nicht im Depot."},{"seite":"bruecke.html","titel":"16.5 Wo die Brücke endet","anker":"sec:bruecke-grenzen","text":"Eine Analogie ist nur so nützlich wie die Grenzen, die man ihr zieht. Drei Dinge wandern nicht mit:"},{"seite":"bruecke.html","titel":"16.6 Übungsaufgaben","anker":"sec:bruecke-uebungsaufgaben","text":""},{"seite":"bruecke.html","titel":"16.7 Finde den Denkfehler","anker":"sec:bruecke-denkfehler","text":""},{"seite":"bruecke.html","titel":"16.8 Micro-Quiz","anker":"sec:bruecke-quiz","text":""},{"seite":"bruecke.html","titel":"16.9 Selbsttest","anker":"sec:bruecke-selbsttest","text":""},{"seite":"bruecke.html","titel":"16.10 Zusammenfassung","anker":"sec:bruecke-zusammenfassung","text":""},{"seite":"supplychain.html","titel":"Kapitel 17: Supply-Chain und Energieeinsatz unter Unsicherheit","anker":null,"text":""},{"seite":"supplychain.html","titel":"17.1 In 5 Minuten gelöst","anker":"sec:supplychain-schnellstart","text":""},{"seite":"supplychain.html","titel":"17.2 Lernziele","anker":"sec:supplychain-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"supplychain.html","titel":"17.3 Die Aufgabe","anker":"sec:supplychain-aufgabe","text":"Fünf Blöcke, 24 Stunden, eine Last zwischen 270 und 804 MW. Dazu Windeinspeisung, die niemand am Vorabend kennt."},{"seite":"supplychain.html","titel":"Die Zeitstruktur der Entscheidung","anker":"die-zeitstruktur-der-entscheidung","text":"Hier geht das Kapitel über Abschnitt 12.5 hinaus:"},{"seite":"supplychain.html","titel":"17.4 Das Programm","anker":"sec:supplychain-programm","text":""},{"seite":"supplychain.html","titel":"17.5 Der Befund","anker":"sec:supplychain-befund","text":""},{"seite":"supplychain.html","titel":"17.6 Was Versorgungssicherheit kostet","anker":"sec:supplychain-sicherheit","text":"Der dritte Plan legt eine CVaR-Schranke auf die nicht gedeckte Energie: Im Mittel der schlechtesten 10 % der Szenarien darf nichts fehlen. Dieselbe Rockafellar-Uryasev-Konstruktion"},{"seite":"supplychain.html","titel":"17.7 Übungsaufgaben","anker":"sec:supplychain-uebungsaufgaben","text":""},{"seite":"supplychain.html","titel":"17.8 Finde den Denkfehler","anker":"sec:supplychain-denkfehler","text":""},{"seite":"supplychain.html","titel":"17.9 Micro-Quiz","anker":"sec:supplychain-quiz","text":""},{"seite":"supplychain.html","titel":"17.10 Selbsttest","anker":"sec:supplychain-selbsttest","text":""},{"seite":"supplychain.html","titel":"17.11 Zusammenfassung","anker":"sec:supplychain-zusammenfassung","text":""},{"seite":"finanzdaten.html","titel":"Kapitel 18: Finanzdaten-Modellierung — Renditen, Kovarianz und Shrinkage","anker":null,"text":""},{"seite":"finanzdaten.html","titel":"18.1 In 5 Minuten gelöst","anker":"sec:finanzdaten-schnellstart","text":""},{"seite":"finanzdaten.html","titel":"18.2 Lernziele","anker":"sec:finanzdaten-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"finanzdaten.html","titel":"18.3 Diskrete und logarithmische Renditen","anker":"sec:finanzdaten-diskrete-und-logarithmische-renditen","text":"Sei P_{i,t} der bereinigte Schlusskurs (adjusted close) von Titel i zum Zeitpunkt t. „Bereinigt“ heißt: um Dividenden und Aktiensplits korrigiert — sonst erscheint jede Dividendenz"},{"seite":"finanzdaten.html","titel":"Diskrete Rendite","anker":"diskrete-rendite","text":"R_{i,t} = \\frac{P_{i,t} - P_{i,t-1}}{P_{i,t-1}} = \\frac{P_{i,t}}{P_{i,t-1}} - 1"},{"seite":"finanzdaten.html","titel":"Logarithmische Rendite","anker":"logarithmische-rendite","text":"r_{i,t} = \\ln\\!\\left(\\frac{P_{i,t}}{P_{i,t-1}}\\right) = \\ln P_{i,t} - \\ln P_{i,t-1}"},{"seite":"finanzdaten.html","titel":"18.4 Das Schätzfehler-Problem","anker":"sec:finanzdaten-das-schaetzfehler-problem","text":"Sei \\mathbf{X}\\in\\mathbb{R}^{T\\times N} die Matrix zentrierter Renditen von N Titeln über T Handelstage. Die Stichproben-Kovarianzmatrix lautet:"},{"seite":"finanzdaten.html","titel":"18.5 Ledoit-Wolf-Shrinkage","anker":"sec:finanzdaten-ledoit-wolf-shrinkage","text":"Olivier Ledoit und Michael Wolf lösten das Dilemma durch lineare Schrumpfung:"},{"seite":"finanzdaten.html","titel":"Welches Ziel \\mathbf{F}?","anker":"welches-ziel-mathbff","text":"Ein häufiges Missverständnis: Es gibt nämlich mehrere Ledoit-Wolf-Varianten, und Text und Code müssen sich konsistent auf dieselbe beziehen:"},{"seite":"finanzdaten.html","titel":"18.6 Praxis: Datenpipeline mit korrekter Spaltenreihenfolge","anker":"sec:finanzdaten-praxis-datenpipeline-mit-korrekter-spaltenreihenfolge","text":""},{"seite":"finanzdaten.html","titel":"18.7 Übungsaufgaben","anker":"sec:finanzdaten-uebungsaufgaben","text":""},{"seite":"finanzdaten.html","titel":"18.8 Finde den Denkfehler","anker":"sec:finanzdaten-denkfehler","text":""},{"seite":"finanzdaten.html","titel":"18.9 Micro-Quiz","anker":"sec:finanzdaten-quiz","text":""},{"seite":"finanzdaten.html","titel":"18.10 Selbsttest","anker":"sec:finanzdaten-selbsttest","text":""},{"seite":"finanzdaten.html","titel":"18.11 Zusammenfassung","anker":"sec:finanzdaten-zusammenfassung","text":""},{"seite":"markowitz.html","titel":"Kapitel 19: Die moderne Portfoliotheorie nach Markowitz","anker":null,"text":""},{"seite":"markowitz.html","titel":"19.1 In 5 Minuten gelöst","anker":"sec:markowitz-schnellstart","text":""},{"seite":"markowitz.html","titel":"19.2 Lernziele","anker":"sec:markowitz-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"markowitz.html","titel":"19.3 Warum Diversifikation funktioniert","anker":"sec:markowitz-warum-diversifikation-funktioniert","text":"Harry Markowitz’ zentrale Einsicht von 1952: Das Risiko eines Portfolios ist nicht die Summe der Einzelrisiken. Es hängt davon ab, wie die Titel zusammenspielen."},{"seite":"markowitz.html","titel":"19.4 Das Mean-Variance-Modell","anker":"sec:markowitz-das-mean-variance-modell","text":"Sei \\mathbf{w} = (w_1,\\dots,w_n)^\\top der Vektor der Portfoliogewichte:"},{"seite":"markowitz.html","titel":"Die Effizienzgrenze und das Tangentialportfolio","anker":"die-effizienzgrenze-und-das-tangentialportfolio","text":"Die Effizienzgrenze (efficient frontier) ist die Kurve aller Portfolios, die zu jedem Risikoniveau die höchstmögliche Rendite liefern."},{"seite":"markowitz.html","titel":"Die Korn-Transformation","anker":"die-korn-transformation","text":"Die Sharpe Ratio ist ein Bruch — und damit nicht konvex. CVXPY würde sie ablehnen. Der Ausweg ist ein eleganter Trick, der die Homogenität des Problems ausnutzt:"},{"seite":"markowitz.html","titel":"19.5 Institutionelle Nebenbedingungen","anker":"sec:markowitz-institutionelle-nebenbedingungen","text":"In der Praxis gelten regulatorische und interne Regeln:"},{"seite":"markowitz.html","titel":"Was diese Regeln kosten","anker":"was-diese-regeln-kosten","text":"Jede Regel schneidet etwas vom Erreichbaren ab. Wie viel, lässt sich ausrechnen — man legt die Effizienzlinie ohne und mit Beschränkungen übereinander:"},{"seite":"markowitz.html","titel":"19.6 Vollimplementierung mit CVXPY","anker":"sec:markowitz-vollimplementierung-mit-cvxpy","text":""},{"seite":"markowitz.html","titel":"19.7 Übungsaufgaben","anker":"sec:markowitz-uebungsaufgaben","text":""},{"seite":"markowitz.html","titel":"19.8 Finde den Denkfehler","anker":"sec:markowitz-denkfehler","text":"Kapitel 18 hat gezeigt, was eine schlecht geschätzte Kovarianzmatrix anrichtet. Bei den erwarteten Renditen ist es schlimmer — und weil sie in der Zielfunktion stehen statt in der "},{"seite":"markowitz.html","titel":"19.9 Micro-Quiz","anker":"sec:markowitz-quiz","text":""},{"seite":"markowitz.html","titel":"19.10 Selbsttest","anker":"sec:markowitz-selbsttest","text":""},{"seite":"markowitz.html","titel":"19.11 Zusammenfassung","anker":"sec:markowitz-zusammenfassung","text":""},{"seite":"cvar.html","titel":"Kapitel 20: Tail-Risiko, CVaR und Transaktionskosten","anker":null,"text":""},{"seite":"cvar.html","titel":"20.1 In 5 Minuten gelöst","anker":"sec:cvar-schnellstart","text":""},{"seite":"cvar.html","titel":"20.2 Lernziele","anker":"sec:cvar-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"cvar.html","titel":"20.3 Die zwei Schwächen des Markowitz-Modells","anker":"sec:cvar-die-zwei-schwaechen-des-markowitz-modells","text":"Erstens: die Normalverteilungs-Illusion. Die Varianz behandelt Aufwärts- und Abwärtsschwankungen gleich und unterstellt implizit symmetrische, dünn auslaufende Verteilungen. Reale "},{"seite":"cvar.html","titel":"20.4 Value at Risk und Conditional Value at Risk","anker":"sec:cvar-value-at-risk-und-conditional-value","text":""},{"seite":"cvar.html","titel":"Das Rockafellar-Uryasev-Theorem (2000)","anker":"das-rockafellar-uryasev-theorem-2000","text":"Rockafellar und Uryasev zeigten, dass sich der CVaR über S Szenarien exakt als lineares Programm formulieren lässt:"},{"seite":"cvar.html","titel":"20.5 Transaktionskosten über die L_1-Norm","anker":"sec:cvar-transaktionskosten-ueber-die-l-1-norm","text":"Sei \\mathbf{w}_{\\text{alt}} das bestehende Portfolio und \\mathbf{w} das neue Ziel. Der Umschlag (turnover) ist:"},{"seite":"cvar.html","titel":"20.6 Implementierung: CVaR-Portfolio mit Reibung","anker":"sec:cvar-implementierung-cvar-portfolio-mit-reibung","text":""},{"seite":"cvar.html","titel":"20.7 Übungsaufgaben","anker":"sec:cvar-uebungsaufgaben","text":""},{"seite":"cvar.html","titel":"20.8 Finde den Denkfehler","anker":"sec:cvar-denkfehler","text":""},{"seite":"cvar.html","titel":"20.9 Micro-Quiz","anker":"sec:cvar-quiz","text":""},{"seite":"cvar.html","titel":"20.10 Selbsttest","anker":"sec:cvar-selbsttest","text":""},{"seite":"cvar.html","titel":"20.11 Zusammenfassung","anker":"sec:cvar-zusammenfassung","text":""},{"seite":"handelsmaschine.html","titel":"Kapitel 21: Die vollständige quantitative Handelsmaschine","anker":null,"text":""},{"seite":"handelsmaschine.html","titel":"21.1 In 5 Minuten gelöst","anker":"sec:handelsmaschine-schnellstart","text":""},{"seite":"handelsmaschine.html","titel":"21.2 Lernziele","anker":"sec:handelsmaschine-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"handelsmaschine.html","titel":"21.3 Die Architektur","anker":"sec:handelsmaschine-die-architektur","text":""},{"seite":"handelsmaschine.html","titel":"21.4 Rebalancing-Termine richtig bestimmen","anker":"sec:handelsmaschine-rebalancing-termine-richtig-bestimmen","text":""},{"seite":"handelsmaschine.html","titel":"21.5 Die Engine","anker":"sec:handelsmaschine-die-engine","text":""},{"seite":"handelsmaschine.html","titel":"21.6 Die fünf Selbsttäuschungen des Backtestens","anker":"sec:handelsmaschine-die-fuenf-selbsttaeuschungen-des-backtestens","text":""},{"seite":"handelsmaschine.html","titel":"21.7 Vom Backtest zum Betrieb","anker":"sec:handelsmaschine-vom-backtest-zum-betrieb","text":"Ein guter Backtest ist eine notwendige, keine hinreichende Bedingung. Was zwischen Backtest und echtem Einsatz liegt:"},{"seite":"handelsmaschine.html","titel":"21.8 Übungsaufgaben","anker":"sec:handelsmaschine-uebungsaufgaben","text":""},{"seite":"handelsmaschine.html","titel":"21.9 Finde den Denkfehler","anker":"sec:handelsmaschine-denkfehler","text":"Backtest_Fallen.py zeigt drei Fehler, die im Backtest stecken: Lookahead, Survivorship, vergessene Kosten. Alle drei kann man einem Programm ansehen, wenn man es liest."},{"seite":"handelsmaschine.html","titel":"21.10 Micro-Quiz","anker":"sec:handelsmaschine-quiz","text":""},{"seite":"handelsmaschine.html","titel":"21.11 Selbsttest","anker":"sec:handelsmaschine-selbsttest","text":""},{"seite":"handelsmaschine.html","titel":"21.12 Zusammenfassung","anker":"sec:handelsmaschine-zusammenfassung","text":""},{"seite":"synthese-anwendungen.html","titel":"Synthese Teil IV","anker":null,"text":""},{"seite":"synthese-anwendungen.html","titel":"Dieselbe Struktur, andere Namen","anker":"dieselbe-struktur-andere-namen","text":""},{"seite":"synthese-anwendungen.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-anwendungen.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-anwendungen.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"praxisfallen.html","titel":"Kapitel 22: Praxisfallen und der Weg zum produktiven Einsatz","anker":null,"text":""},{"seite":"praxisfallen.html","titel":"22.1 In 5 Minuten gelöst","anker":"sec:praxisfallen-schnellstart","text":"Die vorangegangenen vierzehn Kapitel enden fast alle mit derselben Empfehlung: Prüfen Sie das Ergebnis gegen die Wirklichkeit. Dieses Kapitel beginnt damit, diese Prüfung als wiede"},{"seite":"praxisfallen.html","titel":"22.2 Lernziele","anker":"sec:praxisfallen-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"praxisfallen.html","titel":"22.3 Die fünf typischen Praxisfallen","anker":"sec:praxisfallen-die-fuenf-typischen-praxisfallen","text":""},{"seite":"praxisfallen.html","titel":"Falle 1 — Infeasibility","anker":"falle-1-infeasibility","text":"Wenn Parameter unglücklich zusammentreffen — drei Mitarbeitende gleichzeitig krank, kein qualifizierter Ersatz —, meldet der Solver schlicht INFEASIBLE."},{"seite":"praxisfallen.html","titel":"Falle 2 — Der Black-Box-Effekt","anker":"falle-2-der-black-box-effekt","text":"Ein Planer oder Trader lehnt ein System ab, wenn er die Zuweisungen nicht nachvollziehen kann. Akzeptanz ist keine Nebensache, sondern Voraussetzung für den Betrieb."},{"seite":"praxisfallen.html","titel":"Falle 3 — Regimewechsel und Schätzfehler","anker":"falle-3-regimewechsel-und-schätzfehler","text":"Ein Modell, das auf einer mehrjährigen Aufwärtsphase kalibriert wurde, kennt keine Liquiditätskrise und keine Zinswende."},{"seite":"praxisfallen.html","titel":"Falle 4 — Lookahead- und Survivorship-Bias","anker":"falle-4-lookahead--und-survivorship-bias","text":"Ausführlich in Kapitel 21 behandelt. Die Kurzfassung: Beide Fehler machen Backtests systematisch zu gut, ohne eine Fehlermeldung zu erzeugen. Der Lookahead-Selbsttest aus Abschnitt"},{"seite":"praxisfallen.html","titel":"Falle 5 — Laufzeitexplosion","anker":"falle-5-laufzeitexplosion","text":"Exakte Optimalität kann bei MILP oder CP-SAT Minuten bis Stunden dauern — und die Laufzeit wächst nicht linear mit der Problemgröße."},{"seite":"praxisfallen.html","titel":"22.4 Constraint Attribution: welche Bedingung kostet wie viel?","anker":"sec:praxisfallen-attribution","text":"Der Constraint-Trace beantwortet „warum diese Zuweisung?“. Der Deletion Filter in Anhang C beantwortet „warum geht es gar nicht?“. Der häufigste Fall in der Praxis liegt dazwischen"},{"seite":"praxisfallen.html","titel":"Drei Befunde, und keiner steht im Solverergebnis","anker":"drei-befunde-und-keiner-steht-im-solverergebnis","text":"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 —"},{"seite":"praxisfallen.html","titel":"Vom Zahlenwerk zur Vorlage","anker":"vom-zahlenwerk-zur-vorlage","text":"Alle drei Antworten stehen bis hierhin in Tabellen. Tabellen liest niemand in einer Abteilungsleiterrunde. Teil (4) des Programms baut aus denselben Zahlen einen Text — und das ist"},{"seite":"praxisfallen.html","titel":"22.5 Architektur einer produktionsreifen OR-Plattform","anker":"sec:praxisfallen-architektur-einer-produktionsreifen-or-plattform","text":""},{"seite":"praxisfallen.html","titel":"22.6 Der gemeinsame Unterbau: or_kern.py","anker":"sec:praxisfallen-or-kern","text":"Die fünf Prinzipien oben beschreiben eine Plattform. Der Weg dorthin beginnt aber viel kleiner — mit der Frage, welche Teile eines Optimierungsprogramms immer dieselben sind."},{"seite":"praxisfallen.html","titel":"Die vier Schichten","anker":"die-vier-schichten","text":"\\underbrace{\\text{Rohdaten}}_{\\text{Excel, CSV, ERP}}\n\\;\\longrightarrow\\;\n\\underbrace{\\text{Domänenmodell}}_{\\text{geprüft, solverfrei}}\n\\;\\longrightarrow\\;\n\\underbrace{\\text{Model"},{"seite":"praxisfallen.html","titel":"Ein Enum für fünf Bibliotheken","anker":"ein-enum-für-fünf-bibliotheken","text":"Der unscheinbarste, aber wirksamste Teil ist die Statusübersetzung. Dieselbe Aussage heißt in den fünf im Buch verwendeten Bibliotheken:"},{"seite":"praxisfallen.html","titel":"22.7 Der Solverwechsel in der Praxis","anker":"sec:praxisfallen-solverwechsel","text":"Der vorige Abschnitt endet mit einer Behauptung: Ein Solverwechsel betreffe genau einen Baustein. Das ist die Art Satz, die in jedem Architekturvortrag vorkommt und die man deshalb"},{"seite":"praxisfallen.html","titel":"22.8 Eine Checkliste vor dem Produktivgang","anker":"sec:praxisfallen-eine-checkliste-vor-dem-produktivgang","text":"Arbeiten Sie diese Liste ab, bevor ein OR-System in Betrieb geht:"},{"seite":"praxisfallen.html","titel":"22.9 Weiterführende Literatur und Roadmap","anker":"sec:praxisfallen-weiterfuehrende-literatur-und-roadmap","text":"Grundlagen und lineare/ganzzahlige Optimierung * Bertsimas & Tsitsiklis: Introduction to Linear Optimization — Standardwerk zu Simplex, Dualität, Polyedertheorie. * Wolsey: Int"},{"seite":"praxisfallen.html","titel":"22.10 Übungsaufgaben","anker":"sec:praxisfallen-uebungsaufgaben","text":""},{"seite":"praxisfallen.html","titel":"22.11 Finde den Denkfehler","anker":"sec:praxisfallen-denkfehler","text":"Falle 5 — die Laufzeitexplosion — zeigt sich im Betrieb selten als Absturz. Sie zeigt sich als gar nichts."},{"seite":"praxisfallen.html","titel":"22.12 Micro-Quiz","anker":"sec:praxisfallen-quiz","text":""},{"seite":"praxisfallen.html","titel":"22.13 Selbsttest","anker":"sec:praxisfallen-selbsttest","text":""},{"seite":"praxisfallen.html","titel":"22.14 Zusammenfassung","anker":"sec:praxisfallen-zusammenfassung","text":""},{"seite":"testing.html","titel":"Kapitel 23: Testen, Messen, Ausliefern","anker":null,"text":""},{"seite":"testing.html","titel":"23.1 In 5 Minuten gelöst","anker":"sec:testing-schnellstart","text":""},{"seite":"testing.html","titel":"23.2 Lernziele","anker":"sec:testing-lernziele","text":"Nach diesem Kapitel können Sie …"},{"seite":"testing.html","titel":"23.3 Warum Optimierungsmodelle schwer zu testen sind","anker":"sec:testing-warum-schwer","text":"Bei einer gewöhnlichen Funktion schreibt man den erwarteten Wert hin:"},{"seite":"testing.html","titel":"23.4 Die Testsuite","anker":"sec:testing-suite","text":""},{"seite":"testing.html","titel":"23.5 Wer testet die Tests?","anker":"sec:testing-mutation","text":"33 grüne Tests. Das ist noch kein Ergebnis."},{"seite":"testing.html","titel":"Der erste Lauf fand zwei Lücken","anker":"der-erste-lauf-fand-zwei-lücken","text":"Die Suite hatte zunächst 31 Tests. Der Mutationstest sagte dazu:"},{"seite":"testing.html","titel":"23.6 Ein Vergleich, dem man glauben kann","anker":"sec:testing-benchmark","text":"Solververgleiche stehen in jedem Blog, und die meisten sind wertlos. Nicht, weil falsch gemessen wurde, sondern weil zu wenig dazugesagt wird."},{"seite":"testing.html","titel":"Die interessanteste Spalte heißt „Anteil”","anker":"die-interessanteste-spalte-heißt-anteil","text":"Sie sagt, wie viel der Zeit in den Aufbau des Modells geht statt ins Lösen — und die Zahlen sind unbequem:"},{"seite":"testing.html","titel":"23.7 Das Modell als Dienst","anker":"sec:testing-dienst","text":"Ein Modell hinter eine HTTP-Schnittstelle zu hängen sieht nach einer Fingerübung aus. Es gibt aber einen Unterschied, der die ganze Bauform bestimmt:"},{"seite":"testing.html","titel":"Threads oder Prozesse? Eine Messung, keine Meinung","anker":"threads-oder-prozesse-eine-messung-keine-meinung","text":"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 w"},{"seite":"testing.html","titel":"Was im echten Betrieb dazukommt","anker":"was-im-echten-betrieb-dazukommt","text":"Das Beispiel hält das Auftragsbuch in einem dict und rechnet in Threads desselben Prozesses. Für einen einzelnen Rechner reicht das; darüber hinaus nicht:"},{"seite":"testing.html","titel":"23.8 Übungsaufgaben","anker":"sec:testing-uebungsaufgaben","text":""},{"seite":"testing.html","titel":"23.9 Finde den Denkfehler","anker":"sec:testing-denkfehler","text":""},{"seite":"testing.html","titel":"23.10 Micro-Quiz","anker":"sec:testing-quiz","text":""},{"seite":"testing.html","titel":"23.11 Selbsttest","anker":"sec:testing-selbsttest","text":""},{"seite":"testing.html","titel":"23.12 Zusammenfassung","anker":"sec:testing-zusammenfassung","text":""},{"seite":"synthese-praxis.html","titel":"Synthese Teil V","anker":null,"text":""},{"seite":"synthese-praxis.html","titel":"Was schiefgeht, und was dagegen hilft","anker":"was-schiefgeht-und-was-dagegen-hilft","text":""},{"seite":"synthese-praxis.html","titel":"Was dieser Teil gemessen hat","anker":"was-dieser-teil-gemessen-hat","text":""},{"seite":"synthese-praxis.html","titel":"Drei Fehler, die dieser Teil verhindert","anker":"drei-fehler-die-dieser-teil-verhindert","text":""},{"seite":"synthese-praxis.html","titel":"Wenn Sie nur eines mitnehmen","anker":"wenn-sie-nur-eines-mitnehmen","text":""},{"seite":"projektwerkstatt.html","titel":"Projektwerkstatt","anker":null,"text":""},{"seite":"projektwerkstatt.html","titel":"Wie Sie ein Projekt bearbeiten","anker":"wie-sie-ein-projekt-bearbeiten","text":"Halten Sie sich an diese Reihenfolge — sie ist aus vielen gescheiterten und einigen gelungenen Projekten destilliert:"},{"seite":"projektwerkstatt.html","titel":"P1 — Vertretungsplaner für eine Schule","anker":"p1-vertretungsplaner-für-eine-schule","text":""},{"seite":"projektwerkstatt.html","titel":"P2 — Schichtplanung für ein Pflegeteam","anker":"p2-schichtplanung-für-ein-pflegeteam","text":""},{"seite":"projektwerkstatt.html","titel":"P3 — Tourenplanung für einen Lieferdienst","anker":"p3-tourenplanung-für-einen-lieferdienst","text":""},{"seite":"projektwerkstatt.html","titel":"P4 — Standort- und Lagernetzplanung","anker":"p4-standort--und-lagernetzplanung","text":""},{"seite":"projektwerkstatt.html","titel":"P5 — Produktionsplanung mit Rüstkosten","anker":"p5-produktionsplanung-mit-rüstkosten","text":""},{"seite":"projektwerkstatt.html","titel":"P6 — Portfolio-Rebalancer für ein Privatdepot","anker":"p6-portfolio-rebalancer-für-ein-privatdepot","text":""},{"seite":"projektwerkstatt.html","titel":"P7 — Risikoreport mit CVaR und Stresstests","anker":"p7-risikoreport-mit-cvar-und-stresstests","text":""},{"seite":"projektwerkstatt.html","titel":"P9 — Wenn der Solver aussteigt: Tourenplanung in Echtgröße","anker":"p9-wenn-der-solver-aussteigt-tourenplanung-in-echtgröße","text":""},{"seite":"projektwerkstatt.html","titel":"P10 — Zwei Ziele, eine Entscheidung: Kosten gegen CO₂","anker":"p10-zwei-ziele-eine-entscheidung-kosten-gegen-co₂","text":""},{"seite":"projektwerkstatt.html","titel":"P11 — Vom Skript zum Dienst: das Modell übergeben","anker":"p11-vom-skript-zum-dienst-das-modell-übergeben","text":""},{"seite":"projektwerkstatt.html","titel":"P8 — Freies Projekt aus Ihrem eigenen Umfeld","anker":"p8-freies-projekt-aus-ihrem-eigenen-umfeld","text":""},{"seite":"projektwerkstatt.html","titel":"Eine Bitte zum Schluss","anker":"eine-bitte-zum-schluss","text":"Wenn Sie ein Projekt fertig haben, machen Sie zwei Dinge:"},{"seite":"anhang-loesungen.html","titel":"Anhang A: Lösungen zu allen Übungsaufgaben","anker":null,"text":""},{"seite":"anhang-loesungen.html","titel":"A.1 Lösungen zu Kapitel „Einführung in Operations Research — Vom Ursprung zur mathematischen Entscheidungsfindung“","anker":"sec:loesungen-einfuehrung","text":"1.1 — Analytik-Stufen. (a) deskriptiv (Vergangenheit beschreiben). (b) prädiktiv (Prognose). (c) präskriptiv (Handlungsanweisung unter Restriktionen). (d) prädiktiv (Klassifikation"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Schreinerei verdoppelt ihren Gewinn","anker":"finde-den-denkfehler-die-schreinerei-verdoppelt-ihren-gewinn","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-einfuehrung","text":"1 — (c) präskriptiv. Die Frage lautet „was tun“, und es gibt eine Restriktion (das Restbudget). Dass man für die Bewertung eine Prognose braucht, macht die Frage nicht prädiktiv — "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-einfuehrung","text":""},{"seite":"anhang-loesungen.html","titel":"A.2 Lösungen zu Kapitel „Das mathematische Fundament — Vektoren, Matrizen, Konvexität“","anker":"sec:loesungen-fundament","text":"2.1 — Matrixform lesen. \\max 4x_1 + x_2 + 6x_3 u. d. N. x_1 + 2x_2 \\le 10, x_2 + 3x_3 \\le 12, x \\ge 0. 3 Variablen, 2 Nebenbedingungen (plus Nichtnegativität)."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die unauffällige Transposition","anker":"finde-den-denkfehler-die-unauffällige-transposition","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-fundament","text":"1 — (b). Der Fundamentalsatz sagt nur, dass ein Optimum in einer Ecke angenommen wird. (a) ist falsch, weil es mehrere optimale Ecken geben kann (wenn die Zielfunktion parallel zu "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-fundament","text":""},{"seite":"anhang-loesungen.html","titel":"A.3 Lösungen zu Kapitel „Das Python-Ökosystem für OR — Solver, Bindings und Modellierungsschichten“","anker":"sec:loesungen-oekosystem","text":"3.1 — Solverwahl. (a) CP-SAT (diskrete Zuordnung mit Zeitfenstern). (b) scipy.optimize.linprog (klassisches Mischungs-LP, klein). (c) CVXPY (konvexes QP). (d) MIQP — CVXPY mit Binä"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Der Solver, der angeblich dreimal schneller ist","anker":"finde-den-denkfehler-der-solver-der-angeblich-dreimal-schneller-ist","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-oekosystem","text":"1 — (b) CP-SAT. Es geht um diskrete Zuweisung mit logischen Regeln („nicht gleichzeitig“) — CP-SATs Kerngebiet, und Regeln dieser Art formuliert man dort direkt statt über Big-M-Um"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-oekosystem","text":""},{"seite":"anhang-loesungen.html","titel":"A.4 Lösungen zu Kapitel „Vom Management-Wunsch zum Modell“","anker":"sec:loesungen-modellierung","text":"4.1 — Die fehlende Lesart. Eine dritte Lesart: „Der Umsatzanteil der Stammkunden darf nicht unter 30 % fallen.” Sie zielt weder auf einzelne Aufträge noch auf einzelne Kunden, sond"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Die Engpassmaschine soll zu mindestens 92 % ausgelastet sein“","anker":"denkfehler-loesung-modellierung","text":"Fehler 1: Auslastung ist ein Ergebnis, keine Anforderung."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-modellierung","text":"1. b) Die Zielfunktion ist eine vollständige Aussage darüber, was zählt. Was nicht darin steht, ist für das Modell nicht „weniger wichtig”, sondern wertlos. (a) und (c) sind frei e"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-modellierung","text":""},{"seite":"anhang-loesungen.html","titel":"A.5 Lösungen zu Kapitel „Lineare Programmierung — Simplex, Dualität und Schattenpreise“","anker":"sec:loesungen-lp","text":"5.1 — Schlupf deuten. (a) Ressourcen 1 und 3 (Schlupf 0). (b) Ja: Überall ist s_i \\cdot y_i = 0. (c) In Ressource 3 — der höchste Schattenpreis (9,8) bedeutet den größten Grenznutz"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die 380 000-Euro-Maschine","anker":"finde-den-denkfehler-die-380-000-euro-maschine","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-lp","text":"1 — (b). Genau der Satz vom komplementären Schlupf: s_i \\cdot y_i = 0. Ist Schlupf vorhanden, muss der Dualwert null sein. (a) hat die Aussage in ihr Gegenteil verkehrt; (c) verwec"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-lp","text":""},{"seite":"anhang-loesungen.html","titel":"A.6 Lösungen zu Kapitel „Gemischt-ganzzahlige Optimierung — Diskrete Entscheidungen und Branch-and-Bound“","anker":"sec:loesungen-milp","text":"6.1 — Runden widerlegen. Beispiel: \\max x_1 + x_2 u. d. N. 10x_1 + 10x_2 \\le 15, ganzzahlig. LP-Optimum Z = 1{,}5; Abrunden ergibt (0,0) mit Z = 0 — 100 % Verlust. Das ganzzahlige "},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Elf Lager, die keine Fixkosten kosten","anker":"finde-den-denkfehler-elf-lager-die-keine-fixkosten-kosten","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-milp","text":"1 — (b). Der Gap (48\\,200 - 47\\,100)/48\\,200 = 2{,}3\\,\\% ist eine Garantie, keine Schätzung: Besser als 47 100 € kann es nachweislich nicht werden, also ist der vorliegende Plan hö"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-milp","text":""},{"seite":"anhang-loesungen.html","titel":"A.7 Lösungen zu Kapitel „Constraint Programming mit CP-SAT — Logik, Scheduling und Zuweisung“","anker":"sec:loesungen-cpsat","text":"7.1 — Propagation. Aus x_1 + x_2 = 8 und x_1 < x_2 folgt x_1 < 4, also x_1 \\in \\{2,3\\} (denn x_2 = 8-x_1 \\le 6 verlangt x_1 \\ge 2) und entsprechend x_2 \\in \\{5,6\\}. Aus 36 Ko"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Betriebsvereinbarung, die niemanden interessiert","anker":"finde-den-denkfehler-die-betriebsvereinbarung-die-niemanden-interessiert","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-cpsat","text":"1 — (b) wirkungslos. INFEASIBLE ist kein Abbruch, sondern ein Beweis: CP-SAT hat gezeigt, dass keine zulässige Lösung existiert. Mehr Zeit (a) oder mehr Arbeiter (c) ändern daran n"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-cpsat","text":""},{"seite":"anhang-loesungen.html","titel":"A.8 Lösungen zu Kapitel „Graphen, Flüsse und Touren — Min-Cost-Flow, Matching und VRP“","anker":"sec:loesungen-graphen","text":"8.1 — Flusserhaltung. b_i = (15+3) - (12+8) = -2 → Senke (Nettobedarf 2)."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die vergessene Dimension","anker":"finde-den-denkfehler-die-vergessene-dimension","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-graphen","text":"1 — (b) totale Unimodularität. Jede quadratische Teilmatrix hat Determinante 0, +1 oder -1; bei ganzzahliger rechter Seite sind deshalb alle Ecken des zulässigen Bereichs ganzzahli"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-graphen","text":""},{"seite":"anhang-loesungen.html","titel":"A.9 Lösungen zu Kapitel „Metaheuristiken — wenn der exakte Solver aussteigt“","anker":"sec:loesungen-metaheuristiken","text":"9.1 — Die Kurzsichtigkeit von Hand. Ab Schwarz wählt die Faustregel: Schwarz → Dunkelrot (26) → Rot (5) → … und muss dann in die helle Gruppe: Rot → Weiß (50) → Elfenbein (2) → Bei"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Unsere Heuristik ist 6 % besser“","anker":"denkfehler-loesung-metaheuristiken","text":"Es fehlt die Schranke."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-metaheuristiken","text":"1. b) Eine lokale Suche lebt von der Zahl geprüfter Züge. Die volle Summe kostet O(n) statt O(1) — bei 500 Aufträgen zwei Größenordnungen weniger Züge im selben Zeitbudget. Numeris"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-metaheuristiken","text":""},{"seite":"anhang-loesungen.html","titel":"A.10 Lösungen zu Kapitel „Spaltengenerierung“","anker":"sec:loesungen-dekomposition","text":"10.1 — Das Abbruchkriterium. Die Eins ist der Zielfunktionskoeffizient eines Musters: Jedes geschnittene Muster verbraucht genau eine Mutterrolle, und die Zielfunktion lautet \\min "},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Die LP-Lösung sagt 72,92 — also runden wir auf“","anker":"denkfehler-loesung-dekomposition","text":"Das Aufrunden kostet sechs Rollen — acht Prozent."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-dekomposition","text":"1. b) Das Mustermodell kennt keine einzelnen Rollen und damit keine austauschbaren Objekte — die Symmetrie verschwindet. (a) trifft zufällig auch zu, ist aber nicht der Grund; (c) "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-dekomposition","text":""},{"seite":"anhang-loesungen.html","titel":"A.11 Lösungen zu Kapitel „Quadratische und nichtlineare Optimierung — KKT, Lagrange, Konvexität“","anker":"sec:loesungen-qp-nlp","text":"11.1 — Konvexität einordnen. PSD (alle \\ge 0) → konvex, aber nicht streng konvex; die Lösung ist nicht notwendig eindeutig. Der Eigenwert 0 bedeutet eine flache Richtung: Entlang d"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Kovarianzmatrix aus dem Controlling","anker":"finde-den-denkfehler-die-kovarianzmatrix-aus-dem-controlling","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-qp-nlp","text":"1 — (b). Der DCPError ist eine inhaltliche Aussage: Für diese Formulierung kann es keine Optimalitätsgarantie geben. Auf scipy auszuweichen (a) beseitigt die Meldung, nicht die Urs"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-qp-nlp","text":""},{"seite":"anhang-loesungen.html","titel":"A.12 Lösungen zu Kapitel „Optimierung unter Unsicherheit — Monte-Carlo, Stochastik, Robustheit“","anker":"sec:loesungen-unsicherheit","text":"12.1 — Fluch des Durchschnitts. Weil sich Verzögerungen fortpflanzen und die Verteilung rechtsschief ist: Ein Gewerk, das früher fertig wird, beschleunigt selten den Gesamtablauf ("},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Warum jedes Projekt zu spät fertig wird","anker":"finde-den-denkfehler-warum-jedes-projekt-zu-spät-fertig-wird","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-unsicherheit","text":"1 — (b). Das kritische Verhältnis 1400/(1400+120) = 0{,}921 gibt an, wie weit man sich auf die günstigere Fehlerseite stellen soll: Bestellt wird das 92,1-%-Quantil des Bedarfs, hi"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-unsicherheit","text":""},{"seite":"anhang-loesungen.html","titel":"A.13 Lösungen zu Kapitel „Dynamische Programmierung — Die Bellman-Gleichung und Order-Execution“","anker":"sec:loesungen-dynamische-programmierung","text":"13.1 — Bausteine. Stufe = Tag 1–5; Zustand = verbleibende Distanz (ggf. plus Erschöpfungsgrad); Aktion = heutige Tagesetappe; Wertfunktion = minimale Restanstrengung. Nicht in den "},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Der Zustand, der zu wenig weiß","anker":"finde-den-denkfehler-der-zustand-der-zu-wenig-weiß","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-dynamische-programmierung","text":"1 — (b). V_t setzt V_{t+1} voraus: Eine Entscheidung lässt sich erst bewerten, wenn feststeht, was sie für die Zukunft bedeutet. Am Ende ist dieser Wert bekannt (V_T = g), deshalb "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-dynamische-programmierung","text":""},{"seite":"anhang-loesungen.html","titel":"A.14 Lösungen zu Kapitel „Mehrere Ziele — Pareto-Fronten statt Gewichte“","anker":"sec:loesungen-mehrziel","text":"14.1 — Dominanz prüfen. P (14 000 €, 6 000 kg) und Q (13 800 €, 6 100 kg): keiner dominiert den anderen. Q ist billiger, P ist sauberer — beide sind pareto-optimal, die Wahl ist ei"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Wir haben die Gewichte sauber kalibriert“","anker":"denkfehler-loesung-mehrziel","text":"Der Lösungsraum wurde nicht vollständig abgetastet — und zwar aus prinzipiellen Gründen."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-mehrziel","text":"1. b) Geometrisch heißt „gewichtete Summe minimieren“: eine Gerade von links unten an die Punktwolke schieben. Sie berührt immer einen Eckpunkt der unteren konvexen Hülle; Punkte d"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-mehrziel","text":""},{"seite":"anhang-loesungen.html","titel":"A.15 Lösungen zu Kapitel „Predict-then-Optimize“","anker":"sec:loesungen-prognose","text":"15.1 — Andere Preise. Der Überhang kostet nur noch 1,50 €, die Fehlmenge weiterhin 6 €. Das kritische Verhältnis steigt von 6/9 = 0{,}667 auf 6/7{,}5 = 0{,}80. Die Bestellmenge ver"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Wir haben die Prognose um 18 % verbessert“","anker":"denkfehler-loesung-prognose","text":"Der Sicherheitszuschlag stammt aus den Residuen des alten Modells."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-prognose","text":"1. b) Die Kostenasymmetrie verschiebt das Optimum vom Erwartungswert zum kritischen Quantil. (a) und (c) sind reale Probleme, aber nicht dieses: Selbst bei perfekt bekannter, norma"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-prognose","text":""},{"seite":"anhang-loesungen.html","titel":"A.16 Lösungen zu Kapitel „Die Strukturbrücke — dieselbe Mathematik, zwei Welten“","anker":"sec:loesungen-bruecke","text":"16.1 — Die dritte Ressource. „Liquidität” — wie schnell sich eine Position ohne Kursabschlag verkaufen lässt — entspricht in der Werkstatt der Umrüstbarkeit oder der Vorlaufzeit: W"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Das ist doch dasselbe Problem“","anker":"denkfehler-loesung-bruecke","text":"Fehler 1: Varianz ist hier das falsche Risikomaß — genau der Fall, für den es CVaR gibt."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-bruecke","text":"1. b) Beide Probleme haben dieselbe Struktur: knappe Größen auf konkurrierende Verwendungen verteilen. (a) ist falsch — Produktionsproblem ist streng typisiert und validiert beim E"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-bruecke","text":""},{"seite":"anhang-loesungen.html","titel":"A.17 Lösungen zu Kapitel „Supply-Chain und Energieeinsatz unter Unsicherheit“","anker":"sec:loesungen-supplychain","text":"17.1 — Der Umschlagpunkt. Bei 60 MW statt 120 MW halbiert sich die Grenzkostendifferenz je Stunde (83 €/MWh × 60 MW = 4 980 €/h). Der Umschlagpunkt verdoppelt sich auf 7,7 Stunden."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Wir rechnen mit dem P50-Szenario“","anker":"denkfehler-loesung-supplychain","text":"Fehler 1: Der Median ist keine Absicherung, sondern eine Wette auf die Hälfte der Fälle."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-supplychain","text":"1. b) Anfahrkosten und Mindestlaufzeiten koppeln die Stunden. Die Merit-Order ist eine Sortierung und kennt keine Kopplung über die Zeit; sie ist für einen einzelnen Zeitpunkt rich"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-supplychain","text":""},{"seite":"anhang-loesungen.html","titel":"A.18 Lösungen zu Kapitel „Finanzdaten-Modellierung — Renditen, Kovarianz und Shrinkage“","anker":"sec:loesungen-finanzdaten","text":"18.1 — Renditeart. (a) diskret. (b) logarithmisch. (c) logarithmisch (bzw. diskret kumuliert über Produkt). (d) logarithmisch (statistische Eigenschaften)."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Das risikofreie Portfolio","anker":"finde-den-denkfehler-das-risikofreie-portfolio","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-finanzdaten","text":"1 — (b) bei 75 %. 1{,}0 \\cdot 0{,}5 \\cdot 1{,}5 = 0{,}75. Prozentuale Änderungen verknüpfen sich multiplikativ; ein Verlust wiegt schwerer als ein gleich großer Gewinn, weil er von"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-finanzdaten","text":""},{"seite":"anhang-loesungen.html","titel":"A.19 Lösungen zu Kapitel „Die moderne Portfoliotheorie nach Markowitz“","anker":"sec:loesungen-markowitz","text":"19.1 — Diversifikationseffekt."},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Zwölf gleiche Anlagen, ein sehr ungleiches Portfolio","anker":"finde-den-denkfehler-zwölf-gleiche-anlagen-ein-sehr-ungleiches-portfolio","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-markowitz","text":"1 — (b). Das renditestärkste Portfolio auf der Effizienzlinie hat notwendig das schlechteste Rendite-Risiko-Verhältnis (im Kapitelbeispiel 0,44 gegenüber 0,75 beim Optimum) und bes"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-markowitz","text":""},{"seite":"anhang-loesungen.html","titel":"A.20 Lösungen zu Kapitel „Tail-Risiko, CVaR und Transaktionskosten“","anker":"sec:loesungen-cvar","text":"20.1 — VaR 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{"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Das Risikobudget, das durch Diversifikation stieg","anker":"finde-den-denkfehler-das-risikobudget-das-durch-diversifikation-stieg","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-cvar","text":"1 — (b) nichts. Der VaR ist ein Quantil: Er markiert die Schwelle und sagt nichts über den Bereich dahinter. Genau das zeigt der Schnellstart dieses Kapitels — zwei Anlagen mit ide"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-cvar","text":""},{"seite":"anhang-loesungen.html","titel":"A.21 Lösungen zu Kapitel „Die vollständige quantitative Handelsmaschine“","anker":"sec:loesungen-handelsmaschine","text":"21.1 — Lookahead erkennen. (a) sauber (:heute). (b) Lookahead — gesamter Zeitraum. (c) Lookahead — Volatilität über den ganzen Zeitraum enthält Zukunft. (d) sauber — Gewichte aus D"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Die Strategie mit dem hochsignifikanten Ergebnis","anker":"finde-den-denkfehler-die-strategie-mit-dem-hochsignifikanten-ergebnis","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-handelsmaschine","text":"1 — (b) nichts. Beide Kennzahlen sind Mittelwerte über die Zeit und blind für die Reihenfolge. Der Schnellstart dieses Kapitels zeigt es an denselben Tagesrenditen, nur anders ange"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-handelsmaschine","text":""},{"seite":"anhang-loesungen.html","titel":"A.22 Lösungen zu Kapitel „Praxisfallen und der Weg zum produktiven Einsatz“","anker":"sec:loesungen-praxisfallen","text":"22.1 — Hart oder weich, revisited. (a) hart: gesetzliche Ruhezeit, Qualifikationspflicht. (b) weich: individuelle Wunschtage, Vermeidung von Freistunden. (c) diskutabel: Höchstzahl"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — Das Modell, das seit einem Jahr nicht mehr optimiert","anker":"finde-den-denkfehler-das-modell-das-seit-einem-jahr-nicht-mehr-optimiert","text":""},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-praxisfallen","text":"1 — (b) das Zeitlimit greift. Eine Laufzeit, die exakt dem Limit entspricht und über Monate konstant bleibt, ist kein Stabilitätsbeleg, sondern zeigt, dass der Solver jedes Mal abg"},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-praxisfallen","text":""},{"seite":"anhang-loesungen.html","titel":"A.23 Lösungen zu Kapitel „Testen, Messen, Ausliefern“","anker":"sec:loesungen-testing","text":"23.1 — Den Schnellstart reparieren. Zwei Wege: (a) Abrunden statt runden — np.floor statt np.round. Das ist immer zulässig, weil weniger produzieren nie eine Kapazität sprengt, kos"},{"seite":"anhang-loesungen.html","titel":"Finde den Denkfehler — „Die Suite ist grün, das Modell stimmt”","anker":"denkfehler-loesung-testing","text":"Alle Prüfungen benutzen dieselbe falsche Zahl."},{"seite":"anhang-loesungen.html","titel":"Micro-Quiz","anker":"quiz-loesung-testing","text":"1. b) Es gibt keine unabhängige Quelle für die richtige Antwort — sonst bräuchte man den Solver nicht. (a) ist bei festgelegtem Seed und Zeitlimit meist beherrschbar; (c) löst man "},{"seite":"anhang-loesungen.html","titel":"Selbsttest","anker":"selbsttest-loesung-testing","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"Anhang B: Katalog der Modellierungsmuster","anker":null,"text":""},{"seite":"anhang-modellierungsmuster.html","titel":"Übersicht","anker":"übersicht","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"Logische Schalter","anker":"logische-schalter","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B1 — Aktivierungsschalter (Fixkosten)","anker":"b1-aktivierungsschalter-fixkosten","text":"Regel. „Wenn überhaupt etwas produziert wird, fallen Rüstkosten F an.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B2 — Semikontinuierliche Variable","anker":"b2-semikontinuierliche-variable","text":"Regel. „Entweder gar nicht oder mindestens L (und höchstens U).“"},{"seite":"anhang-modellierungsmuster.html","titel":"B3 — Implikation","anker":"b3-implikation","text":"Regel. „Wenn A gewählt wird, muss auch B gewählt werden.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B4 — Entweder-Oder (disjunktive Bedingung)","anker":"b4-entweder-oder-disjunktive-bedingung","text":"Regel. „Es muss f(\\mathbf{x}) \\le b_1 oder g(\\mathbf{x}) \\le b_2 gelten.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B5 — Exklusiv-Oder","anker":"b5-exklusiv-oder","text":"Regel. „Genau eine der Optionen wird gewählt.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B6 — Kardinalität","anker":"b6-kardinalität","text":"Regel. „Höchstens (mindestens, genau) K von N.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B7 — Bedingte Kopplung (Konjunktion)","anker":"b7-bedingte-kopplung-konjunktion","text":"Regel. „Wenn A und B, dann auch C.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Mengen und Grenzen","anker":"mengen-und-grenzen","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B8 — Weiche Grenze mit Strafkosten","anker":"b8-weiche-grenze-mit-strafkosten","text":"Regel. „Möglichst nicht über b — wenn doch, kostet es.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B9 — Gestaffelte Preise (stückweise linear)","anker":"b9-gestaffelte-preise-stückweise-linear","text":"Regel. „Die ersten 100 Stück kosten 5 €, danach 8 €.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B10 — Absolutbetrag / Abweichung","anker":"b10-absolutbetrag-abweichung","text":"Regel. „Die Abweichung vom Zielwert soll klein sein, egal in welche Richtung.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B11 — Min/Max in der Zielfunktion","anker":"b11-minmax-in-der-zielfunktion","text":"Regel. „Der am schlechtesten gestellte Beteiligte soll möglichst gut dastehen“ (Maximin/Fairness)."},{"seite":"anhang-modellierungsmuster.html","titel":"B12 — Verhältnis-Bedingung","anker":"b12-verhältnis-bedingung","text":"Regel. „Der Anteil von Gruppe G soll mindestens 30 % betragen.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B25 — Mindestabnahmemenge über einen Zeitraum","anker":"b25-mindestabnahmemenge-über-einen-zeitraum","text":"Regel. „Entweder wir arbeiten mit diesem Lieferanten gar nicht, oder wir nehmen ihm im Jahr mindestens 500 Einheiten ab.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B27 — Budgetlimit","anker":"b27-budgetlimit","text":"Regel. „Alle Maßnahmen zusammen dürfen 2 Mio. € nicht überschreiten.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Zeit und Reihenfolge","anker":"zeit-und-reihenfolge","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B13 — Vorrangbeziehung","anker":"b13-vorrangbeziehung","text":"Regel. „Arbeitsgang B darf erst beginnen, wenn A fertig ist.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B14 — Nichtüberlappung","anker":"b14-nichtüberlappung","text":"Regel. „Eine Maschine bearbeitet nur einen Job gleichzeitig.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B15 — Kumulative Ressource","anker":"b15-kumulative-ressource","text":"Regel. „Zu keinem Zeitpunkt dürfen mehr als 3 Arbeiten gleichzeitig laufen“ bzw. „die Stromlast darf 500 kW nie übersteigen“."},{"seite":"anhang-modellierungsmuster.html","titel":"B16 — Gleitendes Fenster","anker":"b16-gleitendes-fenster","text":"Regel. „Höchstens 5 Arbeitstage in Folge“ / „mindestens 2 freie Tage je Woche“."},{"seite":"anhang-modellierungsmuster.html","titel":"B17 — Umrüst- bzw. Wechselkosten","anker":"b17-umrüst--bzw.-wechselkosten","text":"Regel. „Ein Produktwechsel kostet Rüstzeit.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B26 — Rüstzeit als Kapazitätsverbrauch","anker":"b26-rüstzeit-als-kapazitätsverbrauch","text":"Regel. „Das Umrüsten kostet nicht nur Geld, es kostet Maschinenstunden — und die fehlen dann für die Produktion.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Robustheit und Diagnose","anker":"robustheit-und-diagnose","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B18 — Schlupfvariablen gegen Unlösbarkeit","anker":"b18-schlupfvariablen-gegen-unlösbarkeit","text":"Das wichtigste Muster für den Produktivbetrieb."},{"seite":"anhang-modellierungsmuster.html","titel":"B19 — Hierarchische Ziele (lexikografisch)","anker":"b19-hierarchische-ziele-lexikografisch","text":"Regel. „Erst die Besetzung sicherstellen, dann die Fairness optimieren.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B20 — Symmetriebrechung","anker":"b20-symmetriebrechung","text":"Regel. „Drei identische Maschinen — der Solver soll nicht alle Vertauschungen durchprobieren.“"},{"seite":"anhang-modellierungsmuster.html","titel":"B21 — Worst-Case-Abzug (robuste Formulierung)","anker":"b21-worst-case-abzug-robuste-formulierung","text":"Regel. „Rechne nicht mit dem geschätzten Wert, sondern mit dem ungünstigsten plausiblen.“"},{"seite":"anhang-modellierungsmuster.html","titel":"Netzwerke","anker":"netzwerke","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B22 — Flusserhaltung","anker":"b22-flusserhaltung","text":"\\sum_{j:(i,j)\\in E} x_{ij} - \\sum_{k:(k,i)\\in E} x_{ki} = b_i \\qquad \\forall i"},{"seite":"anhang-modellierungsmuster.html","titel":"B23 — Zuordnung 1:1","anker":"b23-zuordnung-11","text":""},{"seite":"anhang-modellierungsmuster.html","titel":"B24 — Subtour-Eliminierung","anker":"b24-subtour-eliminierung","text":"MTZ (einfach, aber schwach): u_i - u_j + C x_{ij} \\le C - d_j \\qquad \\forall i\\ne j"},{"seite":"anhang-modellierungsmuster.html","titel":"Ein Wort zur Auswahl","anker":"ein-wort-zur-auswahl","text":"Wenn mehrere Muster passen, entscheiden Sie nach dieser Reihenfolge:"},{"seite":"anhang-fehlerdiagnose.html","titel":"Anhang C: Fehlerdiagnose-Handbuch","anker":null,"text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"Symptom-Schnellübersicht","anker":"symptom-schnellübersicht","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C1 — INFEASIBLE","anker":"c1-infeasible","text":"Bedeutung. Es gibt keinen einzigen Punkt, der alle Bedingungen gleichzeitig erfüllt. Das ist eine Aussage über Ihr Modell, nicht über den Solver."},{"seite":"anhang-fehlerdiagnose.html","titel":"Diagnose in fünf Schritten","anker":"diagnose-in-fünf-schritten","text":"Schritt 1 — Trivialprüfungen von Hand. Rechnen Sie die offensichtlichen Bilanzen nach, bevor Sie den Solver befragen:"},{"seite":"anhang-fehlerdiagnose.html","titel":"Wenn die fünf Schritte nicht reichen: den Konflikt einkreisen","anker":"wenn-die-fünf-schritte-nicht-reichen-den-konflikt-einkreisen","text":"Warum Schritt 2 so oft ins Leere läuft. Bedingungen einzeln abzuschalten funktioniert nur, solange es einen Schuldigen gibt. Überlagern sich zwei unabhängige Widersprüche, bleibt d"},{"seite":"anhang-fehlerdiagnose.html","titel":"C2 — UNBOUNDED","anker":"c2-unbounded","text":"Bedeutung. Die Zielfunktion lässt sich unbegrenzt verbessern."},{"seite":"anhang-fehlerdiagnose.html","titel":"C3 — Zu langsam","anker":"c3-zu-langsam","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"Diagnosereihenfolge","anker":"diagnosereihenfolge","text":"1. Ist es überhaupt das Lösen?"},{"seite":"anhang-fehlerdiagnose.html","titel":"C4 — Unsinniges Ergebnis","anker":"c4-unsinniges-ergebnis","text":"Der Solver hat immer recht — bezogen auf das Modell, das Sie ihm gegeben haben. Wenn das Ergebnis unsinnig ist, beschreibt Ihr Modell nicht das Problem, das Sie meinen."},{"seite":"anhang-fehlerdiagnose.html","titel":"Checkliste","anker":"checkliste","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"Die wirksamste Gegenmaßnahme","anker":"die-wirksamste-gegenmaßnahme","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C5 — Instabile Lösung","anker":"c5-instabile-lösung","text":"Symptom. Ein zusätzlicher Handelstag, und das Portfolio sieht völlig anders aus."},{"seite":"anhang-fehlerdiagnose.html","titel":"Derselbe Fehler außerhalb der Finanzwelt","anker":"derselbe-fehler-außerhalb-der-finanzwelt","text":"Instabilität ist kein Portfolioproblem, sondern ein Skalierungsproblem — und es trifft jedes Modell, in dem Größen sehr verschiedener Ordnung nebeneinanderstehen. Euro-Beträge (10^"},{"seite":"anhang-fehlerdiagnose.html","titel":"C6 — Falsche Dualwerte","anker":"c6-falsche-dualwerte","text":"Symptom. Schattenpreise sind negativ, wo sie positiv sein sollten — oder null bei einer offensichtlich knappen Ressource."},{"seite":"anhang-fehlerdiagnose.html","titel":"Die drei Prüfungen","anker":"die-drei-prüfungen","text":"1. Vorzeichenkonvention. Haben Sie zur Maximierung negiert?"},{"seite":"anhang-fehlerdiagnose.html","titel":"C7 — Widersprüchliche Solver","anker":"c7-widersprüchliche-solver","text":"Symptom. linprog sagt 530, CVXPY sagt 529,8."},{"seite":"anhang-fehlerdiagnose.html","titel":"C8 — DCPError","anker":"c8-dcperror","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C9 — Importfehler","anker":"c9-importfehler","text":""},{"seite":"anhang-fehlerdiagnose.html","titel":"C10 — Verdächtig guter Backtest","anker":"c10-verdächtig-guter-backtest","text":"Faustregel: Eine Sharpe Ratio über 2 bei einer einfachen Strategie ist fast immer ein Fehler, kein Fund."},{"seite":"anhang-fehlerdiagnose.html","titel":"Prüfreihenfolge","anker":"prüfreihenfolge","text":"1. Lookahead-Selbsttest."},{"seite":"anhang-fehlerdiagnose.html","titel":"C11 — Vertauschte Spalten","anker":"c11-vertauschte-spalten","text":"Symptom. Ergebnisse sind plausibel, aber falsch beschriftet — oder eine Sektorgrenze greift auf die falschen Titel."},{"seite":"anhang-fehlerdiagnose.html","titel":"Die goldene Diagnoseregel","anker":"die-goldene-diagnoseregel","text":""},{"seite":"anhang-spickzettel.html","titel":"Anhang D: Spickzettel der Solver","anker":null,"text":""},{"seite":"anhang-spickzettel.html","titel":"D1 — SciPy: linprog und milp","anker":"d1-scipy-linprog-und-milp","text":"Wofür. Die Einstiegsschicht: keine zusätzliche Installation, HiGHS als Unterbau, ideal für lineare und gemischt-ganzzahlige Probleme in Matrixform. Wofür nicht: alles, was sich nic"},{"seite":"anhang-spickzettel.html","titel":"Lineares Programm","anker":"lineares-programm","text":""},{"seite":"anhang-spickzettel.html","titel":"Ganzzahlig: milp","anker":"ganzzahlig-milp","text":""},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine","text":""},{"seite":"anhang-spickzettel.html","titel":"D2 — HiGHS über highspy","anker":"d2-highs-über-highspy","text":"Wofür. Derselbe Solver wie unter SciPy, aber direkt gesteuert: Optionen, Warm-Starts, inkrementelles Ändern eines bestehenden Modells. Wofür nicht: schnelles Hinschreiben — die CSR"},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-1","text":""},{"seite":"anhang-spickzettel.html","titel":"D3 — OR-Tools: pywraplp","anker":"d3-or-tools-pywraplp","text":"Wofür. Bequeme algebraische Schreibweise für LP und MILP mit umschaltbarem Backend (GLOP, SCIP, CBC, SAT). Wofür nicht: Scheduling und kombinatorische Bedingungen — dafür ist CP-SA"},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-2","text":""},{"seite":"anhang-spickzettel.html","titel":"D4 — CP-SAT: cp_model","anker":"d4-cp-sat-cp_model","text":"Wofür. Scheduling, Zuordnung, Reihenfolgen, alles Kombinatorische mit globalen Bedingungen. Wofür nicht: stetige Größen — CP-SAT rechnet ausschließlich ganzzahlig. Wer Nachkommaste"},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-3","text":""},{"seite":"anhang-spickzettel.html","titel":"D5 — CVXPY","anker":"d5-cvxpy","text":"Wofür. Konvexe Probleme: quadratische Ziele, Normen, CVaR, alles mit Regularisierungstermen. Wofür nicht: große kombinatorische Modelle — der Aufbau der Ausdrücke wird dann selbst "},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-4","text":""},{"seite":"anhang-spickzettel.html","titel":"D6 — Modellierungssprachen: Pyomo und Linopy","anker":"d6-modellierungssprachen-pyomo-und-linopy","text":"Wofür. Beide trennen Modell von Solver: dasselbe Modell läuft ohne Änderung unter HiGHS, CBC, Gurobi. Pyomo denkt in Mengen und Indizes wie eine mathematische Formulierung; Linopy "},{"seite":"anhang-spickzettel.html","titel":"Pyomo","anker":"pyomo","text":""},{"seite":"anhang-spickzettel.html","titel":"Linopy","anker":"linopy","text":""},{"seite":"anhang-spickzettel.html","titel":"Die drei häufigsten Stolpersteine","anker":"die-drei-häufigsten-stolpersteine-5","text":""},{"seite":"anhang-spickzettel.html","titel":"Die gemeinsame Regel","anker":"die-gemeinsame-regel","text":"Alle sechs Seiten haben denselben längsten Abschnitt: die Statusauswertung. Das ist kein Zufall. Ein Solveraufruf hat nie zwei Ausgänge, sondern mindestens fünf — optimal, zulässig"},{"seite":"anhang-glossar.html","titel":"Anhang E: Glossar","anker":null,"text":""},{"seite":"anhang-literatur.html","titel":"Anhang F: Literaturverzeichnis","anker":null,"text":""},{"seite":"anhang-literatur.html","titel":"Grundlagen und Standardwerke des Operations Research","anker":"grundlagen-und-standardwerke-des-operations-research","text":"Zu Kapitel 1 und Kapitel 2."},{"seite":"anhang-literatur.html","titel":"Modellierung in Python: Bibliotheken und Modellierungsschichten","anker":"modellierung-in-python-bibliotheken-und-modellierungsschichten","text":"Zu Kapitel 3."},{"seite":"anhang-literatur.html","titel":"Lineare und ganzzahlige Optimierung","anker":"lineare-und-ganzzahlige-optimierung","text":"Zu Kapitel 5 und Kapitel 6."},{"seite":"anhang-literatur.html","titel":"Moderne Solver: Implementierung, Vergleich und Benchmarks","anker":"moderne-solver-implementierung-vergleich-und-benchmarks","text":"Zu Kapitel 3 und Anhang D. Neuer Abschnitt: Das Buch vergleicht durchgehend Solver, die Literatur dazu stand bisher verstreut."},{"seite":"anhang-literatur.html","titel":"Constraint Programming und Scheduling","anker":"constraint-programming-und-scheduling","text":"Zu Kapitel 7."},{"seite":"anhang-literatur.html","titel":"Graphen, Flüsse und Tourenplanung","anker":"graphen-flüsse-und-tourenplanung","text":"Zu Kapitel 8. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Metaheuristiken","anker":"metaheuristiken","text":"Zu Kapitel 9. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Spaltengenerierung und Dekomposition","anker":"spaltengenerierung-und-dekomposition","text":"Zu Kapitel 10. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Konvexe und nichtlineare Optimierung","anker":"konvexe-und-nichtlineare-optimierung","text":"Zu Kapitel 11."},{"seite":"anhang-literatur.html","titel":"Optimierung unter Unsicherheit: stochastisch, robust, Chance Constraints","anker":"optimierung-unter-unsicherheit-stochastisch-robust-chance-constraints","text":"Zu Kapitel 12 und Kapitel 17. Aus dem früheren Block „Konvexe, nichtlineare und robuste Optimierung” herausgelöst und erweitert."},{"seite":"anhang-literatur.html","titel":"Dynamische Programmierung und sequenzielle Entscheidungen","anker":"dynamische-programmierung-und-sequenzielle-entscheidungen","text":"Zu Kapitel 13. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Mehrkriterielle Optimierung","anker":"mehrkriterielle-optimierung","text":"Zu Kapitel 14. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Lernbasierte Optimierung: maschinelles Lernen und OR","anker":"lernbasierte-optimierung-maschinelles-lernen-und-or","text":"Zu Kapitel 15. Neuer Abschnitt — im Buch als eigenes Kapitel behandelt, in der Literaturliste bisher gar nicht vertreten."},{"seite":"anhang-literatur.html","titel":"Supply Chain, Energie und Produktionsplanung","anker":"supply-chain-energie-und-produktionsplanung","text":"Zu Kapitel 16 und Kapitel 17. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Quantitative Finanzmathematik","anker":"quantitative-finanzmathematik","text":"Zu Kapitel 18, Kapitel 19, Kapitel 20 und Kapitel 21."},{"seite":"anhang-literatur.html","titel":"Praxis: Betrieb, Test und Auslieferung von Optimierungsmodellen","anker":"praxis-betrieb-test-und-auslieferung-von-optimierungsmodellen","text":"Zu Kapitel 22 und Kapitel 23. Neuer Abschnitt."},{"seite":"anhang-literatur.html","titel":"Software, Dokumentation und Datenquellen","anker":"software-dokumentation-und-datenquellen","text":""},{"seite":"anhang-literatur.html","titel":"Verbände, Normen und Regulierung","anker":"verbände-normen-und-regulierung","text":""},{"seite":"anhang-literatur.html","titel":"Änderungsprotokoll","anker":"änderungsprotokoll","text":"Stand: September 2026. Überarbeitung des Literaturverzeichnisses gegenüber der Vorgängerfassung."},{"seite":"anhang-literatur.html","titel":"Prüfung gegen Crossref","anker":"prüfung-gegen-crossref","text":"Alle Einträge wurden einzeln gegen die Crossref-API geprüft — bei einem Literaturverzeichnis ist eine erfundene oder falsch zitierte Quelle der schwerste Fehler, weil der Leser sie"}];
diff --git a/OR_HTML_04/bilder_04/kap_dekomposition_regelkreis.svg b/OR_HTML_04/bilder_04/kap_dekomposition_regelkreis.svg
new file mode 100644
index 0000000..702ed68
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_dekomposition_regelkreis.svg
@@ -0,0 +1,2284 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_dp_almgren_chriss.svg b/OR_HTML_04/bilder_04/kap_dp_almgren_chriss.svg
new file mode 100644
index 0000000..58db6f8
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_dp_almgren_chriss.svg
@@ -0,0 +1,1909 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_einfuehrung_kombinatorik.svg b/OR_HTML_04/bilder_04/kap_einfuehrung_kombinatorik.svg
new file mode 100644
index 0000000..adcaafb
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_einfuehrung_kombinatorik.svg
@@ -0,0 +1,2440 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_graphen_subtouren.svg b/OR_HTML_04/bilder_04/kap_graphen_subtouren.svg
new file mode 100644
index 0000000..ae0cf36
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_graphen_subtouren.svg
@@ -0,0 +1,2026 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_lp_entartung.svg b/OR_HTML_04/bilder_04/kap_lp_entartung.svg
new file mode 100644
index 0000000..53403a1
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_lp_entartung.svg
@@ -0,0 +1,3309 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_milp_big_m.svg b/OR_HTML_04/bilder_04/kap_milp_big_m.svg
new file mode 100644
index 0000000..9b9bd3c
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_milp_big_m.svg
@@ -0,0 +1,3483 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_modellierung_zielgroessen.svg b/OR_HTML_04/bilder_04/kap_modellierung_zielgroessen.svg
new file mode 100644
index 0000000..d0d74cb
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_modellierung_zielgroessen.svg
@@ -0,0 +1,1556 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_oekosystem_laufzeit.svg b/OR_HTML_04/bilder_04/kap_oekosystem_laufzeit.svg
new file mode 100644
index 0000000..8c7a8cb
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_oekosystem_laufzeit.svg
@@ -0,0 +1,1820 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_prognose_entscheidungsguete.svg b/OR_HTML_04/bilder_04/kap_prognose_entscheidungsguete.svg
new file mode 100644
index 0000000..50542a2
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_prognose_entscheidungsguete.svg
@@ -0,0 +1,1888 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_supplychain_lastabwurf.svg b/OR_HTML_04/bilder_04/kap_supplychain_lastabwurf.svg
new file mode 100644
index 0000000..43bdd44
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_supplychain_lastabwurf.svg
@@ -0,0 +1,1972 @@
+
+
+
diff --git a/OR_HTML_04/bilder_04/kap_unsicherheit_durchschnitt.svg b/OR_HTML_04/bilder_04/kap_unsicherheit_durchschnitt.svg
new file mode 100644
index 0000000..0bae4ca
--- /dev/null
+++ b/OR_HTML_04/bilder_04/kap_unsicherheit_durchschnitt.svg
@@ -0,0 +1,2542 @@
+
+
+
diff --git a/OR_HTML_04/dekomposition.html b/OR_HTML_04/dekomposition.html
index 15f4fae..c9f9931 100644
--- a/OR_HTML_04/dekomposition.html
+++ b/OR_HTML_04/dekomposition.html
@@ -230,6 +230,11 @@
Fange mit wenigen Mustern an. Frage nach jeder Lösung, ob es ein noch nicht bekanntes Muster gibt, das sich lohnen würde — und wenn ja, nimm nur dieses eine dazu.
Die Frage „lohnt sich noch ein Muster?” beantworten die Dualwerte des Master-LPs. Der Dualwert \pi_i zur Bedarfszeile i ist genau der Schattenpreis aus Abschnitt 5.6: Er sagt, wie viele Rollen ein zusätzliches Stück der Breite i kostet.
+
+
+Abb. 10.1: Der Kreislauf zwischen Master-LP und Pricing-Problem. Erzeugt von bilder_04/erzeuge_spaltengenerierung_flow.py.
+
+
Was Sie in der Abbildung sehen. Die Information fließt in beide Richtungen: Preise nach rechts, Muster nach links. Der Ausgang unten wird erst geöffnet, wenn das Pricing nichts mehr findet — und genau das ist der Optimalitätsbeweis.
Ein neues Muster a lohnt sich, wenn seine reduzierten Kosten negativ sind:
1 - \sum_i \pi_i\, a_i < 0
diff --git a/OR_HTML_04/dynamische-programmierung.html b/OR_HTML_04/dynamische-programmierung.html
index 9688580..5dfaa16 100644
--- a/OR_HTML_04/dynamische-programmierung.html
+++ b/OR_HTML_04/dynamische-programmierung.html
@@ -776,6 +776,11 @@ C(n_t, X_t) = \underbrace{\eta\,n_t^2}_{\text{Marktauswirkung}} \;+\; \underbrac
plt.savefig(ziel, dpi=150)print(f"\nDiagramm gespeichert unter '{ziel}'")print("="*84)
+
+
+Abb. 13.2: Drei Wege, dieselbe Position abzubauen, mit den Kosten aus periodenkosten(). Erzeugt von bilder_04/erzeuge_almgren_chriss.py.
+
+
Was Sie in der Abbildung sehen. Die optimale Kurve liegt nicht in der Mitte zwischen den Extremen, sondern ist gekrümmt: vorne mehr, hinten weniger. Diese Krümmung ist die Antwort auf die Frage, wie teuer Eile gegen Warten steht.
Der springende Punkt: Zwischen n = 15 (22 Minuten, machbar) und n = 20 (77 Jahre, hoffnungslos) liegen nur fünf zusätzliche Aufträge. Es gibt keine sanfte Verschlechterung — es gibt eine Wand.
+
+
+Abb. 1.2: Rechenzeit bei einer Milliarde geprüften Reihenfolgen je Sekunde. Alle drei Kurven stehen auf derselben Achse — deshalb kleben n^2 und n^3 am unteren Rand, während n! das Bild verlässt. Erzeugt von bilder_04/erzeuge_kombinatorik_wand.py.
+
+
Was Sie in der Abbildung sehen. Der markierte Streifen zwischen n = 15 und n = 20 ist der eigentliche Befund: Dort wird aus einer Kaffeepause ein Menschenleben. Wer eine Maschine kauft, die tausendmal schneller rechnet, verschiebt diese Wand um genau zwei Aufträge.
Und die Rechnung ist noch geschönt: Ein schnellerer Rechner hilft praktisch nicht. Selbst eine Beschleunigung um den Faktor eine Million verschiebt die Grenze von n=20 nur auf etwa n=24. Gegen kombinatorisches Wachstum ist Hardware machtlos.
Das folgende Programm macht diesen Effekt erfahrbar. Es löst dasselbe Zuordnungsproblem zweimal — einmal durch vollständiges Durchprobieren, einmal mit einem OR-Solver — und vergleicht die Laufzeiten.
#!/usr/bin/env python3
@@ -522,8 +527,8 @@ Der Solver löst dieselbe Instanz in Sekundenbruchteilen.
1.6 Die vier universellen Bausteine jedes OR-Problems
Dies ist der wichtigste Abschnitt des Kapitels. Jedes Optimierungsproblem der Welt lässt sich — unabhängig von der Branche — auf vier Elemente reduzieren. Wenn Sie später vor einem neuen Problem sitzen, ist dies Ihre Checkliste.
-
-Abb. 1.2: Die vier universellen Bausteine eines OR-Modells
+
+Abb. 1.3: Die vier universellen Bausteine eines OR-Modells
Baustein 1 — Entscheidungsvariablen (x)
Die Stellschrauben des Modells: Werte, die der Algorithmus aktiv festlegen darf.
Der springende Punkt: Zwischen n = 15 (22 Minuten, machbar) und n = 20 (77 Jahre, hoffnungslos) liegen nur fünf zusätzliche Aufträge. Es gibt keine sanfte Verschlechterung — es gibt eine Wand.
+
+
+Abb. 1.2: Rechenzeit bei einer Milliarde geprüften Reihenfolgen je Sekunde. Alle drei Kurven stehen auf derselben Achse — deshalb kleben n^2 und n^3 am unteren Rand, während n! das Bild verlässt. Erzeugt von bilder_04/erzeuge_kombinatorik_wand.py.
+
+
Was Sie in der Abbildung sehen. Der markierte Streifen zwischen n = 15 und n = 20 ist der eigentliche Befund: Dort wird aus einer Kaffeepause ein Menschenleben. Wer eine Maschine kauft, die tausendmal schneller rechnet, verschiebt diese Wand um genau zwei Aufträge.
Und die Rechnung ist noch geschönt: Ein schnellerer Rechner hilft praktisch nicht. Selbst eine Beschleunigung um den Faktor eine Million verschiebt die Grenze von n=20 nur auf etwa n=24. Gegen kombinatorisches Wachstum ist Hardware machtlos.
Das folgende Programm macht diesen Effekt erfahrbar. Es löst dasselbe Zuordnungsproblem zweimal — einmal durch vollständiges Durchprobieren, einmal mit einem OR-Solver — und vergleicht die Laufzeiten.
#!/usr/bin/env python3
@@ -3561,8 +3566,8 @@ Der Solver löst dieselbe Instanz in Sekundenbruchteilen.
1.6 Die vier universellen Bausteine jedes OR-Problems
Dies ist der wichtigste Abschnitt des Kapitels. Jedes Optimierungsproblem der Welt lässt sich — unabhängig von der Branche — auf vier Elemente reduzieren. Wenn Sie später vor einem neuen Problem sitzen, ist dies Ihre Checkliste.
-
-Abb. 1.2: Die vier universellen Bausteine eines OR-Modells
+
+Abb. 1.3: Die vier universellen Bausteine eines OR-Modells
Baustein 1 — Entscheidungsvariablen (x)
Die Stellschrauben des Modells: Werte, die der Algorithmus aktiv festlegen darf.
Lesen Sie die letzte Spalte. Bei 62 500 Variablen verbringt Variante A 69 % der Gesamtzeit damit, das Modell überhaupt aufzuschreiben — und nur 31 % mit Rechnen. Die vektorisierten Varianten kehren das Verhältnis um: 1 % Aufbau, 99 % Solver. Erst dort ist ein schnellerer Solver überhaupt die richtige Stellschraube.
+
+
+Abb. 3.2: Dieselbe Aufgabe, zwei Arten sie aufzuschreiben — aufgeteilt in Aufbauzeit (Python) und Lösezeit (C++). Werte aus der Messung oben. Erzeugt von bilder_04/erzeuge_laufzeit_aufbau.py.
+
+
Was Sie in der Abbildung sehen. Der rote Anteil ist die Zeit, in der der Solver noch gar nicht rechnet. Bei Variante A wächst er mit dem Modell, bei Variante C verschwindet er — dieselbe Mathematik, nur anders aufgeschrieben.
💻 Code-Durchgang
@@ -7381,6 +7391,7 @@ Es muss also ausgewaehlt werden. 3 der Kunden sind Stammkunden:
"Maschinen besser auslasten" 205,000 54,000 100% 4 1 5
"Deckungsbeitrag maximieren" 222,000 78,500 100% 2 1 8
+
Der Umsatzplan bringt 5,000 EUR mehr Umsatz und 12,500 EUR WENIGER
Deckungsbeitrag. Fuer 5,000 EUR Umsatz werden also 12,500 EUR Ergebnis
aufgegeben - und 5 von 6 Stammkundenauftraegen dazu.
@@ -7454,7 +7465,11 @@ Drei Dinge, die deshalb vor dem ersten Modell geklaert gehoeren:
zwar genau dann, wenn ein besonders grosser Auftrag hereinkommt.
Weiche Regeln antworten auch dann noch.
====================================================================================
-
Teil 1: Drei Ziele, drei Pläne
+
+
+Abb. 4.1: Die drei Pläne aus der Tabelle, je Achse auf den besten der drei bezogen. Erzeugt von bilder_04/erzeuge_zielgroessen_radar.py.
+
+
Was Sie in der Abbildung sehen. Jeder Plan gewinnt auf seiner eigenen Achse — das ist keine Überraschung, sondern die Definition. Interessant ist, was daneben passiert: Der Auslastungsplan liegt bei der Auslastung gleichauf mit den anderen und verliert beim Deckungsbeitrag ein knappes Drittel. ### Teil 1: Drei Ziele, drei Pläne
5.9 Wann Schattenpreise lügen: Entartung und Toleranzen
Der vorige Abschnitt hat gezeigt, wie wertvoll Schattenpreise sind. Dieser zeigt die zwei Fälle, in denen sie eine Entscheidung nicht tragen — und wie man beide erkennt, bevor jemand auf ihrer Grundlage eine Maschine kauft.
+
+
+Abb. 5.3: Links laufen drei Geraden durch dieselbe Ecke — eine mehr, als zwei Dimensionen brauchen. Rechts die Folge: Der Schattenpreis ist keine Zahl mehr, sondern eine Spanne. Erzeugt von bilder_04/erzeuge_entartung_polyeder.py.
+
+
Was Sie in der Abbildung sehen. Jeder Wert innerhalb der farbigen Balken erfüllt die Optimalitätsbedingungen. Zwei Solver dürfen also verschiedene Schattenpreise melden und haben beide recht — die Frage „was ist eine Stunde wert?” hat hier schlicht keine eindeutige Antwort.
Fall 1: Entartung
Erinnern Sie sich an Abschnitt 2.4: In zwei Dimensionen legen zwei sich schneidende Geraden eine Ecke fest, in drei Dimensionen drei Ebenen, allgemein n Restriktionen bei n Variablen. Was passiert, wenn in einer Ecke mehr Nebenbedingungen aktiv sind als das Problem Variablen hat?
Geometrisch: Drei Geraden laufen zufällig durch denselben Punkt. Die Ecke ist immer noch eine Ecke — aber sie ist überbestimmt. Man nennt das Entartung (Degeneriertheit), und sie ist in der Praxis nicht die Ausnahme, sondern die Regel: Sie entsteht überall dort, wo Kapazitäten aus derselben Planung stammen und deshalb glatt aufeinander passen — Schichtlängen, Chargengrößen, runde Vertragsmengen.
@@ -9669,6 +9689,11 @@ Loesung eine Nebenbedingung verletzt. 'Verlust' = Abstand zum exakten Op
6.5 Modellierungstricks: Big-M und logische Bedingungen
Hier kommt das Handwerkszeug, das MILP so mächtig macht: Man übersetzt Geschäftsregeln in lineare Ungleichungen — mithilfe binärer Hilfsvariablen y \in \{0,1\} und einer hinreichend großen Konstante M.
+
+
+Abb. 6.3: Dieselbe Bedingung x \le M\,y, zwei Zahlen für M. Gezeigt ist die LP-Relaxation — also das, was der Solver sieht, bevor y ganzzahlig wird. Erzeugt von bilder_04/erzeuge_big_m_vergleich.py.
+
+
Was Sie in der Abbildung sehen. Für y \in \{0,1\} sind beide Modelle gleichwertig; die beiden blauen Punkte stimmen überein. Verschieden ist nur, was dazwischen erlaubt ist — und rechts genügt bereits y = 0{,}08, um die volle Kapazität freizugeben.
Muster 1 — Fixkosten / Aktivierungsschalter
Regel: Wird Maschine j genutzt (x_j > 0), fallen Rüstkosten F_j an.
Die Touren sind aus demselben Grund Luftlinien und keine Straßenrouten: Das Modell kennt keine Straßen, es rechnet mit den Abständen der Distanzmatrix. Eine Linie, die einer echten Straße folgte, wäre hübscher und würde eine Genauigkeit vortäuschen, die das Modell nicht hat. Wer Straßenentfernungen braucht, ersetzt die Matrix — Abschnitt 8.7 sagt, was dabei zu beachten ist.
Kurzzyklen verhindern
Ein naives Modell erlaubt Subtouren: isolierte Kreise, die das Depot nie anfahren. Die klassische Gegenmaßnahme ist die MTZ-Formulierung nach Miller, Tucker und Zemlin. Man führt Rangvariablen u_i ein (die Position des Knotens in der Tour):
+
+
+Abb. 8.3: Links eine Lösung, die jede Gradbedingung erfüllt und trotzdem unbrauchbar ist; rechts dieselbe Instanz mit Kurzzyklus-Bedingungen. Erzeugt von bilder_04/erzeuge_vrp_subtours.py.
+
+
Was Sie in der Abbildung sehen. Links wird jeder Kunde genau einmal angefahren — das Modell hat also gerechnet, was man ihm aufgeschrieben hat. Was fehlt, ist die Bedingung, an die man beim Aufschreiben nicht denkt: dass jede Tour am Depot beginnen muss.
u_i - u_j + C \cdot x_{ij} \le C - d_j \qquad \forall i \ne j
@@ -15397,6 +15427,11 @@ Abstand zum Optimum.
Fange mit wenigen Mustern an. Frage nach jeder Lösung, ob es ein noch nicht bekanntes Muster gibt, das sich lohnen würde — und wenn ja, nimm nur dieses eine dazu.
Die Frage „lohnt sich noch ein Muster?” beantworten die Dualwerte des Master-LPs. Der Dualwert \pi_i zur Bedarfszeile i ist genau der Schattenpreis aus Abschnitt 5.6: Er sagt, wie viele Rollen ein zusätzliches Stück der Breite i kostet.
+
+
+Abb. 10.1: Der Kreislauf zwischen Master-LP und Pricing-Problem. Erzeugt von bilder_04/erzeuge_spaltengenerierung_flow.py.
+
+
Was Sie in der Abbildung sehen. Die Information fließt in beide Richtungen: Preise nach rechts, Muster nach links. Der Ausgang unten wird erst geöffnet, wenn das Pricing nichts mehr findet — und genau das ist der Optimalitätsbeweis.
Ein neues Muster a lohnt sich, wenn seine reduzierten Kosten negativ sind:
1 - \sum_i \pi_i\, a_i < 0
@@ -17503,6 +17538,11 @@ q^{*} = \frac{c_{\text{zu wenig}}}{c_{\text{zu wenig}} + c_{\text{zu viel}}}
print("\nDas Optimum liegt exakt auf einem Szenariowert (250 = 'Volatil'),")print("nicht beim Mittelwert 225 - typisch fuer asymmetrische Kostenfunktionen.")
+
+
+Abb. 12.1: Erwartete Gesamtkosten über allen Bestellmengen, gerechnet aus den drei Szenarien der Handrechnung. Erzeugt von bilder_04/erzeuge_fluch_durchschnitt.py.
+
+
Was Sie in der Abbildung sehen. Die Kurve ist nicht symmetrisch: Sie fällt links flach und steigt rechts steil, weil Fehlmenge 120 € kostet und Überschuss nur 5 €. Ihr tiefster Punkt liegt deshalb rechts vom Erwartungswert — nicht auf ihm.
Erwartete Ausgabe:
======================================================================
DER FLUCH DES DURCHSCHNITTS
@@ -17530,8 +17570,8 @@ nicht beim Mittelwert 225 - typisch fuer asymmetrische Kostenfunktionen.<
Die vier Ansätze im Überblick
-
-Abb. 12.1: Ansätze für Optimierung unter Unsicherheit
+
+Abb. 12.2: Ansätze für Optimierung unter Unsicherheit
@@ -19113,6 +19153,11 @@ C(n_t, X_t) = \underbrace{\eta\,n_t^2}_{\text{Marktauswirkung}} \;+\; \underbrac
plt.savefig(ziel, dpi=150)print(f"\nDiagramm gespeichert unter '{ziel}'")print("="*84)
+
+
+Abb. 13.2: Drei Wege, dieselbe Position abzubauen, mit den Kosten aus periodenkosten(). Erzeugt von bilder_04/erzeuge_almgren_chriss.py.
+
+
Was Sie in der Abbildung sehen. Die optimale Kurve liegt nicht in der Mitte zwischen den Extremen, sondern ist gekrümmt: vorne mehr, hinten weniger. Diese Krümmung ist die Antwort auf die Frage, wie teuer Eile gegen Warten steht.
Erwartete Ausgabe:
====================================================================================
OPTIMALE MEHRPERIODIGE ORDER-EXECUTION (BELLMAN DP)
@@ -20326,6 +20371,7 @@ Training: Tag 1 bis 1000. Bewertung: die restlichen 4000 Tage.
bester MSE: bestelle die Punktprognose
beste Kosten: Quantilregression aufs kritische Quantil
+
Das Verfahren mit dem besten MSE hat die HOECHSTEN Kosten, und das
Verfahren mit den besten Kosten hat einen um 13% SCHLECHTEREN MSE.
Wer Prognosemodelle nach MSE auswaehlt, waehlt hier das falsche.
@@ -20400,7 +20446,11 @@ erfordert Bibliotheken wie cvxpylayers. Die dritte Zeile der Tabelle
oben ist seine einfachste denkbare Form: ein einziger Parameter, auf
Kosten statt auf Fehler trainiert.
====================================================================================
-
+
+
+Abb. 15.1: Dieselben vier Verfahren, zwei Maßstäbe. Grün ist jeweils der beste Wert. Erzeugt von bilder_04/erzeuge_predict_vs_optimize.py.
+
+
Was Sie in der Abbildung sehen. Links und rechts gewinnt nicht dasselbe Verfahren. Die Punktprognose hat den besten Prognosefehler und die höchsten Kosten — beide Maßstäbe messen etwas anderes, und nur einer davon steht am Ende in der Bilanz.
15.5 Der Befund
@@ -22081,10 +22131,15 @@ Was Versorgungssicherheit kostet
Der Erwartungswert-Plan kostet in der Wirklichkeit 149 % mehr, und sein schlimmster Tag ist sechsmal so teuer.
+
+
+Abb. 17.1: Die 40 Szenarien einzeln, aufsteigend nach Kosten. Punkte markieren Szenarien mit Lastabwurf. Erzeugt von bilder_04/erzeuge_lastabwurf_verteilung.py.
+
+
Was Sie in der Abbildung sehen. Der Erwartungswert-Plan ist in den ruhigen Szenarien tatsächlich der billigere — die rote Kurve verläuft links von der grünen. Er kippt erst rechts, und zwar so weit, dass der Mittelwert das Vorzeichen wechselt.
Wofür genau? Die Summendifferenz von 523 514 € sagt noch nicht, wo sie entsteht. Zerlegt man sie nach Kostenarten, wird aus dem Befund eine Aussage, die man vorlegen kann:
-
-Abb. 17.1: Wofür der Erwartungswert-Plan 149 % mehr bezahlt
+
+Abb. 17.2: Wofür der Erwartungswert-Plan 149 % mehr bezahlt
Drei Dinge stehen darin, die die Tabelle nicht zeigt. Die Anfahrkosten sind in beiden Plänen gleich (58 000 €) — der Erwartungswert-Plan spart also nicht dort, wo man es vermuten würde. Er spart 12 725 € Brennstoff, weil er weniger Blockstunden vorhält. Und er bezahlt dafür 536 239 € Lastabwurf: das 42-fache seiner Ersparnis.
Genau diese Gegenüberstellung ist es, die eine Investitionsentscheidung trägt. „149 % mehr” ist eine Zahl, über die man streiten kann; „wir sparen 12 725 € und riskieren dafür 536 239 €” ist eine, über die man entscheidet.
Die Touren sind aus demselben Grund Luftlinien und keine Straßenrouten: Das Modell kennt keine Straßen, es rechnet mit den Abständen der Distanzmatrix. Eine Linie, die einer echten Straße folgte, wäre hübscher und würde eine Genauigkeit vortäuschen, die das Modell nicht hat. Wer Straßenentfernungen braucht, ersetzt die Matrix — Abschnitt 8.7 sagt, was dabei zu beachten ist.
Kurzzyklen verhindern
Ein naives Modell erlaubt Subtouren: isolierte Kreise, die das Depot nie anfahren. Die klassische Gegenmaßnahme ist die MTZ-Formulierung nach Miller, Tucker und Zemlin. Man führt Rangvariablen u_i ein (die Position des Knotens in der Tour):
+
+
+Abb. 8.3: Links eine Lösung, die jede Gradbedingung erfüllt und trotzdem unbrauchbar ist; rechts dieselbe Instanz mit Kurzzyklus-Bedingungen. Erzeugt von bilder_04/erzeuge_vrp_subtours.py.
+
+
Was Sie in der Abbildung sehen. Links wird jeder Kunde genau einmal angefahren — das Modell hat also gerechnet, was man ihm aufgeschrieben hat. Was fehlt, ist die Bedingung, an die man beim Aufschreiben nicht denkt: dass jede Tour am Depot beginnen muss.
u_i - u_j + C \cdot x_{ij} \le C - d_j \qquad \forall i \ne j
5.9 Wann Schattenpreise lügen: Entartung und Toleranzen
Der vorige Abschnitt hat gezeigt, wie wertvoll Schattenpreise sind. Dieser zeigt die zwei Fälle, in denen sie eine Entscheidung nicht tragen — und wie man beide erkennt, bevor jemand auf ihrer Grundlage eine Maschine kauft.
+
+
+Abb. 5.3: Links laufen drei Geraden durch dieselbe Ecke — eine mehr, als zwei Dimensionen brauchen. Rechts die Folge: Der Schattenpreis ist keine Zahl mehr, sondern eine Spanne. Erzeugt von bilder_04/erzeuge_entartung_polyeder.py.
+
+
Was Sie in der Abbildung sehen. Jeder Wert innerhalb der farbigen Balken erfüllt die Optimalitätsbedingungen. Zwei Solver dürfen also verschiedene Schattenpreise melden und haben beide recht — die Frage „was ist eine Stunde wert?” hat hier schlicht keine eindeutige Antwort.
Fall 1: Entartung
Erinnern Sie sich an Abschnitt 2.4: In zwei Dimensionen legen zwei sich schneidende Geraden eine Ecke fest, in drei Dimensionen drei Ebenen, allgemein n Restriktionen bei n Variablen. Was passiert, wenn in einer Ecke mehr Nebenbedingungen aktiv sind als das Problem Variablen hat?
Geometrisch: Drei Geraden laufen zufällig durch denselben Punkt. Die Ecke ist immer noch eine Ecke — aber sie ist überbestimmt. Man nennt das Entartung (Degeneriertheit), und sie ist in der Praxis nicht die Ausnahme, sondern die Regel: Sie entsteht überall dort, wo Kapazitäten aus derselben Planung stammen und deshalb glatt aufeinander passen — Schichtlängen, Chargengrößen, runde Vertragsmengen.
diff --git a/OR_HTML_04/milp.html b/OR_HTML_04/milp.html
index 8bfd0bf..f7ff495 100644
--- a/OR_HTML_04/milp.html
+++ b/OR_HTML_04/milp.html
@@ -395,6 +395,11 @@ Loesung eine Nebenbedingung verletzt. 'Verlust' = Abstand zum exakten Op
6.5 Modellierungstricks: Big-M und logische Bedingungen
Hier kommt das Handwerkszeug, das MILP so mächtig macht: Man übersetzt Geschäftsregeln in lineare Ungleichungen — mithilfe binärer Hilfsvariablen y \in \{0,1\} und einer hinreichend großen Konstante M.
+
+
+Abb. 6.3: Dieselbe Bedingung x \le M\,y, zwei Zahlen für M. Gezeigt ist die LP-Relaxation — also das, was der Solver sieht, bevor y ganzzahlig wird. Erzeugt von bilder_04/erzeuge_big_m_vergleich.py.
+
+
Was Sie in der Abbildung sehen. Für y \in \{0,1\} sind beide Modelle gleichwertig; die beiden blauen Punkte stimmen überein. Verschieden ist nur, was dazwischen erlaubt ist — und rechts genügt bereits y = 0{,}08, um die volle Kapazität freizugeben.
Muster 1 — Fixkosten / Aktivierungsschalter
Regel: Wird Maschine j genutzt (x_j > 0), fallen Rüstkosten F_j an.
diff --git a/OR_HTML_04/modellierung.html b/OR_HTML_04/modellierung.html
index e150edc..3dcefb8 100644
--- a/OR_HTML_04/modellierung.html
+++ b/OR_HTML_04/modellierung.html
@@ -521,6 +521,7 @@ Es muss also ausgewaehlt werden. 3 der Kunden sind Stammkunden:
"Maschinen besser auslasten" 205,000 54,000 100% 4 1 5
"Deckungsbeitrag maximieren" 222,000 78,500 100% 2 1 8
+
Der Umsatzplan bringt 5,000 EUR mehr Umsatz und 12,500 EUR WENIGER
Deckungsbeitrag. Fuer 5,000 EUR Umsatz werden also 12,500 EUR Ergebnis
aufgegeben - und 5 von 6 Stammkundenauftraegen dazu.
@@ -594,7 +595,11 @@ Drei Dinge, die deshalb vor dem ersten Modell geklaert gehoeren:
zwar genau dann, wenn ein besonders grosser Auftrag hereinkommt.
Weiche Regeln antworten auch dann noch.
====================================================================================
-
Teil 1: Drei Ziele, drei Pläne
+
+
+Abb. 4.1: Die drei Pläne aus der Tabelle, je Achse auf den besten der drei bezogen. Erzeugt von bilder_04/erzeuge_zielgroessen_radar.py.
+
+
Was Sie in der Abbildung sehen. Jeder Plan gewinnt auf seiner eigenen Achse — das ist keine Überraschung, sondern die Definition. Interessant ist, was daneben passiert: Der Auslastungsplan liegt bei der Auslastung gleichauf mit den anderen und verliert beim Deckungsbeitrag ein knappes Drittel. ### Teil 1: Drei Ziele, drei Pläne
Lesen Sie die letzte Spalte. Bei 62 500 Variablen verbringt Variante A 69 % der Gesamtzeit damit, das Modell überhaupt aufzuschreiben — und nur 31 % mit Rechnen. Die vektorisierten Varianten kehren das Verhältnis um: 1 % Aufbau, 99 % Solver. Erst dort ist ein schnellerer Solver überhaupt die richtige Stellschraube.
+
+
+Abb. 3.2: Dieselbe Aufgabe, zwei Arten sie aufzuschreiben — aufgeteilt in Aufbauzeit (Python) und Lösezeit (C++). Werte aus der Messung oben. Erzeugt von bilder_04/erzeuge_laufzeit_aufbau.py.
+
+
Was Sie in der Abbildung sehen. Der rote Anteil ist die Zeit, in der der Solver noch gar nicht rechnet. Bei Variante A wächst er mit dem Modell, bei Variante C verschwindet er — dieselbe Mathematik, nur anders aufgeschrieben.
💻 Code-Durchgang
diff --git a/OR_HTML_04/prognose.html b/OR_HTML_04/prognose.html
index 8e6677b..c184daf 100644
--- a/OR_HTML_04/prognose.html
+++ b/OR_HTML_04/prognose.html
@@ -430,6 +430,7 @@ Training: Tag 1 bis 1000. Bewertung: die restlichen 4000 Tage.
bester MSE: bestelle die Punktprognose
beste Kosten: Quantilregression aufs kritische Quantil
+
Das Verfahren mit dem besten MSE hat die HOECHSTEN Kosten, und das
Verfahren mit den besten Kosten hat einen um 13% SCHLECHTEREN MSE.
Wer Prognosemodelle nach MSE auswaehlt, waehlt hier das falsche.
@@ -504,7 +505,11 @@ erfordert Bibliotheken wie cvxpylayers. Die dritte Zeile der Tabelle
oben ist seine einfachste denkbare Form: ein einziger Parameter, auf
Kosten statt auf Fehler trainiert.
====================================================================================
-
+
+
+Abb. 15.1: Dieselben vier Verfahren, zwei Maßstäbe. Grün ist jeweils der beste Wert. Erzeugt von bilder_04/erzeuge_predict_vs_optimize.py.
+
+
Was Sie in der Abbildung sehen. Links und rechts gewinnt nicht dasselbe Verfahren. Die Punktprognose hat den besten Prognosefehler und die höchsten Kosten — beide Maßstäbe messen etwas anderes, und nur einer davon steht am Ende in der Bilanz.
15.5 Der Befund
diff --git a/OR_HTML_04/supplychain.html b/OR_HTML_04/supplychain.html
index 76c0b45..8327e70 100644
--- a/OR_HTML_04/supplychain.html
+++ b/OR_HTML_04/supplychain.html
@@ -771,10 +771,15 @@ Was Versorgungssicherheit kostet
Der Erwartungswert-Plan kostet in der Wirklichkeit 149 % mehr, und sein schlimmster Tag ist sechsmal so teuer.
+
+
+Abb. 17.1: Die 40 Szenarien einzeln, aufsteigend nach Kosten. Punkte markieren Szenarien mit Lastabwurf. Erzeugt von bilder_04/erzeuge_lastabwurf_verteilung.py.
+
+
Was Sie in der Abbildung sehen. Der Erwartungswert-Plan ist in den ruhigen Szenarien tatsächlich der billigere — die rote Kurve verläuft links von der grünen. Er kippt erst rechts, und zwar so weit, dass der Mittelwert das Vorzeichen wechselt.
Wofür genau? Die Summendifferenz von 523 514 € sagt noch nicht, wo sie entsteht. Zerlegt man sie nach Kostenarten, wird aus dem Befund eine Aussage, die man vorlegen kann:
-
-Abb. 17.1: Wofür der Erwartungswert-Plan 149 % mehr bezahlt
+
+Abb. 17.2: Wofür der Erwartungswert-Plan 149 % mehr bezahlt
Drei Dinge stehen darin, die die Tabelle nicht zeigt. Die Anfahrkosten sind in beiden Plänen gleich (58 000 €) — der Erwartungswert-Plan spart also nicht dort, wo man es vermuten würde. Er spart 12 725 € Brennstoff, weil er weniger Blockstunden vorhält. Und er bezahlt dafür 536 239 € Lastabwurf: das 42-fache seiner Ersparnis.
Genau diese Gegenüberstellung ist es, die eine Investitionsentscheidung trägt. „149 % mehr” ist eine Zahl, über die man streiten kann; „wir sparen 12 725 € und riskieren dafür 536 239 €” ist eine, über die man entscheidet.
diff --git a/OR_HTML_04/unsicherheit.html b/OR_HTML_04/unsicherheit.html
index 040fe87..fb01cbf 100644
--- a/OR_HTML_04/unsicherheit.html
+++ b/OR_HTML_04/unsicherheit.html
@@ -317,6 +317,11 @@ q^{*} = \frac{c_{\text{zu wenig}}}{c_{\text{zu wenig}} + c_{\text{zu viel}}}
print("\nDas Optimum liegt exakt auf einem Szenariowert (250 = 'Volatil'),")print("nicht beim Mittelwert 225 - typisch fuer asymmetrische Kostenfunktionen.")
+
+
+Abb. 12.1: Erwartete Gesamtkosten über allen Bestellmengen, gerechnet aus den drei Szenarien der Handrechnung. Erzeugt von bilder_04/erzeuge_fluch_durchschnitt.py.
+
+
Was Sie in der Abbildung sehen. Die Kurve ist nicht symmetrisch: Sie fällt links flach und steigt rechts steil, weil Fehlmenge 120 € kostet und Überschuss nur 5 €. Ihr tiefster Punkt liegt deshalb rechts vom Erwartungswert — nicht auf ihm.
Erwartete Ausgabe:
======================================================================
DER FLUCH DES DURCHSCHNITTS
@@ -344,8 +349,8 @@ nicht beim Mittelwert 225 - typisch fuer asymmetrische Kostenfunktionen.<
Die vier Ansätze im Überblick
-
-Abb. 12.1: Ansätze für Optimierung unter Unsicherheit
+
+Abb. 12.2: Ansätze für Optimierung unter Unsicherheit
diff --git a/Operations_Research_mit_Python_Version_04.md b/Operations_Research_mit_Python_Version_04.md
index 96dfaec..2d788df 100644
--- a/Operations_Research_mit_Python_Version_04.md
+++ b/Operations_Research_mit_Python_Version_04.md
@@ -868,6 +868,11 @@ Die Behauptung „vollständiges Durchprobieren ist unmöglich“ wird oft aufge
>
> **Der springende Punkt:** Zwischen $n = 15$ (22 Minuten, machbar) und $n = 20$ (77 Jahre, hoffnungslos) liegen nur **fünf zusätzliche Aufträge**. Es gibt keine sanfte Verschlechterung — es gibt eine Wand.
+
+
+**Was Sie in der Abbildung sehen.** Der markierte Streifen zwischen $n = 15$ und $n = 20$ ist der eigentliche Befund: Dort wird aus einer Kaffeepause ein Menschenleben. Wer eine Maschine kauft, die tausendmal schneller rechnet, verschiebt diese Wand um genau zwei Aufträge.
+
Und die Rechnung ist noch geschönt: Ein schnellerer Rechner hilft praktisch nicht. Selbst eine Beschleunigung um den Faktor **eine Million** verschiebt die Grenze von $n=20$ nur auf etwa $n=24$. Gegen kombinatorisches Wachstum ist Hardware machtlos.
Das folgende Programm macht diesen Effekt erfahrbar. Es löst dasselbe Zuordnungsproblem zweimal — einmal durch vollständiges Durchprobieren, einmal mit einem OR-Solver — und vergleicht die Laufzeiten.
@@ -1040,7 +1045,7 @@ Heute treibt OR die Kernsysteme moderner Industrien an:
Dies ist der wichtigste Abschnitt des Kapitels. Jedes Optimierungsproblem der Welt lässt sich — unabhängig von der Branche — auf vier Elemente reduzieren. Wenn Sie später vor einem neuen Problem sitzen, ist dies Ihre Checkliste.
-
+
### Baustein 1 — Entscheidungsvariablen ($x$)
@@ -3904,6 +3909,11 @@ Groesse Variante Aufbau Loesen Aufba
**Lesen Sie die letzte Spalte.** Bei 62 500 Variablen verbringt Variante A **69 % der Gesamtzeit damit, das Modell überhaupt aufzuschreiben** — und nur 31 % mit Rechnen. Die vektorisierten Varianten kehren das Verhältnis um: 1 % Aufbau, 99 % Solver. Erst dort ist ein schnellerer Solver überhaupt die richtige Stellschraube.
+
+
+**Was Sie in der Abbildung sehen.** Der rote Anteil ist die Zeit, in der der Solver noch gar nicht rechnet. Bei Variante A wächst er mit dem Modell, bei Variante C verschwindet er — dieselbe Mathematik, nur anders aufgeschrieben.
+
> **💻 Code-Durchgang**
>
> | Stelle | Was passiert | Warum es zählt |
@@ -4390,6 +4400,7 @@ Es muss also ausgewaehlt werden. 3 der Kunden sind Stammkunden:
"Maschinen besser auslasten" 205,000 54,000 100% 4 1 5
"Deckungsbeitrag maximieren" 222,000 78,500 100% 2 1 8
+
Der Umsatzplan bringt 5,000 EUR mehr Umsatz und 12,500 EUR WENIGER
Deckungsbeitrag. Fuer 5,000 EUR Umsatz werden also 12,500 EUR Ergebnis
aufgegeben - und 5 von 6 Stammkundenauftraegen dazu.
@@ -4465,6 +4476,11 @@ Drei Dinge, die deshalb vor dem ersten Modell geklaert gehoeren:
====================================================================================
```
+
+
+
+**Was Sie in der Abbildung sehen.** Jeder Plan gewinnt auf seiner eigenen Achse — das ist keine Überraschung, sondern die Definition. Interessant ist, was daneben passiert: Der Auslastungsplan liegt bei der Auslastung gleichauf mit den anderen und verliert beim Deckungsbeitrag ein knappes Drittel.
### Teil 1: Drei Ziele, drei Pläne
| Zielgröße | Umsatz | Deckungsbeitrag | Auslastung | abgelehnte Stammaufträge |
@@ -5539,6 +5555,11 @@ Der Zukauf für 18 €/h ist hochprofitabel: Jede zusätzliche Prüfstunde bring
Der vorige Abschnitt hat gezeigt, wie wertvoll Schattenpreise sind. Dieser zeigt die zwei Fälle, in denen sie eine Entscheidung **nicht** tragen — und wie man beide erkennt, bevor jemand auf ihrer Grundlage eine Maschine kauft.
+
+
+**Was Sie in der Abbildung sehen.** Jeder Wert innerhalb der farbigen Balken erfüllt die Optimalitätsbedingungen. Zwei Solver dürfen also verschiedene Schattenpreise melden und haben beide recht — die Frage „was ist eine Stunde wert?" hat hier schlicht keine eindeutige Antwort.
+
### Fall 1: Entartung
Erinnern Sie sich an [Abschnitt 2.4](#sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder): In zwei Dimensionen legen **zwei** sich schneidende Geraden eine Ecke fest, in drei Dimensionen drei Ebenen, allgemein $n$ Restriktionen bei $n$ Variablen. Was passiert, wenn in einer Ecke **mehr** Nebenbedingungen aktiv sind als das Problem Variablen hat?
@@ -6225,6 +6246,11 @@ Zusätzlich fügen Solver **Schnittebenen**`\index{Schnittebenen}`{=latex} (*cut
Hier kommt das Handwerkszeug, das MILP so mächtig macht:`\index{Big-M-Methode}`{=latex} Man übersetzt Geschäftsregeln in lineare Ungleichungen — mithilfe binärer Hilfsvariablen $y \in \{0,1\}$ und einer hinreichend großen Konstante $M$.
+
+
+**Was Sie in der Abbildung sehen.** Für $y \in \{0,1\}$ sind beide Modelle gleichwertig; die beiden blauen Punkte stimmen überein. Verschieden ist nur, was dazwischen erlaubt ist — und rechts genügt bereits $y = 0{,}08$, um die volle Kapazität freizugeben.
+
### Muster 1 — Fixkosten / Aktivierungsschalter
*Regel:* Wird Maschine $j$ genutzt ($x_j > 0$), fallen Rüstkosten $F_j$ an.
@@ -9597,6 +9623,11 @@ Die Touren sind aus demselben Grund **Luftlinien und keine Straßenrouten**: Das
Ein naives Modell erlaubt **Subtouren**`\index{Subtour}`{=latex}: isolierte Kreise, die das Depot nie anfahren. Die klassische Gegenmaßnahme ist die **MTZ-Formulierung**`\index{MTZ-Formulierung}`{=latex} nach Miller, Tucker und Zemlin. Man führt Rangvariablen $u_i$ ein (die Position des Knotens in der Tour):
+
+
+**Was Sie in der Abbildung sehen.** Links wird jeder Kunde genau einmal angefahren — das Modell hat also gerechnet, was man ihm aufgeschrieben hat. Was fehlt, ist die Bedingung, an die man beim Aufschreiben nicht denkt: dass jede Tour am Depot beginnen muss.
+
$$
u_i - u_j + C \cdot x_{ij} \le C - d_j \qquad \forall i \ne j
$$
@@ -11604,6 +11635,11 @@ Die Idee ist alt (Gilmore und Gomory, 1961) und in einem Satz gesagt:
Die Frage „lohnt sich noch ein Muster?" beantworten die **Dualwerte** des Master-LPs. Der Dualwert $\pi_i$ zur Bedarfszeile $i$ ist genau der Schattenpreis aus [Abschnitt 5.6](#sec:lp-dualitaet-und-schattenpreise): Er sagt, wie viele Rollen ein zusätzliches Stück der Breite $i$ kostet.
+
+
+**Was Sie in der Abbildung sehen.** Die Information fließt in beide Richtungen: Preise nach rechts, Muster nach links. Der Ausgang unten wird erst geöffnet, wenn das Pricing nichts mehr findet — und genau das ist der Optimalitätsbeweis.
+
Ein neues Muster $a$ lohnt sich, wenn seine **reduzierten Kosten** negativ sind:
$$
@@ -13507,6 +13543,11 @@ if __name__ == "__main__":
print("nicht beim Mittelwert 225 - typisch fuer asymmetrische Kostenfunktionen.")
```
+
+
+**Was Sie in der Abbildung sehen.** Die Kurve ist nicht symmetrisch: Sie fällt links flach und steigt rechts steil, weil Fehlmenge 120 € kostet und Überschuss nur 5 €. Ihr tiefster Punkt liegt deshalb rechts vom Erwartungswert — nicht auf ihm.
+
**Erwartete Ausgabe:**
```
@@ -13539,7 +13580,7 @@ Kein Rechentrick, sondern brute-force über alle ganzzahligen $x$ von 0 bis 500
### Die vier Ansätze im Überblick
-
+
| | **Monte-Carlo** | **Stochastische Programmierung** | **Robuste Optimierung** | **Chance Constraints** |
| --- | --- | --- | --- | --- |
@@ -15021,6 +15062,11 @@ if __name__ == "__main__":
print("=" * 84)
```
+
+
+**Was Sie in der Abbildung sehen.** Die optimale Kurve liegt nicht in der Mitte zwischen den Extremen, sondern ist gekrümmt: vorne mehr, hinten weniger. Diese Krümmung ist die Antwort auf die Frage, wie teuer Eile gegen Warten steht.
+
**Erwartete Ausgabe:**
```
@@ -16248,6 +16294,7 @@ Training: Tag 1 bis 1000. Bewertung: die restlichen 4000 Tage.
bester MSE: bestelle die Punktprognose
beste Kosten: Quantilregression aufs kritische Quantil
+
Das Verfahren mit dem besten MSE hat die HOECHSTEN Kosten, und das
Verfahren mit den besten Kosten hat einen um 13% SCHLECHTEREN MSE.
Wer Prognosemodelle nach MSE auswaehlt, waehlt hier das falsche.
@@ -16324,6 +16371,11 @@ Kosten statt auf Fehler trainiert.
====================================================================================
```
+
+
+
+**Was Sie in der Abbildung sehen.** Links und rechts gewinnt nicht dasselbe Verfahren. Die Punktprognose hat den besten Prognosefehler und die höchsten Kosten — beide Maßstäbe messen etwas anderes, und nur einer davon steht am Ende in der Bilanz.
---
## 15.5 Der Befund {#sec:prognose-befund}
@@ -17724,9 +17776,14 @@ Was Versorgungssicherheit kostet
Der Erwartungswert-Plan kostet in der Wirklichkeit **149 % mehr**, und sein schlimmster Tag ist sechsmal so teuer.
+
+
+**Was Sie in der Abbildung sehen.** Der Erwartungswert-Plan ist in den ruhigen Szenarien tatsächlich der billigere — die rote Kurve verläuft links von der grünen. Er kippt erst rechts, und zwar so weit, dass der Mittelwert das Vorzeichen wechselt.
+
**Wofür genau?** Die Summendifferenz von 523 514 € sagt noch nicht, wo sie entsteht. Zerlegt man sie nach Kostenarten, wird aus dem Befund eine Aussage, die man vorlegen kann:
-
+
Drei Dinge stehen darin, die die Tabelle nicht zeigt. Die **Anfahrkosten sind in beiden Plänen gleich** (58 000 €) — der Erwartungswert-Plan spart also nicht dort, wo man es vermuten würde. Er spart **12 725 € Brennstoff**, weil er weniger Blockstunden vorhält. Und er bezahlt dafür **536 239 € Lastabwurf**: das **42-fache** seiner Ersparnis.
diff --git a/Operations_Research_mit_Python_Version_04.pdf b/Operations_Research_mit_Python_Version_04.pdf
index e5a586d..5107196 100644
Binary files a/Operations_Research_mit_Python_Version_04.pdf and b/Operations_Research_mit_Python_Version_04.pdf differ
diff --git a/Operations_Research_mit_Python_Version_04/10_Einfuehrung_OR.md b/Operations_Research_mit_Python_Version_04/10_Einfuehrung_OR.md
index fea3591..6e82b76 100644
--- a/Operations_Research_mit_Python_Version_04/10_Einfuehrung_OR.md
+++ b/Operations_Research_mit_Python_Version_04/10_Einfuehrung_OR.md
@@ -188,6 +188,14 @@ Zahl im Text.
> hoffnungslos) liegen nur **fünf zusätzliche Aufträge**. Es gibt keine sanfte
> Verschlechterung — es gibt eine Wand.
+
+
+**Was Sie in der Abbildung sehen.** Der markierte Streifen zwischen $n = 15$ und $n = 20$ ist
+der eigentliche Befund: Dort wird aus einer Kaffeepause ein Menschenleben. Wer eine Maschine
+kauft, die tausendmal schneller rechnet, verschiebt diese Wand um genau zwei Aufträge.
+
Und die Rechnung ist noch geschönt: Ein schnellerer Rechner hilft praktisch nicht. Selbst
eine Beschleunigung um den Faktor **eine Million** verschiebt die Grenze von $n=20$ nur auf
etwa $n=24$. Gegen kombinatorisches Wachstum ist Hardware machtlos.
diff --git a/Operations_Research_mit_Python_Version_04/12_Python_Oekosystem.md b/Operations_Research_mit_Python_Version_04/12_Python_Oekosystem.md
index 0260121..61222d7 100644
--- a/Operations_Research_mit_Python_Version_04/12_Python_Oekosystem.md
+++ b/Operations_Research_mit_Python_Version_04/12_Python_Oekosystem.md
@@ -1152,6 +1152,14 @@ Gesamtzeit damit, das Modell überhaupt aufzuschreiben** — und nur 31 % mit Re
vektorisierten Varianten kehren das Verhältnis um: 1 % Aufbau, 99 % Solver. Erst dort ist
ein schnellerer Solver überhaupt die richtige Stellschraube.
+
+
+**Was Sie in der Abbildung sehen.** Der rote Anteil ist die Zeit, in der der Solver noch gar
+nicht rechnet. Bei Variante A wächst er mit dem Modell, bei Variante C verschwindet er —
+dieselbe Mathematik, nur anders aufgeschrieben.
+
> **💻 Code-Durchgang**
>
> | Stelle | Was passiert | Warum es zählt |
diff --git a/Operations_Research_mit_Python_Version_04/13_Vom_Wunsch_zum_Modell.md b/Operations_Research_mit_Python_Version_04/13_Vom_Wunsch_zum_Modell.md
index abd57ab..78e6fc7 100644
--- a/Operations_Research_mit_Python_Version_04/13_Vom_Wunsch_zum_Modell.md
+++ b/Operations_Research_mit_Python_Version_04/13_Vom_Wunsch_zum_Modell.md
@@ -411,6 +411,7 @@ Es muss also ausgewaehlt werden. 3 der Kunden sind Stammkunden:
"Maschinen besser auslasten" 205,000 54,000 100% 4 1 5
"Deckungsbeitrag maximieren" 222,000 78,500 100% 2 1 8
+
Der Umsatzplan bringt 5,000 EUR mehr Umsatz und 12,500 EUR WENIGER
Deckungsbeitrag. Fuer 5,000 EUR Umsatz werden also 12,500 EUR Ergebnis
aufgegeben - und 5 von 6 Stammkundenauftraegen dazu.
@@ -486,6 +487,14 @@ Drei Dinge, die deshalb vor dem ersten Modell geklaert gehoeren:
====================================================================================
```
+
+
+
+**Was Sie in der Abbildung sehen.** Jeder Plan gewinnt auf seiner eigenen Achse — das ist
+keine Überraschung, sondern die Definition. Interessant ist, was daneben passiert: Der
+Auslastungsplan liegt bei der Auslastung gleichauf mit den anderen und verliert beim
+Deckungsbeitrag ein knappes Drittel.
### Teil 1: Drei Ziele, drei Pläne
| Zielgröße | Umsatz | Deckungsbeitrag | Auslastung | abgelehnte Stammaufträge |
diff --git a/Operations_Research_mit_Python_Version_04/20_Lineare_Programmierung.md b/Operations_Research_mit_Python_Version_04/20_Lineare_Programmierung.md
index 4d4f026..2b41ffc 100644
--- a/Operations_Research_mit_Python_Version_04/20_Lineare_Programmierung.md
+++ b/Operations_Research_mit_Python_Version_04/20_Lineare_Programmierung.md
@@ -944,6 +944,15 @@ Der vorige Abschnitt hat gezeigt, wie wertvoll Schattenpreise sind. Dieser zeigt
Fälle, in denen sie eine Entscheidung **nicht** tragen — und wie man beide erkennt, bevor
jemand auf ihrer Grundlage eine Maschine kauft.
+
+
+**Was Sie in der Abbildung sehen.** Jeder Wert innerhalb der farbigen Balken erfüllt die
+Optimalitätsbedingungen. Zwei Solver dürfen also verschiedene Schattenpreise melden und haben
+beide recht — die Frage „was ist eine Stunde wert?" hat hier schlicht keine eindeutige
+Antwort.
+
### Fall 1: Entartung
Erinnern Sie sich an {ref:sec:fundament-der-zulaessige-loesungsraum-und-das-polyeder}: In zwei
diff --git a/Operations_Research_mit_Python_Version_04/21_MILP.md b/Operations_Research_mit_Python_Version_04/21_MILP.md
index 020fbf8..a67ad6b 100644
--- a/Operations_Research_mit_Python_Version_04/21_MILP.md
+++ b/Operations_Research_mit_Python_Version_04/21_MILP.md
@@ -366,6 +366,14 @@ Hier kommt das Handwerkszeug, das MILP so mächtig macht:{idx:Big-M-Methode} Man
lineare Ungleichungen — mithilfe binärer Hilfsvariablen $y \in \{0,1\}$ und einer
hinreichend großen Konstante $M$.
+
+
+**Was Sie in der Abbildung sehen.** Für $y \in \{0,1\}$ sind beide Modelle gleichwertig; die
+beiden blauen Punkte stimmen überein. Verschieden ist nur, was dazwischen erlaubt ist — und
+rechts genügt bereits $y = 0{,}08$, um die volle Kapazität freizugeben.
+
### Muster 1 — Fixkosten / Aktivierungsschalter
*Regel:* Wird Maschine $j$ genutzt ($x_j > 0$), fallen Rüstkosten $F_j$ an.
diff --git a/Operations_Research_mit_Python_Version_04/23_Graphen_Fluesse_Touren.md b/Operations_Research_mit_Python_Version_04/23_Graphen_Fluesse_Touren.md
index 597dfca..af4c16b 100644
--- a/Operations_Research_mit_Python_Version_04/23_Graphen_Fluesse_Touren.md
+++ b/Operations_Research_mit_Python_Version_04/23_Graphen_Fluesse_Touren.md
@@ -514,6 +514,14 @@ Ein naives Modell erlaubt **Subtouren**{idx:Subtour}: isolierte Kreise, die das
klassische Gegenmaßnahme ist die **MTZ-Formulierung**{idx:MTZ-Formulierung} nach Miller, Tucker und Zemlin. Man
führt Rangvariablen $u_i$ ein (die Position des Knotens in der Tour):
+
+
+**Was Sie in der Abbildung sehen.** Links wird jeder Kunde genau einmal angefahren — das
+Modell hat also gerechnet, was man ihm aufgeschrieben hat. Was fehlt, ist die Bedingung, an
+die man beim Aufschreiben nicht denkt: dass jede Tour am Depot beginnen muss.
+
$$
u_i - u_j + C \cdot x_{ij} \le C - d_j \qquad \forall i \ne j
$$
diff --git a/Operations_Research_mit_Python_Version_04/25_Spaltengenerierung.md b/Operations_Research_mit_Python_Version_04/25_Spaltengenerierung.md
index 8a17364..efda759 100644
--- a/Operations_Research_mit_Python_Version_04/25_Spaltengenerierung.md
+++ b/Operations_Research_mit_Python_Version_04/25_Spaltengenerierung.md
@@ -160,6 +160,13 @@ Dualwert $\pi_i$ zur Bedarfszeile $i$ ist genau der Schattenpreis aus
{ref:sec:lp-dualitaet-und-schattenpreise}: Er sagt, wie viele Rollen ein zusätzliches Stück
der Breite $i$ kostet.
+
+
+**Was Sie in der Abbildung sehen.** Die Information fließt in beide Richtungen: Preise nach
+rechts, Muster nach links. Der Ausgang unten wird erst geöffnet, wenn das Pricing nichts mehr
+findet — und genau das ist der Optimalitätsbeweis.
+
Ein neues Muster $a$ lohnt sich, wenn seine **reduzierten Kosten** negativ sind:
$$
diff --git a/Operations_Research_mit_Python_Version_04/31_Unsicherheit.md b/Operations_Research_mit_Python_Version_04/31_Unsicherheit.md
index ea6ae32..ddae0b2 100644
--- a/Operations_Research_mit_Python_Version_04/31_Unsicherheit.md
+++ b/Operations_Research_mit_Python_Version_04/31_Unsicherheit.md
@@ -225,6 +225,14 @@ if __name__ == "__main__":
print("nicht beim Mittelwert 225 - typisch fuer asymmetrische Kostenfunktionen.")
```
+
+
+**Was Sie in der Abbildung sehen.** Die Kurve ist nicht symmetrisch: Sie fällt links flach und
+steigt rechts steil, weil Fehlmenge 120 € kostet und Überschuss nur 5 €. Ihr tiefster Punkt
+liegt deshalb rechts vom Erwartungswert — nicht auf ihm.
+
**Erwartete Ausgabe:**
```
diff --git a/Operations_Research_mit_Python_Version_04/32_Dynamische_Programmierung.md b/Operations_Research_mit_Python_Version_04/32_Dynamische_Programmierung.md
index 8461715..f889524 100644
--- a/Operations_Research_mit_Python_Version_04/32_Dynamische_Programmierung.md
+++ b/Operations_Research_mit_Python_Version_04/32_Dynamische_Programmierung.md
@@ -581,6 +581,13 @@ if __name__ == "__main__":
print("=" * 84)
```
+
+
+**Was Sie in der Abbildung sehen.** Die optimale Kurve liegt nicht in der Mitte zwischen den
+Extremen, sondern ist gekrümmt: vorne mehr, hinten weniger. Diese Krümmung ist die Antwort
+auf die Frage, wie teuer Eile gegen Warten steht.
+
**Erwartete Ausgabe:**
```
diff --git a/Operations_Research_mit_Python_Version_04/34_Predict_then_Optimize.md b/Operations_Research_mit_Python_Version_04/34_Predict_then_Optimize.md
index ea6822b..281e97c 100644
--- a/Operations_Research_mit_Python_Version_04/34_Predict_then_Optimize.md
+++ b/Operations_Research_mit_Python_Version_04/34_Predict_then_Optimize.md
@@ -398,6 +398,7 @@ Training: Tag 1 bis 1000. Bewertung: die restlichen 4000 Tage.
bester MSE: bestelle die Punktprognose
beste Kosten: Quantilregression aufs kritische Quantil
+
Das Verfahren mit dem besten MSE hat die HOECHSTEN Kosten, und das
Verfahren mit den besten Kosten hat einen um 13% SCHLECHTEREN MSE.
Wer Prognosemodelle nach MSE auswaehlt, waehlt hier das falsche.
@@ -474,6 +475,13 @@ Kosten statt auf Fehler trainiert.
====================================================================================
```
+
+
+
+**Was Sie in der Abbildung sehen.** Links und rechts gewinnt nicht dasselbe Verfahren. Die
+Punktprognose hat den besten Prognosefehler und die höchsten Kosten — beide Maßstäbe messen
+etwas anderes, und nur einer davon steht am Ende in der Bilanz.
---
## Der Befund {#sec:prognose-befund}
diff --git a/Operations_Research_mit_Python_Version_04/36_Supply_Chain_Energie.md b/Operations_Research_mit_Python_Version_04/36_Supply_Chain_Energie.md
index a9e2681..af9bd04 100644
--- a/Operations_Research_mit_Python_Version_04/36_Supply_Chain_Energie.md
+++ b/Operations_Research_mit_Python_Version_04/36_Supply_Chain_Energie.md
@@ -595,6 +595,14 @@ Was Versorgungssicherheit kostet
Der Erwartungswert-Plan kostet in der Wirklichkeit **149 % mehr**, und sein schlimmster Tag
ist sechsmal so teuer.
+
+
+**Was Sie in der Abbildung sehen.** Der Erwartungswert-Plan ist in den ruhigen Szenarien
+tatsächlich der billigere — die rote Kurve verläuft links von der grünen. Er kippt erst
+rechts, und zwar so weit, dass der Mittelwert das Vorzeichen wechselt.
+
**Wofür genau?** Die Summendifferenz von 523 514 € sagt noch nicht, wo sie entsteht. Zerlegt
man sie nach Kostenarten, wird aus dem Befund eine Aussage, die man vorlegen kann:
diff --git a/PROGRESS.md b/PROGRESS.md
index f181af2..fa4e6bd 100644
--- a/PROGRESS.md
+++ b/PROGRESS.md
@@ -2487,6 +2487,58 @@ Gegengeprüft mit einem simulierten Klon: Das Kritik-Verzeichnis fehlt dort voll
Historie. Wer einen alten Commit auscheckt, bekommt sie weiterhin. Sie wirklich zu tilgen,
verlangte `git filter-repo` und einen erzwungenen Push — dafür ist der Anlass zu gering.
+### ✅ Grafik-Upgrade, Stufe 1: elf neue Diagramme
+
+`Grafik_Upgrade.md` verlangt „37 didaktisch wertvolle Visualisierungen". **Es sind 19.** Die
+Abschnitte „Modul 1–4" wiederholen die Grafiken 1–18 unter den Nummern 19–36; nur Grafik 37
+ist zusätzlich. Belegt an den Skriptnamen: 38 Nennungen, 19 verschiedene Dateien —
+`erzeuge_kombinatorik_wand.py` steht dreimal darin. Von den 19 betreffen neun bereits
+vorhandene Diagramme; Grafik 37 (OR-Architektur) existiert sogar zweimal.
+
+Umgesetzt sind die **zehn wirklich neuen** plus eine elfte, die aus einem Sachfehler des
+Auftrags entstand: Grafik 14 sollte in Abschnitt 12.3 stehen, nannte aber Zahlen aus
+Kapitel 17. Beide Stellen haben nun ihre eigene Grafik mit ihren eigenen Zahlen.
+
+**Vier Vorgaben des Auftrags wurden bewusst nicht befolgt:** PNG bei 300 dpi (das Buch kennt
+nur SVG — die 33 verwaisten PNGs waren gerade erst gelöscht worden), Matplotlib-Standardfarben
+(die Buchpalette steht in 33 Diagrammen), harte Kapitelnummern im Fließtext (`{ref:sec:…}`
+statt dessen) und die fehlende Byte-Reproduzierbarkeit.
+
+**Der eigentliche Ertrag waren die Selbsttests.** Jeder Generator prüft seine Zahlen gegen
+das, was im Kapitel steht, und bricht bei Abweichung ab. Vier davon haben angeschlagen:
+
+* **Kombinatorik-Wand:** 25! ergibt 491,5 Millionen Jahre; die Tabelle nennt 490 Millionen.
+ Kein Fehler des Buchs, sondern Rundung auf zwei signifikante Stellen — mein Formatierer
+ rundete auf volle Millionen.
+* **Laufzeit-Diagramm:** Die abgedruckte Prozentspalte lässt sich aus den abgedruckten Zeiten
+ *nicht* exakt nachrechnen (0,001 s / 0,008 s ergibt 12 %, gedruckt sind 14 %). Die Zeiten
+ sind auf drei Stellen gerundet, die Prozente stammen aus den ungerundeten Werten. Das Bild
+ zeigt jetzt die gedruckten Prozente.
+* **Predict-then-Optimize:** Meine geratene Datenaufteilung ergab 197,35 statt 200,95 MSE.
+ Mit `TRAINING` aus dem Buchprogramm stimmen alle vier Kostenwerte auf den Cent.
+* **Almgren-Chriss — ein echter Fehler im Buchprogramm**, siehe unten.
+
+**Der Fund: `analytische_loesung()` minimiert die eigene Kostenfunktion nicht.** Ihr Pfad
+kostet 10 860,40 €, der DP-Pfad 10 266,24 € — und ein Gitterverfahren kann das kontinuierliche
+Optimum nicht unterbieten. Ursache: `periodenkosten()` rechnet das Risiko mit **λ/2**, die
+geschlossene Formel setzt $\tilde\kappa^2 = \lambda\sigma^2 P_0^2/\eta$ **ohne** dieses
+Halbe. Mit λ/2 liefert die Formel 10 264,85 € und praktisch denselben Pfad wie die DP — knapp
+*unter* der Gitterlösung, wie es sein muss. Die Grafik zeigt bis zur Entscheidung darüber den
+DP-Pfad; er ist der, den das Kapitel abdruckt.
+
+**Nachweise:** Alle elf Diagramme sind über zwei Läufe byte-identisch. Kein vorhandenes
+Diagramm wurde verändert. Die Zahlen decken sich mit dem Buch, teils bis auf den Cent — die
+Lastabwurf-Grafik reproduziert die Befundtabelle exakt (874 870 € / 2 504 154 € / 28 von 40
+gegen 351 356 € / 415 924 € / 0 von 40).
+
+**Zwei Abbildungen landeten beim automatischen Einfügen im Codeblock** (ihre Anker standen in
+abgedruckten Ausgaben) und wurden dahinter verschoben. Eine Prüfung über alle elf zeigt jetzt
+null Fehlplatzierungen.
+
+Neu: `bilder_04/stil_04.py` bündelt Palette, `rcParams` und `speichere()`. `networkx` wurde
+entgegen der Planung **nicht** gebraucht — `pyproject.toml` bleibt unverändert.
+PDF von 781 auf **788 Seiten**, 44 Diagramme, 27 Generatoren.
+
---
## 8. Commit-Historie des V04-Strangs
diff --git a/README.md b/README.md
index 1b0f610..fb07b94 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Technik und Finanzmärkte*
Ein Lehrbuch über Operations Research mit Python: **23 Kapitel in 5 Teilen, 6 Anhänge,
141 Aufgaben mit vollständigen Lösungen, 76 lauffähige Beispielprogramme, 25 Jupyter-Notebooks,
-33 Diagramme — 759 PDF-Seiten.** Von der linearen Programmierung über Constraint Programming
+44 Diagramme — 788 PDF-Seiten.** Von der linearen Programmierung über Constraint Programming
und Metaheuristiken bis zu Portfoliooptimierung, CVaR und dem Weg vom Prototyp in den Betrieb.
**Online lesen: ** · Repository:
@@ -114,7 +114,7 @@ pip install -r Operations_Research_mit_Python_Version_04_Programme/requirements.
| Pfad | Rolle |
| --- | --- |
| `Operations_Research_mit_Python_Version_04/` | **Quelle**: 37 Kapiteldateien (inkl. 5 Teil-Synthesen), Build-Skripte und `NEUER_TITEL.md` — der Titeltext, aus dem PDF-Titelseite und Startseite entstehen |
-| `bilder_04/` | **Quelle**: 33 Diagramme (SVG) + 16 `erzeuge_*.py`-Generatoren |
+| `bilder_04/` | **Quelle**: 44 Diagramme (SVG) + 27 `erzeuge_*.py`-Generatoren |
| `web_04/` | **Quelle**: `site.css`, `site.js`, `icons.svg`, `plotly.min.js`, `katex/` — die statischen Bestandteile der Website |
| `pyproject.toml`, `Dockerfile`, `.dockerignore` | **Quelle**: Abhängigkeitsgruppen und Kurs-Image |
| `pandoc-defaults-*.yaml`, `pandoc/` | **Quelle**: Konfiguration des PDF-Baus |
diff --git a/bilder_04/erzeuge_almgren_chriss.py b/bilder_04/erzeuge_almgren_chriss.py
new file mode 100644
index 0000000..34d19e0
--- /dev/null
+++ b/bilder_04/erzeuge_almgren_chriss.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python3
+
+# erzeuge_almgren_chriss.py
+"""
+Erzeugt das Ausfuehrungsdiagramm zum Kapitel Dynamische Programmierung:
+
+ bilder_04/kap_dp_almgren_chriss.svg
+
+Drei Wege, dieselbe Position abzubauen, und was sie kosten:
+
+ * SOFORT - alles in der ersten Periode. Kein Kursrisiko, dafuer der volle
+ Marktimpact auf einen Schlag.
+ * TWAP - gleich grosse Scheiben. Wenig Impact je Scheibe, dafuer haelt man
+ die Position lange und traegt ihr Kursrisiko.
+ * OPTIMAL - die Loesung der Bellman-Gleichung: vorne mehr, hinten weniger.
+
+Der Punkt, auf den es ankommt: Die optimale Kurve liegt nicht "in der Mitte"
+zwischen den beiden Extremen, sondern ist gekruemmt. Ihre Kruemmung ist die
+Antwort auf die Frage, wie teuer Eile gegen Warten ist - und genau diese Frage
+beantwortet die dynamische Programmierung.
+
+Bestand und Kosten kommen aus Mehrperiodige_Order_Execution.py. Der Vergleich
+der Kosten steht als Zahl im Bild; sie wird gerechnet, nicht eingetragen.
+
+GEZEICHNET WIRD DER DP-PFAD, NICHT DIE GESCHLOSSENE FORMEL. Beim Bau dieses
+Bildes fiel auf, dass beide auseinanderlaufen: Der DP-Pfad kostet 10 266,24 EUR
+- der Wert, den das Kapitel abdruckt -, der Pfad aus analytische_loesung()
+dagegen 10 860,40 EUR. Ein Gitterverfahren kann das kontinuierliche Optimum
+aber nicht unterbieten, also stimmt die Formel nicht mit der Kostenfunktion
+ueberein: periodenkosten() rechnet das Risiko mit lambda/2, die Formel setzt
+kappa~^2 = lambda*sigma^2*P0^2/eta ohne dieses Halbe. Mit lambda/2 ergibt die
+Formel 10 264,85 EUR und denselben Pfad wie die DP - knapp UNTER der
+Gitterloesung, wie es sein muss. Bis das im Programm entschieden ist, zeigt das
+Bild den DP-Pfad; er ist der, den das Kapitel ausweist.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_almgren_chriss.py
+
+Benoetigt: numpy, matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+HIER = os.path.dirname(os.path.abspath(__file__))
+BASIS = os.path.dirname(HIER)
+sys.path.insert(0, HIER)
+sys.path.insert(0, os.path.join(
+ BASIS, "Operations_Research_mit_Python_Version_04_Programme"))
+
+from stil_04 import FARBEN, neue_figur, speichere # noqa: E402
+from Mehrperiodige_Order_Execution import (ETA, GESAMTBESTAND, # noqa: E402
+ KURS, PERIODEN,
+ RISIKOAVERSION,
+ VOLA_PERIODE,
+ SCHRITTWEITE, loese_dp,
+ periodenkosten)
+
+# Der im Kapitel abgedruckte Wert der optimalen Strategie - nur zum
+# Gegenpruefen.
+GESAMTREIBUNG_IM_BUCH = 10_266.24
+
+
+def impaktkosten(bestand: np.ndarray) -> float:
+ """Temporaerer Marktimpact: eta je Stueck^2 auf jede Scheibe."""
+ scheiben = -np.diff(bestand)
+ return float(ETA * np.sum(scheiben ** 2))
+
+
+def risikokosten(bestand: np.ndarray) -> float:
+ """Risiko des jeweiligen Restbestands, mit dem Faktor des Buchprogramms."""
+ return float(gesamtkosten(bestand) - impaktkosten(bestand))
+
+
+def gesamtkosten(bestand: np.ndarray) -> float:
+ """Summe der Periodenkosten - mit periodenkosten() des Buchprogramms.
+
+ Bewusst nicht selbst formuliert: Das Buch rechnet das Risiko mit dem Faktor
+ lambda/2. Eine eigene Formel ohne diesen Faktor haette Zahlen ergeben, die
+ zur Tabelle im Kapitel nicht passen."""
+ scheiben = -np.diff(bestand)
+ return float(sum(periodenkosten(float(scheiben[t]), float(bestand[t + 1]))
+ for t in range(len(scheiben))))
+
+
+def zeichne(pfade: dict[str, np.ndarray]) -> None:
+ figur, achse = neue_figur(breite=8.0, hoehe=4.6)
+ t = np.arange(PERIODEN + 1)
+
+ stile = {
+ "sofort verkaufen": (FARBEN["fehler"], "--"),
+ "gleichmäßig (TWAP)": (FARBEN["zweit"], "--"),
+ "optimal (Bellman)": (FARBEN["gut"], "-"),
+ }
+ for name, bestand in pfade.items():
+ farbe, strich = stile[name]
+ achse.plot(t, bestand / 1000.0, strich, color=farbe,
+ linewidth=2.6 if strich == "-" else 1.9,
+ marker="o", markersize=5, zorder=4,
+ label=f"{name} — {gesamtkosten(bestand):,.0f} €"
+ .replace(",", "."))
+
+ achse.set_xlabel("Handelsperiode $t$")
+ achse.set_ylabel("verbleibender Bestand in Tausend Stück")
+ achse.set_title(f"{GESAMTBESTAND:,} Stück abbauen — drei Wege, "
+ f"drei Rechnungen".replace(",", "."),
+ fontsize=10.5, color=FARBEN["text"])
+ achse.set_xticks(t)
+ achse.set_ylim(-4, GESAMTBESTAND / 1000.0 * 1.08)
+ achse.legend(fontsize=9, loc="upper right", frameon=False)
+
+ achse.annotate(
+ "Eile kostet Marktimpact, Warten kostet Kursrisiko.\n"
+ "Die optimale Kurve ist gekrümmt, weil sie beides gegeneinander "
+ "abwägt.",
+ xy=(0.03, 0.06), xycoords="axes fraction", fontsize=9,
+ color=FARBEN["text"], va="bottom")
+
+ speichere(figur, "kap_dp_almgren_chriss")
+
+
+if __name__ == "__main__":
+ sofort = np.array([GESAMTBESTAND] + [0] * PERIODEN, dtype=float)
+ twap = np.linspace(GESAMTBESTAND, 0, PERIODEN + 1)
+
+ # Der Pfad der Rueckwaertsinduktion - genau der, den das Kapitel abdruckt.
+ _zustaende, _V, politik = loese_dp()
+ bestand, verlauf = float(GESAMTBESTAND), [float(GESAMTBESTAND)]
+ for t in range(PERIODEN):
+ bestand -= politik[t, int(round(bestand / SCHRITTWEITE))]
+ verlauf.append(bestand)
+ optimal = np.array(verlauf, dtype=float)
+
+ pfade = {"sofort verkaufen": sofort, "gleichmäßig (TWAP)": twap,
+ "optimal (Bellman)": optimal}
+ for name, bestand in pfade.items():
+ print(f" {name:<20} Impact {impaktkosten(bestand):>10,.0f} EUR "
+ f"Risiko {risikokosten(bestand):>9,.0f} EUR "
+ f"gesamt {gesamtkosten(bestand):>10,.0f} EUR")
+
+ if gesamtkosten(optimal) > min(gesamtkosten(sofort), gesamtkosten(twap)):
+ raise SystemExit(
+ "Almgren-Chriss-Bild: Die analytische Loesung ist teurer als eine "
+ "der beiden Vergleichsstrategien. Dann stimmt die Kostenformel "
+ "hier nicht mit der des Buchprogramms ueberein.")
+ abweichung = abs(gesamtkosten(optimal) - GESAMTREIBUNG_IM_BUCH)
+ if abweichung > 0.01:
+ raise SystemExit(
+ f"Almgren-Chriss-Bild: Der DP-Pfad kostet "
+ f"{gesamtkosten(optimal):,.2f} EUR, das Kapitel druckt "
+ f"{GESAMTREIBUNG_IM_BUCH:,.2f} EUR.")
+ print(f" stimmt mit dem abgedruckten Wert überein: "
+ f"{GESAMTREIBUNG_IM_BUCH:,.2f} EUR")
+ zeichne(pfade)
diff --git a/bilder_04/erzeuge_big_m_vergleich.py b/bilder_04/erzeuge_big_m_vergleich.py
new file mode 100644
index 0000000..4301a2a
--- /dev/null
+++ b/bilder_04/erzeuge_big_m_vergleich.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+
+# erzeuge_big_m_vergleich.py
+"""
+Erzeugt das Big-M-Diagramm zum MILP-Kapitel:
+
+ bilder_04/kap_milp_big_m.svg
+
+Zwei Bilder derselben Bedingung x <= M*y mit y in [0,1], einmal mit straffem
+und einmal mit ueberdimensioniertem M. Gezeigt wird die LP-RELAXATION - also
+das, was der Solver sieht, bevor er y auf 0 oder 1 zwingt.
+
+Der Punkt: Beide Modelle sind fuer y in {0,1} GLEICHWERTIG. Sie beschreiben
+denselben zulaessigen Bereich, sobald y ganzzahlig ist. Verschieden ist nur die
+Relaxation - und die entscheidet, wie gut die Schranke ist und wie lange der
+Solver sucht. Bei zu grossem M kommt der Trickle Flow dazu: Ein y knapp ueber
+null gilt dem Solver als geschlossen und laesst trotzdem grossen Fluss durch.
+
+Die Trickle-Flow-Zahlen in der Anmerkung stammen aus der Loesung im Anhang des
+Buchs (M = 7,2e9, y = 4e-8, rund 289 Einheiten Fluss). Die beiden M-Werte der
+Geometrie sind Anschauungswerte; das Skript rechnet aus, ab welchem y die
+Relaxation die volle Kapazitaet freigibt, statt eine Zahl zu behaupten. Die
+Flaeche des Relaxationsgebiets waere der falsche Massstab - sie ist wegen der
+Kapazitaetsgrenze in beiden Faellen aehnlich gross.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_big_m_vergleich.py
+
+Benoetigt: numpy, matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from stil_04 import FARBEN, speichere # noqa: E402
+import matplotlib.pyplot as plt # noqa: E402
+
+KAPAZITAET = 40.0 # der tatsaechlich moegliche Hoechstwert von x
+M_STRAFF = 40.0 # so klein wie moeglich: M = Kapazitaet
+M_GROSS = 500.0 # "sicherheitshalber gross" - der haeufige Fehler
+
+# Aus der Loesung im Anhang: ein verschwindend kleines y laesst grossen Fluss
+# durch, weil es mit einem riesigen M multipliziert wird.
+TRICKLE_M = 7.2e9
+TRICKLE_Y = 4e-8
+
+
+def schwelle(m: float) -> float:
+ """Kleinstes y, bei dem die Relaxation die volle Kapazitaet freigibt.
+
+ Das ist der aussagekraeftige Vergleich - nicht die Flaeche des
+ Relaxationsgebiets. Die ist wegen der Kapazitaetsgrenze in beiden Faellen
+ aehnlich gross; der Unterschied liegt darin, wie WENIG y genuegt, um alles
+ durchzulassen."""
+ return min(1.0, KAPAZITAET / m)
+
+
+def zeichne(faktor: float) -> None:
+ figur, achsen = plt.subplots(1, 2, figsize=(9.2, 4.0), sharey=True)
+ y = np.linspace(0, 1, 300)
+
+ for achse, m, titel, farbe in (
+ (achsen[0], M_STRAFF, f"straff: $M = {M_STRAFF:.0f}$",
+ FARBEN["gut"]),
+ (achsen[1], M_GROSS, f"zu groß: $M = {M_GROSS:.0f}$",
+ FARBEN["fehler"])):
+ obergrenze = np.minimum(m * y, KAPAZITAET)
+ achse.fill_between(y, 0, obergrenze, color=farbe, alpha=0.16, zorder=2)
+ achse.plot(y, obergrenze, "-", color=farbe, linewidth=2.2, zorder=4,
+ label=r"$x \le M\,y$ und $x \le$ Kapazität")
+ achse.axhline(KAPAZITAET, color=FARBEN["linie"], linewidth=1.0,
+ linestyle="--", zorder=3)
+ achse.text(0.02, KAPAZITAET + 1.5, "Kapazität", fontsize=8.5,
+ color=FARBEN["gedaempft"])
+
+ # Die beiden Punkte, die das ganzzahlige Modell zulaesst.
+ achse.plot([0, 1], [0, KAPAZITAET], "o", color=FARBEN["haupt"],
+ markersize=8, zorder=5)
+ achse.annotate(r"$y=0$: zu", xy=(0, 0), xytext=(8, 10),
+ textcoords="offset points", fontsize=8.5,
+ color=FARBEN["haupt"])
+ achse.annotate(r"$y=1$: offen", xy=(1, KAPAZITAET), xytext=(-64, -18),
+ textcoords="offset points", fontsize=8.5,
+ color=FARBEN["haupt"])
+
+ achse.set_xlim(0, 1.02)
+ achse.set_ylim(0, KAPAZITAET * 1.25)
+ achse.set_xlabel(r"Schaltvariable $y \in [0,1]$ (relaxiert)")
+ achse.set_title(titel, fontsize=10.5, color=farbe)
+
+ achsen[0].set_ylabel(r"Menge $x$")
+ achsen[1].annotate(
+ f"Schon $y = {schwelle(M_GROSS):.2f}$ gibt die volle\n"
+ f"Kapazität frei — links braucht es dafür $y = 1$.\n"
+ f"Der Solver darf das Lager also fast\n"
+ f"geschlossen lassen und trotzdem alles liefern.",
+ xy=(0.16, KAPAZITAET * 0.42), fontsize=9, color=FARBEN["fehler"],
+ ha="left")
+ achsen[1].plot([schwelle(M_GROSS)], [KAPAZITAET], "o",
+ color=FARBEN["fehler"], markersize=8, zorder=6)
+
+ figur.suptitle("Dieselbe Bedingung, zwei Zahlen für $M$ — gleich für "
+ "$y \\in \\{0,1\\}$, verschieden für den Solver",
+ fontsize=10.5, color=FARBEN["text"], y=1.02)
+ speichere(figur, "kap_milp_big_m")
+
+
+if __name__ == "__main__":
+ faktor = schwelle(M_STRAFF) / schwelle(M_GROSS)
+ print(f" volle Kapazität ab y = {schwelle(M_STRAFF):.3f} (M = "
+ f"{M_STRAFF:.0f})")
+ print(f" volle Kapazität ab y = {schwelle(M_GROSS):.3f} (M = "
+ f"{M_GROSS:.0f}) → {faktor:.0f}-mal weniger y genügt")
+ print(f" Trickle Flow im Anhang: y = {TRICKLE_Y:g} gilt als 0, "
+ f"laesst aber M*y = {TRICKLE_M * TRICKLE_Y:.0f} Einheiten durch.")
+ zeichne(faktor)
diff --git a/bilder_04/erzeuge_entartung_polyeder.py b/bilder_04/erzeuge_entartung_polyeder.py
new file mode 100644
index 0000000..c997aa4
--- /dev/null
+++ b/bilder_04/erzeuge_entartung_polyeder.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+
+# erzeuge_entartung_polyeder.py
+"""
+Erzeugt das Entartungs-Diagramm zum LP-Kapitel:
+
+ bilder_04/kap_lp_entartung.svg
+
+Links die Geometrie: Drei Geraden laufen durch DIESELBE Ecke. In zwei
+Dimensionen legen schon zwei eine Ecke fest - eine ist zu viel, und genau das
+ist Entartung. Rechts die Folge davon: Der Schattenpreis jeder Nebenbedingung
+ist nicht mehr eine Zahl, sondern eine Spanne.
+
+Warum beides in ein Bild gehoert: Die Geometrie allein erklaert nicht, warum
+zwei Solver verschiedene Dualwerte melden duerfen und beide recht haben. Die
+Spannen allein sehen nach einem Fehler aus. Nebeneinander ergibt es Sinn.
+
+Modell und Spannen kommen aus Toleranzen_und_Entartung.py - importiert, nicht
+abgeschrieben. pruefe_ecke() rechnet zusaetzlich nach, dass wirklich alle drei
+Geraden durch den Punkt laufen; waere das nicht so, zeigte das Bild etwas
+anderes als der Text daneben behauptet.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_entartung_polyeder.py
+
+Benoetigt: numpy, scipy, matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+HIER = os.path.dirname(os.path.abspath(__file__))
+BASIS = os.path.dirname(HIER)
+sys.path.insert(0, HIER)
+sys.path.insert(0, os.path.join(
+ BASIS, "Operations_Research_mit_Python_Version_04_Programme"))
+
+from stil_04 import FARBEN, speichere # noqa: E402
+import matplotlib.pyplot as plt # noqa: E402
+from Toleranzen_und_Entartung import (A_UB, B_UB, NAMEN, # noqa: E402
+ schattenpreis_spanne)
+
+ECKE = np.array([4 / 3, 4 / 3])
+LINIENFARBEN = (FARBEN["haupt"], FARBEN["zweit"], FARBEN["akzent"])
+
+
+def pruefe_ecke() -> None:
+ """Alle drei Nebenbedingungen muessen in der Ecke aktiv sein."""
+ schlupf = B_UB - A_UB @ ECKE
+ aktiv = np.abs(schlupf) < 1e-9
+ if not aktiv.all():
+ raise SystemExit(
+ f"Entartungsbild: In {tuple(np.round(ECKE, 3))} sind nur "
+ f"{int(aktiv.sum())} von 3 Bedingungen aktiv (Schlupf "
+ f"{np.round(schlupf, 6)}). Ohne drei aktive Geraden gibt es keine "
+ f"Entartung zu zeigen.")
+
+
+def zeichne(spannen) -> None:
+ figur, (links, rechts) = plt.subplots(1, 2, figsize=(9.4, 4.3),
+ gridspec_kw={"width_ratios": [1, 1]})
+
+ # --- links: die drei Geraden ---------------------------------------
+ x = np.linspace(0, 3.2, 200)
+ for (a, b), grenze, name, farbe in zip(A_UB, B_UB, NAMEN, LINIENFARBEN):
+ y = (grenze - a * x) / b
+ links.plot(x, y, "-", color=farbe, linewidth=2.0, label=name, zorder=3)
+
+ # Zulaessiger Bereich: Schnitt aller Halbraeume, plus x >= 0.
+ gitter = np.linspace(0, 3.2, 400)
+ xx, yy = np.meshgrid(gitter, gitter)
+ zulaessig = np.ones_like(xx, dtype=bool)
+ for (a, b), grenze in zip(A_UB, B_UB):
+ zulaessig &= (a * xx + b * yy <= grenze + 1e-12)
+ links.contourf(xx, yy, zulaessig.astype(float), levels=[0.5, 1.5],
+ colors=[FARBEN["gut"]], alpha=0.13, zorder=1)
+
+ links.plot(*ECKE, "o", color=FARBEN["fehler"], markersize=9, zorder=5)
+ links.annotate(r"Optimum $(4/3,\ 4/3)$" "\n" "drei Geraden, eine Ecke",
+ xy=tuple(ECKE), xytext=(18, 26),
+ textcoords="offset points", fontsize=9,
+ color=FARBEN["fehler"], fontweight="bold",
+ arrowprops=dict(arrowstyle="->", color=FARBEN["fehler"],
+ linewidth=1.2))
+
+ links.set_xlim(0, 3.0)
+ links.set_ylim(0, 3.0)
+ links.set_xlabel(r"$x_1$")
+ links.set_ylabel(r"$x_2$")
+ links.set_title("Eine Bedingung zu viel", fontsize=10.5,
+ color=FARBEN["text"])
+ links.legend(fontsize=8.5, loc="upper right", frameon=False)
+
+ # --- rechts: die Spanne je Schattenpreis ---------------------------
+ y_pos = np.arange(len(NAMEN))[::-1]
+ for stelle, ((unten, oben), name, farbe) in enumerate(
+ zip(spannen, NAMEN, LINIENFARBEN)):
+ y = y_pos[stelle]
+ rechts.plot([unten, oben], [y, y], "-", color=farbe, linewidth=7,
+ solid_capstyle="round", alpha=0.75, zorder=3)
+ rechts.plot([unten, oben], [y, y], "|", color=farbe, markersize=14,
+ markeredgewidth=2, zorder=4)
+ rechts.text(oben + 0.012, y, f"{unten:.2f} – {oben:.2f} €",
+ va="center", fontsize=9, color=FARBEN["text"])
+ rechts.text(-0.012, y, name, va="center", ha="right", fontsize=9,
+ color=FARBEN["text"])
+
+ rechts.set_yticks([])
+ rechts.set_ylim(-0.7, len(NAMEN) - 0.3)
+ rechts.set_xlim(-0.16, max(o for _, o in spannen) * 1.9)
+ rechts.set_xlabel("Schattenpreis in € je zusätzlicher Stunde")
+ rechts.set_title("Was der Solver melden darf — jeder Wert der Spanne "
+ "ist richtig", fontsize=10.5, color=FARBEN["text"])
+ rechts.grid(axis="y", visible=False)
+ rechts.spines["left"].set_visible(False)
+
+ speichere(figur, "kap_lp_entartung")
+
+
+if __name__ == "__main__":
+ pruefe_ecke()
+ zielwert = float(np.ones(2) @ ECKE)
+ spannen = schattenpreis_spanne(zielwert)
+ for name, (unten, oben) in zip(NAMEN, spannen):
+ print(f" {name:<18} {unten:>7.4f} bis {oben:>7.4f} EUR")
+ zeichne(spannen)
diff --git a/bilder_04/erzeuge_fluch_durchschnitt.py b/bilder_04/erzeuge_fluch_durchschnitt.py
new file mode 100644
index 0000000..94d9e4d
--- /dev/null
+++ b/bilder_04/erzeuge_fluch_durchschnitt.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python3
+
+# erzeuge_fluch_durchschnitt.py
+"""
+Erzeugt das Diagramm zum Fluch des Durchschnitts:
+
+ bilder_04/kap_unsicherheit_durchschnitt.svg
+
+Die Handrechnung des Abschnitts vergleicht zwei Plaene fuer dieselbe unsichere
+Nachfrage. Das Bild zeigt, warum der eine schlechter ist - und zwar nicht als
+Behauptung, sondern als Kurve: die erwarteten Kosten ueber ALLEN moeglichen
+Bestellmengen.
+
+Was man daran sieht: Die Kurve hat einen Knick an jedem Szenario, faellt links
+flach und steigt rechts steil - Fehlmenge kostet 120 EUR, Ueberschuss nur 5. In
+dieser Schieflage liegt der ganze Effekt. Ihr Minimum liegt deshalb NICHT beim
+Erwartungswert der Nachfrage, sondern rechts davon.
+
+Ohne Formel gesagt: Mit dem Mittelwert zu planen unterstellt, dass sich zu viel
+und zu wenig gegenseitig aufheben. Sie tun es nicht.
+
+Alle Werte werden gerechnet. pruefe_gegen_handrechnung() vergleicht sie mit den
+im Kapitel abgedruckten Zwischenergebnissen - weicht eines ab, bricht das
+Skript ab.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_fluch_durchschnitt.py
+
+Benoetigt: numpy, matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from stil_04 import FARBEN, neue_figur, speichere # noqa: E402
+
+# Die Instanz der Handrechnung: (Bedarf, Wahrscheinlichkeit)
+SZENARIEN = [(100, 0.50), (250, 0.30), (500, 0.20)]
+NAMEN = ["Ruhig", "Volatil", "Crash"]
+
+VORAB = 40.0 # EUR je Einheit im Voraus
+FEHLT = 120.0 # EUR je fehlender Einheit, kurzfristig
+UEBRIG = 5.0 # EUR je ueberschuessiger Einheit, Verwaltung
+
+# Aus dem Kapitel abgedruckt - nur zum Gegenpruefen.
+ERWARTET_IM_BUCH = {225: 16_812.50, 250: 16_375.00}
+
+
+def kosten(x: float) -> float:
+ """Erwartete Gesamtkosten bei Bestellmenge x."""
+ return sum(p * (VORAB * x + FEHLT * max(bedarf - x, 0.0)
+ + UEBRIG * max(x - bedarf, 0.0))
+ for bedarf, p in SZENARIEN)
+
+
+def pruefe_gegen_handrechnung() -> None:
+ for x, erwartet in ERWARTET_IM_BUCH.items():
+ ist = kosten(x)
+ if abs(ist - erwartet) > 0.01:
+ raise SystemExit(
+ f"Fluch des Durchschnitts: Bei x={x} ergibt die Rechnung "
+ f"{ist:,.2f} EUR, die Handrechnung im Kapitel nennt "
+ f"{erwartet:,.2f} EUR.")
+
+
+def zeichne(mittelwert: float, bestes_x: float) -> None:
+ figur, achse = neue_figur(breite=8.0, hoehe=4.6)
+
+ x = np.linspace(0, 560, 1200)
+ y = np.array([kosten(float(k)) for k in x])
+ achse.plot(x, y, "-", color=FARBEN["haupt"], linewidth=2.4, zorder=4,
+ label="erwartete Gesamtkosten")
+
+ # Die Szenarien als senkrechte Marken - dort knickt die Kurve.
+ for (bedarf, p), name in zip(SZENARIEN, NAMEN):
+ achse.axvline(bedarf, color=FARBEN["linie"], linewidth=0.9,
+ linestyle=":", zorder=2)
+ achse.text(bedarf, achse.get_ylim()[0], f" {name}\n {p:.0%}",
+ fontsize=8.5, color=FARBEN["gedaempft"], va="bottom")
+
+ for stelle, farbe, beschriftung in (
+ (mittelwert, FARBEN["fehler"],
+ f"Planung mit dem Mittelwert\n$x = {mittelwert:.0f}$ "
+ f"{kosten(mittelwert):,.0f} €"),
+ (bestes_x, FARBEN["gut"],
+ f"stochastisch optimal\n$x = {bestes_x:.0f}$ "
+ f"{kosten(bestes_x):,.0f} €")):
+ achse.plot([stelle], [kosten(stelle)], "o", color=farbe, markersize=9,
+ zorder=6)
+ achse.annotate(beschriftung.replace(",", "."),
+ xy=(stelle, kosten(stelle)),
+ xytext=(14 if farbe == FARBEN["gut"] else -14, 44),
+ textcoords="offset points", fontsize=9, color=farbe,
+ fontweight="bold",
+ ha="left" if farbe == FARBEN["gut"] else "right",
+ arrowprops=dict(arrowstyle="->", color=farbe,
+ linewidth=1.2))
+
+ mehrkosten = kosten(mittelwert) - kosten(bestes_x)
+ achse.annotate(
+ f"Der Mittelwertplan kostet {mehrkosten:,.0f} € mehr —\n"
+ f"nicht weil er ungenau ist, sondern weil\n"
+ f"Fehlmenge {FEHLT:.0f} € kostet und Überschuss nur "
+ f"{UEBRIG:.0f} €.".replace(",", "."),
+ xy=(0.03, 0.95), xycoords="axes fraction", fontsize=9,
+ color=FARBEN["text"], va="top")
+
+ achse.set_xlabel("vorab gekaufte Kapazität $x$")
+ achse.set_ylabel("erwartete Gesamtkosten in €")
+ achse.set_title("Warum der Mittelwert der falsche Plan ist",
+ fontsize=10.5, color=FARBEN["text"])
+ achse.set_xlim(0, 560)
+
+ speichere(figur, "kap_unsicherheit_durchschnitt")
+
+
+if __name__ == "__main__":
+ pruefe_gegen_handrechnung()
+ mittelwert = sum(bedarf * p for bedarf, p in SZENARIEN)
+ gitter = np.arange(0, 561, 1.0)
+ bestes_x = float(gitter[int(np.argmin([kosten(float(k)) for k in gitter]))])
+ print(f" Erwartungswert der Nachfrage: {mittelwert:.0f}")
+ print(f" Kosten dort: {kosten(mittelwert):,.2f} EUR")
+ print(f" bestes x: {bestes_x:.0f}")
+ print(f" Kosten dort: {kosten(bestes_x):,.2f} EUR")
+ zeichne(mittelwert, bestes_x)
diff --git a/bilder_04/erzeuge_kombinatorik_wand.py b/bilder_04/erzeuge_kombinatorik_wand.py
new file mode 100644
index 0000000..2e1e87f
--- /dev/null
+++ b/bilder_04/erzeuge_kombinatorik_wand.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+
+# erzeuge_kombinatorik_wand.py
+"""
+Erzeugt das Wachstumsdiagramm zur Einfuehrung:
+
+ bilder_04/kap_einfuehrung_kombinatorik.svg
+
+Die Handrechnung des Abschnitts rechnet vor, wie lange vollstaendiges
+Durchprobieren dauert, wenn ein Rechner eine Milliarde Reihenfolgen je Sekunde
+prueft. Das Bild macht daraus eine Kurve - und zeigt daneben, was polynomiales
+Wachstum im selben Massstab bedeutet: eine Linie, die am unteren Rand klebt.
+
+Der didaktische Punkt ist nicht "n! waechst schnell", sondern die SCHMALHEIT
+des Uebergangs: Zwischen n=15 (22 Minuten, machbar) und n=20 (77 Jahre,
+hoffnungslos) liegen fuenf Auftraege. Deshalb der markierte Streifen.
+
+ZU DEN ZAHLEN: Sie werden gerechnet, nicht eingetragen. pruefe_gegen_buch()
+vergleicht sie anschliessend mit der abgedruckten Tabelle des Kapitels - weicht
+eine ab, bricht das Skript ab, statt ein Bild zu erzeugen, das der Tabelle
+daneben widerspricht.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_kombinatorik_wand.py
+
+Benoetigt: numpy, matplotlib
+"""
+
+from __future__ import annotations
+
+import math
+import os
+import sys
+
+import numpy as np
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from stil_04 import FARBEN, neue_figur, speichere # noqa: E402
+
+PRUEFUNGEN_JE_SEKUNDE = 1e9
+SEKUNDEN_JE_JAHR = 365.25 * 24 * 3600
+
+# Die vier Marken der Handrechnung. Werte NUR zum Gegenpruefen - gezeichnet
+# wird, was gerechnet wurde.
+TABELLE_IM_BUCH = {
+ 10: "0,004 Sekunden",
+ 15: "22 Minuten",
+ 20: "77 Jahre",
+ 25: "490 Millionen Jahre",
+}
+
+
+def sekunden(n: int) -> float:
+ return math.factorial(n) / PRUEFUNGEN_JE_SEKUNDE
+
+
+def _signifikant(wert: float, stellen: int = 2) -> int:
+ """Rundet auf 'stellen' signifikante Ziffern.
+
+ Die Tabelle des Kapitels tut genau das: 491,5 Millionen Jahre stehen dort
+ als '490 Millionen'. Volle Millionen zu runden ergaebe 492 - und damit ein
+ Bild, das der Tabelle daneben widerspricht."""
+ if wert == 0:
+ return 0
+ ordnung = math.floor(math.log10(abs(wert)))
+ faktor = 10 ** (ordnung - stellen + 1)
+ return int(round(wert / faktor) * faktor)
+
+
+def lesbar(n: int) -> str:
+ """Formatiert eine Dauer so, wie die Tabelle des Kapitels es tut."""
+ s = sekunden(n)
+ if s < 1:
+ return f"{s:.3f}".replace(".", ",") + " Sekunden"
+ if s < 3600:
+ return f"{round(s / 60)} Minuten"
+ jahre = s / SEKUNDEN_JE_JAHR
+ if jahre < 1000:
+ return f"{round(jahre)} Jahre"
+ if jahre < 1e9:
+ return f"{_signifikant(jahre / 1e6)} Millionen Jahre"
+ return f"{jahre:.1e} Jahre"
+
+
+def pruefe_gegen_buch() -> None:
+ """Die Zahlen im Bild muessen die der abgedruckten Tabelle sein."""
+ for n, erwartet in TABELLE_IM_BUCH.items():
+ ist = lesbar(n)
+ if ist != erwartet:
+ raise SystemExit(
+ f"Kombinatorik-Wand: Fuer n={n} ergibt die Rechnung {ist!r}, "
+ f"die Tabelle im Kapitel nennt {erwartet!r}. Bild und Text "
+ f"wuerden sich widersprechen.")
+
+
+def zeichne() -> None:
+ figur, achse = neue_figur(breite=7.8, hoehe=5.0)
+ n = np.arange(1, 31)
+
+ fakultaet = np.array([sekunden(int(k)) for k in n])
+ quadrat = n.astype(float) ** 2 / PRUEFUNGEN_JE_SEKUNDE
+ kubik = n.astype(float) ** 3 / PRUEFUNGEN_JE_SEKUNDE
+
+ achse.semilogy(n, fakultaet, "-", color=FARBEN["fehler"], linewidth=2.4,
+ label=r"$n!$ — alle Reihenfolgen durchprobieren", zorder=4)
+ achse.semilogy(n, kubik, "-", color=FARBEN["zweit"], linewidth=1.8,
+ label=r"$n^3$", zorder=3)
+ achse.semilogy(n, quadrat, "-", color=FARBEN["haupt"], linewidth=1.8,
+ label=r"$n^2$", zorder=3)
+
+ # Der schmale Uebergang, um den es geht.
+ achse.axvspan(15, 20, color=FARBEN["warnung"], alpha=0.12, zorder=1)
+ achse.annotate("fünf Aufträge mehr —\n22 Minuten wird zu 77 Jahren",
+ xy=(17.5, sekunden(17) * 0.02), fontsize=9,
+ color=FARBEN["warnung"], ha="center", fontweight="bold")
+
+ # Waagerechte Bezugsmarken: was ein Mensch noch abwartet.
+ for hoehe, text in ((1.0, "1 Sekunde"), (3600.0, "1 Stunde"),
+ (SEKUNDEN_JE_JAHR, "1 Jahr")):
+ achse.axhline(hoehe, color=FARBEN["linie"], linewidth=0.9,
+ linestyle="--", zorder=2)
+ achse.text(30.4, hoehe, text, fontsize=8, color=FARBEN["gedaempft"],
+ va="center")
+
+ for k in sorted(TABELLE_IM_BUCH):
+ achse.plot([k], [sekunden(k)], "o", color=FARBEN["fehler"],
+ markersize=6, zorder=5)
+ achse.annotate(f"$n={k}$: {lesbar(k)}",
+ xy=(k, sekunden(k)), xytext=(-6, 12),
+ textcoords="offset points", fontsize=8.5,
+ color=FARBEN["text"], ha="right",
+ arrowprops=dict(arrowstyle="-", color=FARBEN["linie"],
+ linewidth=0.8))
+
+ achse.set_xlabel("Zahl der Aufträge $n$")
+ achse.set_ylabel(r"Rechenzeit in Sekunden bei $10^9$ Prüfungen/s")
+ achse.set_title("Warum Ausprobieren scheitert — dieselbe Achse für alle "
+ "drei Kurven", fontsize=10.5, color=FARBEN["text"])
+ achse.set_xlim(1, 30)
+ achse.set_ylim(1e-9, 1e26)
+ achse.legend(fontsize=9, loc="upper left", frameon=False)
+
+ speichere(figur, "kap_einfuehrung_kombinatorik")
+
+
+if __name__ == "__main__":
+ pruefe_gegen_buch()
+ print("Zahlen stimmen mit der Tabelle des Kapitels überein.")
+ zeichne()
diff --git a/bilder_04/erzeuge_lastabwurf_verteilung.py b/bilder_04/erzeuge_lastabwurf_verteilung.py
new file mode 100644
index 0000000..9b4a409
--- /dev/null
+++ b/bilder_04/erzeuge_lastabwurf_verteilung.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+
+# erzeuge_lastabwurf_verteilung.py
+"""
+Erzeugt das Verteilungsdiagramm zum Supply-Chain-Kapitel:
+
+ bilder_04/kap_supplychain_lastabwurf.svg
+
+Das vorhandene Bild kap_supplychain_wirkung.svg zerlegt die Kostendifferenz der
+beiden Plaene nach Kostenarten. Dieses hier zeigt etwas anderes: die 40
+Szenarien einzeln.
+
+Warum das noetig ist: Ein Mittelwert von 874 870 EUR gegen 351 356 EUR sagt
+nicht, WIE die Differenz zustande kommt. Die Verteilung sagt es. Der
+Erwartungswert-Plan ist in den ruhigen Szenarien tatsaechlich billiger - und
+faellt in den windarmen Szenarien so weit durch, dass der Mittelwert kippt. Das
+ist die Gestalt, die eine einzelne Kennzahl verbirgt.
+
+Die Szenarien mit Lastabwurf sind eigens markiert; ihre Zahl muss die im
+Kapitel abgedruckte sein (28 von 40 gegen 0 von 40), sonst bricht das Skript
+ab.
+
+RECHENZEIT: Das Skript loest 2 x 40 Fahrplaene zuzueglich zweier
+Commitment-Probleme. Das dauert einige Minuten - anders ist die Verteilung
+nicht ehrlich zu bekommen.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_lastabwurf_verteilung.py
+
+Benoetigt: numpy, matplotlib, ortools
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+HIER = os.path.dirname(os.path.abspath(__file__))
+BASIS = os.path.dirname(HIER)
+sys.path.insert(0, HIER)
+sys.path.insert(0, os.path.join(
+ BASIS, "Operations_Research_mit_Python_Version_04_Programme"))
+
+from stil_04 import FARBEN, neue_figur, speichere # noqa: E402
+from Kraftwerkseinsatz import (SZENARIEN, WIND_ERWARTUNG, # noqa: E402
+ bewerte, erzeuge_windszenarien, plane)
+
+# Aus der Befundtabelle des Kapitels - nur zum Gegenpruefen.
+ABWURF_IM_BUCH = {"Erwartungswert": 28, "alle Szenarien": 0}
+
+
+def pruefe_abwurf(zaehlung: dict[str, int]) -> None:
+ for name, erwartet in ABWURF_IM_BUCH.items():
+ if zaehlung[name] != erwartet:
+ raise SystemExit(
+ f"Lastabwurf-Bild: Der Plan '{name}' wirft in "
+ f"{zaehlung[name]} von {SZENARIEN} Szenarien Last ab, die "
+ f"Befundtabelle des Kapitels nennt {erwartet}.")
+
+
+def zeichne(kosten: dict, fehlt: dict) -> None:
+ figur, achse = neue_figur(breite=8.2, hoehe=4.6)
+
+ for name, farbe in (("Erwartungswert", FARBEN["fehler"]),
+ ("alle Szenarien", FARBEN["gut"])):
+ werte = np.sort(kosten[name]) / 1000.0
+ rang = np.arange(1, len(werte) + 1)
+ achse.step(werte, rang, where="post", color=farbe, linewidth=2.2,
+ zorder=4,
+ label=f"Plan „{name}“ — Mittel "
+ f"{kosten[name].mean() / 1000:,.0f} Tsd. €"
+ .replace(",", "."))
+
+ betroffen = int((fehlt[name] > 1e-6).sum())
+ if betroffen:
+ mit_abwurf = np.sort(kosten[name][fehlt[name] > 1e-6]) / 1000.0
+ achse.scatter(mit_abwurf,
+ np.searchsorted(werte, mit_abwurf, side="right"),
+ s=26, color=farbe, zorder=5, alpha=0.85)
+
+ achse.set_xlabel("Kosten des Tages in Tausend €")
+ achse.set_ylabel("Szenarien mit höchstens diesen Kosten")
+ achse.set_title(f"Dieselben {SZENARIEN} Windszenarien, zwei Pläne — "
+ f"Punkte: Szenarien mit Lastabwurf",
+ fontsize=10.5, color=FARBEN["text"])
+ achse.set_ylim(0, SZENARIEN + 1)
+ achse.legend(fontsize=9, loc="lower right", frameon=False)
+
+ achse.annotate(
+ f"Der Erwartungswert-Plan ist links günstiger —\n"
+ f"und wirft in {int((fehlt['Erwartungswert'] > 1e-6).sum())} von "
+ f"{SZENARIEN} Szenarien Last ab.\n"
+ f"Der zweistufige Plan in keinem.",
+ xy=(0.03, 0.95), xycoords="axes fraction", fontsize=9,
+ color=FARBEN["text"], va="top")
+
+ speichere(figur, "kap_supplychain_lastabwurf")
+
+
+if __name__ == "__main__":
+ # erzeuge_windszenarien() liefert (wind, ist_flaute), plane() liefert
+ # (plan, dauer, optimal) - beide Rueckgaben werden hier nur teilweise
+ # gebraucht.
+ wind, _ist_flaute = erzeuge_windszenarien()
+ gleich = np.full(SZENARIEN, 1.0 / SZENARIEN)
+
+ kosten, fehlt, zaehlung = {}, {}, {}
+ for name, plan in (
+ ("Erwartungswert", plane(WIND_ERWARTUNG.reshape(1, -1), [1.0])[0]),
+ ("alle Szenarien", plane(wind, gleich)[0])):
+ kosten[name], fehlt[name] = bewerte(plan, wind)
+ zaehlung[name] = int((fehlt[name] > 1e-6).sum())
+ print(f" Plan „{name}“: Mittel {kosten[name].mean():>12,.0f} EUR, "
+ f"schlimmster Tag {kosten[name].max():>12,.0f} EUR, "
+ f"Lastabwurf in {zaehlung[name]:>2} von {SZENARIEN}")
+
+ pruefe_abwurf(zaehlung)
+ zeichne(kosten, fehlt)
diff --git a/bilder_04/erzeuge_laufzeit_aufbau.py b/bilder_04/erzeuge_laufzeit_aufbau.py
new file mode 100644
index 0000000..106da69
--- /dev/null
+++ b/bilder_04/erzeuge_laufzeit_aufbau.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python3
+
+# erzeuge_laufzeit_aufbau.py
+"""
+Erzeugt das Laufzeit-Diagramm zum Oekosystem-Kapitel:
+
+ bilder_04/kap_oekosystem_laufzeit.svg
+
+Gestapelte Balken: Wie viel Zeit geht in den AUFBAU des Modells (Python) und
+wie viel ins LOESEN (C++)? Verglichen werden Variante A (ein Add() je
+Nebenbedingung) und Variante C (vektorisiert ueber NumPy) bei drei
+Problemgroessen.
+
+WARUM HIER NICHT GEMESSEN WIRD: Die Zeiten stehen bereits als abgedruckte
+Ausgabe im Kapitel. Ein Neumessen auf einer anderen Maschine ergaebe andere
+Werte - das Bild widerspraeche dann der Tabelle unmittelbar daneben. Die
+Konstanten unten sind aus genau dieser Ausgabe uebernommen; pruefe_anteile()
+rechnet die Prozentspalte grob nach und schlaegt an, wenn eine Abweichung
+groesser ist als die Rundung der abgedruckten Zeiten erklaeren kann. So ist das
+Uebertragen abgesichert, ohne die Messung zu wiederholen.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_laufzeit_aufbau.py
+
+Benoetigt: numpy, matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from stil_04 import FARBEN, neue_figur, speichere # noqa: E402
+
+# (Groesse, Variablen, Aufbau A, Loesen A, Anteil A, Aufbau C, Loesen C,
+# Anteil C) - wortgleich aus der abgedruckten Ausgabe des Kapitels.
+MESSUNG = [
+ ("40 × 40", 1_600, 0.031, 0.005, 87, 0.001, 0.007, 14),
+ ("120 × 120", 14_400, 0.287, 0.070, 80, 0.001, 0.047, 3),
+ ("250 × 250", 62_500, 1.284, 0.569, 69, 0.003, 0.205, 1),
+]
+
+
+# Wie weit die aus den gerundeten Zeiten nachgerechnete Prozentzahl von der
+# abgedruckten abweichen darf. Die Zeiten stehen mit drei Nachkommastellen im
+# Buch, die Prozentspalte wurde aber aus den UNGERUNDETEN Werten berechnet:
+# 0,001s / 0,008s ergibt nachgerechnet 12 %, abgedruckt sind 14 %. Das ist
+# kein Fehler, sondern die Folge der Rundung - bei einer Aufbauzeit von einer
+# Millisekunde schlaegt schon die vierte Stelle durch. Die Schranke faengt
+# trotzdem einen echten Uebertragungsfehler ab.
+TOLERANZ_PROZENTPUNKTE = 4
+
+
+def pruefe_anteile() -> None:
+ """Plausibilitaetspruefung der uebertragenen Prozentspalte."""
+ for name, _var, auf_a, los_a, pro_a, auf_c, los_c, pro_c in MESSUNG:
+ for auf, los, pro, variante in ((auf_a, los_a, pro_a, "A"),
+ (auf_c, los_c, pro_c, "C")):
+ gerechnet = round(auf / (auf + los) * 100)
+ if abs(gerechnet - pro) > TOLERANZ_PROZENTPUNKTE:
+ raise SystemExit(
+ f"Laufzeit-Diagramm: {name}, Variante {variante}: Aus "
+ f"{auf}s Aufbau und {los}s Loesen folgen {gerechnet} % "
+ f"Aufbauanteil, die Tabelle nennt {pro} %. Das ist mehr "
+ f"als Rundung erklaert - Uebertragungsfehler?")
+
+
+def zeichne() -> None:
+ figur, achse = neue_figur(breite=8.0, hoehe=4.4)
+
+ # Zwei Balken je Groesse: oben Variante A, darunter Variante C.
+ beschriftung, hoehen = [], []
+ aufbau, loesen = [], []
+ # Gezeichnet wird die ABGEDRUCKTE Prozentzahl - so zeigt das Bild genau
+ # das, was in der Tabelle daneben steht.
+ for name, variablen, _aa, _la, pro_a, _ac, _lc, pro_c in MESSUNG:
+ for variante, anteil in (("A Schleife", pro_a),
+ ("C vektorisiert", pro_c)):
+ beschriftung.append(f"{name} {variante}")
+ aufbau.append(float(anteil))
+ loesen.append(100.0 - anteil)
+ hoehen.append(variablen)
+
+ y = np.arange(len(beschriftung))[::-1].astype(float)
+ # Luecke zwischen den Groessengruppen
+ y = y + np.repeat(np.arange(len(MESSUNG))[::-1], 2) * 0.6
+
+ achse.barh(y, aufbau, height=0.62, color=FARBEN["fehler"],
+ label="Aufbau in Python", zorder=3)
+ achse.barh(y, loesen, height=0.62, left=aufbau, color=FARBEN["haupt"],
+ label="Lösen in C++", zorder=3)
+
+ for stelle, (anteil, name) in enumerate(zip(aufbau, beschriftung)):
+ # Bei 1 % und 3 % ist der Balken schmaler als die Beschriftung - dann
+ # steht sie rechts daneben, in der Farbe des Balkens.
+ if anteil >= 10:
+ achse.text(anteil / 2, y[stelle], f"{round(anteil)} %",
+ ha="center", va="center", fontsize=8.5, color="white",
+ fontweight="bold", zorder=4)
+ else:
+ achse.text(anteil + 1.5, y[stelle], f"{round(anteil)} %",
+ ha="left", va="center", fontsize=8.5,
+ color=FARBEN["fehler"], fontweight="bold", zorder=4)
+ achse.text(101, y[stelle], name, va="center", fontsize=8.5,
+ color=FARBEN["text"])
+
+ achse.set_yticks([])
+ achse.set_xlim(0, 100)
+ achse.set_xlabel("Anteil an der Gesamtzeit in Prozent")
+ achse.set_title("Wo die Zeit wirklich hingeht — dieselbe Aufgabe, zwei "
+ "Arten sie aufzuschreiben", fontsize=10.5,
+ color=FARBEN["text"])
+ achse.grid(axis="y", visible=False)
+ achse.legend(fontsize=9, loc="lower center", bbox_to_anchor=(0.5, -0.28),
+ ncol=2, frameon=False)
+
+ speichere(figur, "kap_oekosystem_laufzeit")
+
+
+if __name__ == "__main__":
+ pruefe_anteile()
+ print("Prozentspalte stimmt mit den abgedruckten Zeiten überein.")
+ zeichne()
diff --git a/bilder_04/erzeuge_predict_vs_optimize.py b/bilder_04/erzeuge_predict_vs_optimize.py
new file mode 100644
index 0000000..07f3790
--- /dev/null
+++ b/bilder_04/erzeuge_predict_vs_optimize.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+
+# erzeuge_predict_vs_optimize.py
+"""
+Erzeugt das Diagramm zum Predict-then-Optimize-Kapitel:
+
+ bilder_04/kap_prognose_entscheidungsguete.svg
+
+Vier Verfahren, zwei Massstaebe: links der Prognosefehler (MSE), rechts die
+Kosten je Tag. Die Balken sind absichtlich nebeneinander gestellt, denn der
+Befund des Kapitels ist genau ihr Auseinanderlaufen: Das Verfahren mit dem
+BESTEN MSE hat die HOECHSTEN Kosten.
+
+Ohne Formel gesagt: Der Prognostiker optimiert seinen Fehler, der Planer traegt
+die Kosten - und beide messen etwas anderes. Wer die Prognose verbessert, ohne
+zu fragen, wofuer sie gebraucht wird, verbessert die falsche Zahl.
+
+Alle Werte kommen aus Predict_then_Optimize.py: dieselben Daten, dieselbe Saat,
+dieselben vier Verfahren. pruefe_befund() stellt sicher, dass die Aussage des
+Kapitels im Bild auch wirklich zu sehen ist - sonst waere das Bild ein
+Widerspruch zum Text daneben.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_predict_vs_optimize.py
+
+Benoetigt: numpy, scipy, scikit-learn, matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+HIER = os.path.dirname(os.path.abspath(__file__))
+BASIS = os.path.dirname(HIER)
+sys.path.insert(0, HIER)
+sys.path.insert(0, os.path.join(
+ BASIS, "Operations_Research_mit_Python_Version_04_Programme"))
+
+from stil_04 import FARBEN, speichere # noqa: E402
+import matplotlib.pyplot as plt # noqa: E402
+from scipy.stats import norm # noqa: E402
+from sklearn.linear_model import LinearRegression, QuantileRegressor # noqa: E402
+from Predict_then_Optimize import (KRITISCHES_VERHAELTNIS, TAGE, # noqa: E402
+ TRAINING, erzeuge_daten, tageskosten)
+
+KURZ = ["Punkt-\nprognose", "+ Zuschlag aus der\nNormalverteilung",
+ "+ Zuschlag auf\nKosten trainiert", "Quantil-\nregression"]
+
+
+def rechne() -> list[tuple[str, float, float]]:
+ """Dieselben vier Verfahren wie im Buchprogramm."""
+ merkmale, nachfrage = erzeuge_daten()[:2]
+ # Dieselbe Aufteilung wie im Buchprogramm - eine selbst gewaehlte Grenze
+ # ergaebe andere Zahlen als die abgedruckte Tabelle.
+ lernen = slice(0, TRAINING)
+ pruefen = slice(TRAINING, TAGE)
+
+ kq = LinearRegression().fit(merkmale[lernen], nachfrage[lernen])
+ punkt = kq.predict(merkmale[pruefen])
+ rest = nachfrage[lernen] - kq.predict(merkmale[lernen])
+ pauschal = norm.ppf(KRITISCHES_VERHAELTNIS) * rest.std()
+
+ kandidaten = np.linspace(-10.0, 30.0, 401)
+ trainingsprognose = kq.predict(merkmale[lernen])
+ kostenzuschlag = float(kandidaten[np.argmin(
+ [tageskosten(trainingsprognose + z, nachfrage[lernen])
+ for z in kandidaten])])
+
+ quantil = QuantileRegressor(quantile=KRITISCHES_VERHAELTNIS, alpha=0.0,
+ solver="highs").fit(merkmale[lernen],
+ nachfrage[lernen])
+ quantilprognose = quantil.predict(merkmale[pruefen])
+
+ verfahren = [
+ (KURZ[0], punkt, punkt),
+ (KURZ[1], punkt, punkt + pauschal),
+ (KURZ[2], punkt, punkt + kostenzuschlag),
+ (KURZ[3], quantilprognose, quantilprognose),
+ ]
+ aus = []
+ for name, prognose, bestellung in verfahren:
+ mse = float(((prognose - nachfrage[pruefen]) ** 2).mean())
+ aus.append((name, mse, tageskosten(bestellung, nachfrage[pruefen])))
+ return aus
+
+
+def pruefe_befund(werte) -> None:
+ """Die Aussage des Kapitels muss im Bild sichtbar sein."""
+ bester_mse = min(werte, key=lambda z: z[1])
+ teuerster = max(werte, key=lambda z: z[2])
+ if bester_mse[0] != teuerster[0]:
+ raise SystemExit(
+ f"Predict-then-Optimize-Bild: Das Verfahren mit dem besten MSE "
+ f"({bester_mse[0].replace(chr(10), ' ')}) ist nicht das teuerste "
+ f"({teuerster[0].replace(chr(10), ' ')}). Das Kapitel behauptet "
+ f"genau das - Bild und Text wuerden sich widersprechen.")
+
+
+def zeichne(werte) -> None:
+ figur, achsen = plt.subplots(1, 2, figsize=(9.4, 4.4))
+ namen = [n for n, _, _ in werte]
+ y = np.arange(len(namen))[::-1]
+
+ for achse, index, titel, einheit, farbe in (
+ (achsen[0], 1, "Prognosefehler (MSE)", "", FARBEN["zweit"]),
+ (achsen[1], 2, "Kosten je Tag", " €", FARBEN["warnung"])):
+ wert = [w[index] for w in werte]
+ bester = min(wert)
+ farben = [FARBEN["gut"] if abs(w - bester) < 1e-9 else farbe
+ for w in wert]
+ achse.barh(y, wert, height=0.62, color=farben, zorder=3)
+ for stelle, w in enumerate(wert):
+ achse.text(w * 1.01, y[stelle], f"{w:,.2f}{einheit}"
+ .replace(",", "."), va="center", fontsize=9,
+ color=FARBEN["text"])
+ achse.set_yticks(y)
+ achse.set_yticklabels(namen if index == 1 else [], fontsize=8.5,
+ color=FARBEN["text"])
+ achse.set_xlim(0, max(wert) * 1.22)
+ achse.set_title(titel, fontsize=10.5, color=FARBEN["text"])
+ achse.grid(axis="y", visible=False)
+
+ figur.suptitle("Grün ist jeweils der beste Wert — und es ist nicht "
+ "dasselbe Verfahren",
+ fontsize=11, color=FARBEN["text"], y=1.02)
+ speichere(figur, "kap_prognose_entscheidungsguete")
+
+
+if __name__ == "__main__":
+ werte = rechne()
+ for name, mse, kosten in werte:
+ print(f" {name.replace(chr(10), ' '):<40} MSE {mse:>8.2f} "
+ f"Kosten {kosten:>7.2f} EUR")
+ pruefe_befund(werte)
+ print(" Befund bestätigt: bester MSE = höchste Kosten.")
+ zeichne(werte)
diff --git a/bilder_04/erzeuge_spaltengenerierung_flow.py b/bilder_04/erzeuge_spaltengenerierung_flow.py
new file mode 100644
index 0000000..64ecf84
--- /dev/null
+++ b/bilder_04/erzeuge_spaltengenerierung_flow.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+
+# erzeuge_spaltengenerierung_flow.py
+"""
+Erzeugt das Regelkreis-Diagramm zum Dekompositions-Kapitel:
+
+ bilder_04/kap_dekomposition_regelkreis.svg
+
+Spaltengenerierung ist kein Algorithmus, den man am Stueck liest, sondern ein
+Kreislauf zwischen zwei Problemen, die einander abwechselnd Zahlen zuwerfen:
+
+ Master-LP -- Dualwerte pi_i --> Pricing (Rucksack)
+ Master-LP <-- neue Spalte a -- Pricing
+
+Das Bild macht daraus einen Kreis mit der Abbruchbedingung als Ausgang. Es ist
+bewusst schematisch: Zahlen stehen keine darin, denn die Schleife gilt fuer
+jede Instanz gleichermassen. Was sie zeigt, ist die Richtung der Information -
+und dass das Verfahren erst endet, wenn das Pricing NICHTS mehr findet.
+
+Gezeichnet mit matplotlib.patches statt Graphviz: Das Bild hat fuenf Kaesten
+und vier Pfeile: dafuer eine weitere Abhaengigkeit einzufuehren, waere
+unverhaeltnismaessig - und die Positionen sollen zu den uebrigen Diagrammen des
+Buchs passen, nicht zu Graphviz' Layoutgeschmack.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_spaltengenerierung_flow.py
+
+Benoetigt: matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from stil_04 import FARBEN, speichere # noqa: E402
+import matplotlib.pyplot as plt # noqa: E402
+from matplotlib.patches import FancyArrowPatch, FancyBboxPatch # noqa: E402
+
+
+def kasten(achse, x, y, breite, hoehe, titel, zeilen, farbe, fuellung):
+ achse.add_patch(FancyBboxPatch(
+ (x, y), breite, hoehe,
+ boxstyle="round,pad=0,rounding_size=0.09",
+ facecolor=fuellung, edgecolor=farbe, linewidth=1.8, zorder=2))
+ achse.text(x + breite / 2, y + hoehe - 0.20, titel, ha="center",
+ va="center", fontsize=10, fontweight="bold", color=farbe,
+ zorder=3)
+ achse.text(x + breite / 2, y + hoehe / 2 - 0.16, zeilen, ha="center",
+ va="center", fontsize=8.8, color=FARBEN["text"], zorder=3)
+
+
+def pfeil(achse, von, nach, text, farbe, bogen=0.0, versatz=(0, 0)):
+ achse.add_patch(FancyArrowPatch(
+ von, nach, arrowstyle="-|>", mutation_scale=16, linewidth=1.8,
+ color=farbe, connectionstyle=f"arc3,rad={bogen}", zorder=4,
+ shrinkA=2, shrinkB=2))
+ mitte = ((von[0] + nach[0]) / 2 + versatz[0],
+ (von[1] + nach[1]) / 2 + versatz[1])
+ achse.text(*mitte, text, ha="center", va="center", fontsize=9,
+ color=farbe, fontweight="bold", zorder=5)
+
+
+def zeichne() -> None:
+ figur, achse = plt.subplots(figsize=(8.6, 4.3))
+ achse.set_xlim(0, 10)
+ achse.set_ylim(0, 5)
+ achse.axis("off")
+
+ kasten(achse, 0.3, 2.5, 3.5, 1.9, "Master-LP (RMP)",
+ "rechnet mit den bisher\nbekannten Mustern\nund liefert Dualwerte",
+ FARBEN["haupt"], "#eef2ff")
+ kasten(achse, 6.2, 2.5, 3.5, 1.9, "Pricing: Rucksackproblem",
+ "sucht das EINE Muster mit\nden kleinsten reduzierten\nKosten",
+ FARBEN["zweit"], "#ecfeff")
+ kasten(achse, 3.1, 0.15, 3.8, 1.35, "Optimum bewiesen",
+ "kein Muster mit negativen\nreduzierten Kosten mehr",
+ FARBEN["gut"], "#ecfdf5")
+
+ pfeil(achse, (3.9, 3.9), (6.1, 3.9),
+ r"Dualwerte $\pi_i$", FARBEN["haupt"], bogen=-0.28,
+ versatz=(0, 0.62))
+ pfeil(achse, (6.1, 3.0), (3.9, 3.0),
+ r"neue Spalte $a$, wenn $1-\sum_i \pi_i a_i < 0$",
+ FARBEN["zweit"], bogen=-0.28, versatz=(0, -0.72))
+ pfeil(achse, (7.4, 2.4), (6.0, 1.5), "sonst", FARBEN["gut"], bogen=0.25,
+ versatz=(0.55, 0.12))
+
+ achse.text(5.0, 4.85,
+ "Die Schleife endet nicht, wenn sie müde wird, sondern wenn das "
+ "Pricing nichts mehr findet.",
+ ha="center", fontsize=9.5, color=FARBEN["gedaempft"],
+ style="italic")
+
+ speichere(figur, "kap_dekomposition_regelkreis")
+
+
+if __name__ == "__main__":
+ zeichne()
diff --git a/bilder_04/erzeuge_vrp_subtours.py b/bilder_04/erzeuge_vrp_subtours.py
new file mode 100644
index 0000000..718dd65
--- /dev/null
+++ b/bilder_04/erzeuge_vrp_subtours.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+
+# erzeuge_vrp_subtours.py
+"""
+Erzeugt das Kurzzyklus-Diagramm zum Graphen-Kapitel:
+
+ bilder_04/kap_graphen_subtouren.svg
+
+Links, was ein Tourenmodell OHNE Kurzzyklus-Bedingungen zurueckgeben darf:
+Jeder Kunde hat genau einen Vorgaenger und einen Nachfolger - alle
+Gradbedingungen sind erfuellt -, und trotzdem ist die Loesung unbrauchbar, weil
+die Fahrzeuge nie am Depot vorbeikommen. Rechts dieselbe Instanz mit gueltiger
+Rundreise ab und bis Depot.
+
+Der Punkt: Das linke Bild ist kein Rechenfehler. Es erfuellt jede Bedingung,
+die naiv formuliert wurde. Was fehlt, ist eine Bedingung, an die man beim
+Aufschreiben nicht denkt - und genau dafuer gibt es MTZ.
+
+Die Instanz stammt aus erzeuge_vrp_touren.py, also aus demselben Datensatz wie
+das Buchprogramm. Die Kurzzyklen links sind daraus konstruiert: Es sind die
+Kundenfolgen der gueltigen Loesung, nur ohne das Depot geschlossen. So zeigt
+das Bild denselben Fall und nicht ein zweites, erfundenes Beispiel.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_vrp_subtours.py
+
+Benoetigt: numpy, matplotlib, ortools
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from stil_04 import FARBEN, speichere # noqa: E402
+import matplotlib.pyplot as plt # noqa: E402
+from erzeuge_vrp_touren import (TOURFARBEN, erzeuge_daten, # noqa: E402
+ loese)
+
+
+def kurzzyklen(touren) -> list[list[int]]:
+ """Aus jeder gueltigen Tour einen Kreis ohne Depot machen.
+
+ Genau das darf ein Modell liefern, das nur 'jeder Kunde einmal angefahren'
+ fordert: In sich geschlossene Kreise, die das Depot nie beruehren."""
+ aus = []
+ for tour in touren:
+ kunden = [k for k in tour["stationen"] if k != 0]
+ if len(kunden) >= 2:
+ aus.append(kunden + [kunden[0]])
+ return aus
+
+
+def pruefe_grade(zyklen, anzahl_kunden: int) -> None:
+ """Die unzulaessige Loesung muss die Gradbedingungen trotzdem erfuellen."""
+ besucht = [k for z in zyklen for k in z[:-1]]
+ if sorted(besucht) != list(range(1, anzahl_kunden + 1)):
+ raise SystemExit(
+ "Subtour-Bild: Die konstruierten Kurzzyklen besuchen nicht jeden "
+ "Kunden genau einmal. Dann waere das linke Bild kein gueltiges "
+ "Gegenbeispiel, sondern einfach falsch.")
+
+
+def zeichne(koordinaten, touren, zyklen) -> None:
+ figur, achsen = plt.subplots(1, 2, figsize=(9.6, 4.6), sharex=True,
+ sharey=True)
+
+ for achse, titel in ((achsen[0], "ohne Kurzzyklus-Bedingungen"),
+ (achsen[1], "mit MTZ — jede Tour über das Depot")):
+ for ort in range(1, len(koordinaten)):
+ achse.scatter(*koordinaten[ort], s=34, color=FARBEN["text"],
+ zorder=3)
+ achse.scatter(*koordinaten[0], marker="s", s=150,
+ color=FARBEN["fehler"], zorder=4)
+ achse.annotate("Depot", koordinaten[0], textcoords="offset points",
+ xytext=(9, 7), fontsize=9, color=FARBEN["fehler"],
+ fontweight="bold")
+ achse.set_xlabel("km")
+ achse.set_title(titel, fontsize=10.5, color=FARBEN["text"])
+
+ # links: die Kurzzyklen
+ for nummer, (zyklus, farbe) in enumerate(zip(zyklen, TOURFARBEN), start=1):
+ weg = koordinaten[zyklus]
+ achsen[0].plot(weg[:, 0], weg[:, 1], "-", color=farbe, linewidth=1.8,
+ alpha=0.9, zorder=2)
+ achsen[0].annotate(
+ "Jeder Kunde hat genau einen Vor- und\n"
+ "einen Nachfolger — und kein Fahrzeug\n"
+ "kommt je am Depot vorbei.",
+ xy=(0.03, 0.03), xycoords="axes fraction", fontsize=9,
+ color=FARBEN["fehler"], va="bottom")
+
+ # rechts: die gueltige Loesung
+ for tour, farbe in zip(touren, TOURFARBEN):
+ weg = koordinaten[tour["stationen"]]
+ achsen[1].plot(weg[:, 0], weg[:, 1], "-", color=farbe, linewidth=1.8,
+ alpha=0.9, zorder=2)
+
+ achsen[0].set_ylabel("km")
+ figur.suptitle("Warum Gradbedingungen allein nicht genügen",
+ fontsize=11, color=FARBEN["text"], y=1.01)
+ speichere(figur, "kap_graphen_subtouren")
+
+
+if __name__ == "__main__":
+ koordinaten, distanz = erzeuge_daten()
+ touren = loese(distanz)
+ zyklen = kurzzyklen(touren)
+ pruefe_grade(zyklen, len(koordinaten) - 1)
+ print(f" {len(zyklen)} Kurzzyklen konstruiert, "
+ f"{sum(len(z) - 1 for z in zyklen)} Kunden — jeder genau einmal.")
+ zeichne(koordinaten, touren, zyklen)
diff --git a/bilder_04/erzeuge_zielgroessen_radar.py b/bilder_04/erzeuge_zielgroessen_radar.py
new file mode 100644
index 0000000..109d04d
--- /dev/null
+++ b/bilder_04/erzeuge_zielgroessen_radar.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+
+# erzeuge_zielgroessen_radar.py
+"""
+Erzeugt das Netzdiagramm zum Kapitel "Vom Management-Wunsch zum Modell":
+
+ bilder_04/kap_modellierung_zielgroessen.svg
+
+Drei Saetze aus derselben Besprechung - "Umsatz maximieren", "Maschinen
+auslasten", "Deckungsbeitrag maximieren" - ergeben drei verschiedene Plaene aus
+denselben 14 Anfragen. Das Netzdiagramm legt sie uebereinander. Der Punkt, auf
+den es ankommt: Der Auslastungsplan sieht auf seiner eigenen Achse perfekt aus
+und faellt auf der Deckungsbeitragsachse durch.
+
+KEINE ZAHL IST HIER EINGETRAGEN. Das Skript importiert Vom_Wunsch_zum_Modell.py
+und loest dieselben Modelle mit demselben Solver. Weicht das Buchprogramm
+spaeter ab, aendert sich das Bild mit - nicht der Text neben einem alten Bild.
+
+Aufruf (aus dem Repository-Wurzelverzeichnis):
+ python3 bilder_04/erzeuge_zielgroessen_radar.py
+
+Benoetigt: numpy, scipy, matplotlib
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+
+import numpy as np
+
+HIER = os.path.dirname(os.path.abspath(__file__))
+BASIS = os.path.dirname(HIER)
+sys.path.insert(0, HIER)
+# Das Buchprogramm ist die Quelle der Instanz - importiert, nicht kopiert.
+sys.path.insert(0, os.path.join(
+ BASIS, "Operations_Research_mit_Python_Version_04_Programme"))
+
+from stil_04 import FARBEN, speichere # noqa: E402
+import matplotlib.pyplot as plt # noqa: E402
+from Vom_Wunsch_zum_Modell import (AUFTRAEGE, DECKUNGSBEITRAG, # noqa: E402
+ STUNDEN, UMSATZ, kennzahlen,
+ waehle_aus)
+
+# Die fuenf Achsen des Netzes und wie sie aus kennzahlen() entstehen. Jede
+# Achse wird auf ihr eigenes Maximum ueber die drei Plaene skaliert - sonst
+# erschluege der Umsatz in Euro alle uebrigen Groessen.
+ACHSEN = [
+ ("Deckungsbeitrag", lambda k: k["db"]),
+ ("Umsatz", lambda k: k["umsatz"]),
+ ("Maschinen-\nauslastung", lambda k: k["auslastung"]),
+ ("Stammkunden\nbedient", lambda k: len({a[1] for a in AUFTRAEGE if a[2]})
+ - k["kunden_leer"]),
+ ("angenommene\nAufträge", lambda k: k["angenommen"]),
+]
+
+PLAENE = [
+ ("„Umsatz maximieren“", UMSATZ, FARBEN["zweit"]),
+ ("„Maschinen auslasten“", STUNDEN, FARBEN["warnung"]),
+ ("„Deckungsbeitrag maximieren“", DECKUNGSBEITRAG, FARBEN["gut"]),
+]
+
+
+def loese_alle() -> list[tuple[str, dict, str]]:
+ ergebnis = []
+ for name, ziel, farbe in PLAENE:
+ plan = waehle_aus(ziel)
+ if plan is None:
+ raise SystemExit(f"Radar: Fuer {name} liefert das Modell keinen Plan.")
+ ergebnis.append((name, kennzahlen(plan), farbe))
+ return ergebnis
+
+
+def zeichne(plaene) -> None:
+ werte = {name: [f(k) for _, f in ACHSEN] for name, k, _ in plaene}
+ maxima = [max(werte[name][i] for name in werte) or 1.0
+ for i in range(len(ACHSEN))]
+
+ winkel = np.linspace(0, 2 * np.pi, len(ACHSEN), endpoint=False)
+ geschlossen = np.concatenate([winkel, winkel[:1]])
+
+ figur, achse = plt.subplots(figsize=(6.6, 5.8),
+ subplot_kw={"projection": "polar"})
+ for name, _k, farbe in plaene:
+ anteile = [w / m * 100 for w, m in zip(werte[name], maxima)]
+ anteile += anteile[:1]
+ achse.plot(geschlossen, anteile, "-", color=farbe, linewidth=2.0,
+ label=name, zorder=3)
+ achse.fill(geschlossen, anteile, color=farbe, alpha=0.12, zorder=2)
+
+ achse.set_xticks(winkel)
+ achse.set_xticklabels([bez for bez, _ in ACHSEN], fontsize=9,
+ color=FARBEN["text"])
+ achse.set_yticks([25, 50, 75, 100])
+ achse.set_yticklabels(["25 %", "50 %", "75 %", "100 %"], fontsize=8,
+ color=FARBEN["gedaempft"])
+ achse.set_ylim(0, 108)
+ achse.grid(color=FARBEN["linie"], linewidth=0.7, alpha=0.6)
+ achse.spines["polar"].set_color(FARBEN["linie"])
+ achse.set_title("Drei Sätze aus derselben Besprechung, drei Pläne\n"
+ "je Achse auf den besten der drei Pläne bezogen",
+ fontsize=10.5, color=FARBEN["text"], pad=24)
+ achse.legend(fontsize=9, loc="lower center", bbox_to_anchor=(0.5, -0.20),
+ frameon=False)
+
+ speichere(figur, "kap_modellierung_zielgroessen")
+
+
+if __name__ == "__main__":
+ plaene = loese_alle()
+ for name, k, _ in plaene:
+ print(f" {name:<32} Umsatz {k['umsatz']:>8,.0f} "
+ f"DB {k['db']:>8,.0f} Auslastung {k['auslastung']:>3.0f} % "
+ f"angenommen {k['angenommen']:>2}")
+ zeichne(plaene)
diff --git a/bilder_04/kap_dekomposition_regelkreis.svg b/bilder_04/kap_dekomposition_regelkreis.svg
new file mode 100644
index 0000000..702ed68
--- /dev/null
+++ b/bilder_04/kap_dekomposition_regelkreis.svg
@@ -0,0 +1,2284 @@
+
+
+
diff --git a/bilder_04/kap_dp_almgren_chriss.svg b/bilder_04/kap_dp_almgren_chriss.svg
new file mode 100644
index 0000000..58db6f8
--- /dev/null
+++ b/bilder_04/kap_dp_almgren_chriss.svg
@@ -0,0 +1,1909 @@
+
+
+
diff --git a/bilder_04/kap_einfuehrung_kombinatorik.svg b/bilder_04/kap_einfuehrung_kombinatorik.svg
new file mode 100644
index 0000000..adcaafb
--- /dev/null
+++ b/bilder_04/kap_einfuehrung_kombinatorik.svg
@@ -0,0 +1,2440 @@
+
+
+
diff --git a/bilder_04/kap_graphen_subtouren.svg b/bilder_04/kap_graphen_subtouren.svg
new file mode 100644
index 0000000..ae0cf36
--- /dev/null
+++ b/bilder_04/kap_graphen_subtouren.svg
@@ -0,0 +1,2026 @@
+
+
+
diff --git a/bilder_04/kap_lp_entartung.svg b/bilder_04/kap_lp_entartung.svg
new file mode 100644
index 0000000..53403a1
--- /dev/null
+++ b/bilder_04/kap_lp_entartung.svg
@@ -0,0 +1,3309 @@
+
+
+
diff --git a/bilder_04/kap_milp_big_m.svg b/bilder_04/kap_milp_big_m.svg
new file mode 100644
index 0000000..9b9bd3c
--- /dev/null
+++ b/bilder_04/kap_milp_big_m.svg
@@ -0,0 +1,3483 @@
+
+
+
diff --git a/bilder_04/kap_modellierung_zielgroessen.svg b/bilder_04/kap_modellierung_zielgroessen.svg
new file mode 100644
index 0000000..d0d74cb
--- /dev/null
+++ b/bilder_04/kap_modellierung_zielgroessen.svg
@@ -0,0 +1,1556 @@
+
+
+
diff --git a/bilder_04/kap_oekosystem_laufzeit.svg b/bilder_04/kap_oekosystem_laufzeit.svg
new file mode 100644
index 0000000..8c7a8cb
--- /dev/null
+++ b/bilder_04/kap_oekosystem_laufzeit.svg
@@ -0,0 +1,1820 @@
+
+
+
diff --git a/bilder_04/kap_prognose_entscheidungsguete.svg b/bilder_04/kap_prognose_entscheidungsguete.svg
new file mode 100644
index 0000000..50542a2
--- /dev/null
+++ b/bilder_04/kap_prognose_entscheidungsguete.svg
@@ -0,0 +1,1888 @@
+
+
+
diff --git a/bilder_04/kap_supplychain_lastabwurf.svg b/bilder_04/kap_supplychain_lastabwurf.svg
new file mode 100644
index 0000000..43bdd44
--- /dev/null
+++ b/bilder_04/kap_supplychain_lastabwurf.svg
@@ -0,0 +1,1972 @@
+
+
+
diff --git a/bilder_04/kap_unsicherheit_durchschnitt.svg b/bilder_04/kap_unsicherheit_durchschnitt.svg
new file mode 100644
index 0000000..0bae4ca
--- /dev/null
+++ b/bilder_04/kap_unsicherheit_durchschnitt.svg
@@ -0,0 +1,2542 @@
+
+
+
diff --git a/bilder_04/stil_04.py b/bilder_04/stil_04.py
new file mode 100644
index 0000000..96254ed
--- /dev/null
+++ b/bilder_04/stil_04.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python3
+
+# stil_04.py
+"""
+Gemeinsamer Unterbau der Diagramm-Generatoren: Farben, Grundeinstellungen und
+das Schreiben der SVG-Datei.
+
+Warum es das gibt: Elf neue Generatoren trugen sonst elfmal denselben Vorspann.
+Eine Zeile daraus ist besonders heikel -
+
+ plt.rcParams["svg.hashsalt"] = "or-mit-python-v04"
+
+Ohne sie wuerfelt matplotlib die clip-path-IDs je Figure neu; die Datei aendert
+sich dann bei JEDEM Lauf, ohne dass sich am Bild etwas geaendert haette. Das
+faellt nicht sofort auf, sondern erst als unlesbarer git-diff - und dann sucht
+man die Ursache lange. Dasselbe gilt fuer metadata={"Date": None} beim
+Speichern: Sonst steht der Schreibzeitstempel auf die Mikrosekunde im SVG.
+
+Die 33 aelteren Generatoren setzen beides jeweils selbst. Sie bleiben
+unveraendert - eine Umstellung waere ein eigener Schritt und braeuchte den
+Nachweis, dass jedes einzelne Bild byte-identisch bleibt.
+
+Benutzung:
+
+ from stil_04 import FARBEN, neue_figur, speichere
+
+ figur, achse = neue_figur(breite=7.6, hoehe=4.6)
+ ...
+ speichere(figur, "kap_einfuehrung_kombinatorik")
+"""
+
+from __future__ import annotations
+
+import os
+
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+
+# Reproduzierbare SVG-Ausgabe - siehe Modulkommentar.
+plt.rcParams["svg.hashsalt"] = "or-mit-python-v04"
+
+# Serifenlos und ueberall vorhanden. Bewusst kein Stylesheet von seaborn: Das
+# Buch hat eine eigene Palette, und zwei Stilsysteme nebeneinander sehen nach
+# zwei Buechern aus.
+plt.rcParams["font.family"] = "DejaVu Sans"
+plt.rcParams["axes.grid"] = True
+plt.rcParams["grid.linestyle"] = ":"
+plt.rcParams["grid.alpha"] = 0.4
+plt.rcParams["axes.spines.top"] = False
+plt.rcParams["axes.spines.right"] = False
+
+BASIS = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+BILDER = os.path.join(BASIS, "bilder_04")
+
+# Die Palette des Buchs - dieselben Werte wie in den 33 vorhandenen Diagrammen
+# und auf der Titelseite. Die Namen sagen, wofuer die Farbe steht, nicht wie
+# sie aussieht: So bleibt die Bedeutung erhalten, falls ein Ton je gewechselt
+# wird.
+FARBEN = {
+ "haupt": "#4338ca", # Indigo - die primaere Groesse, Zielfunktion
+ "zweit": "#0891b2", # Teal - die Vergleichsgroesse
+ "warnung": "#b45309", # Amber - teuer, aber zulaessig
+ "gut": "#059669", # Emerald - Optimum, zulaessige Menge
+ "fehler": "#be123c", # Rose - unzulaessig, Verlust, Bruch
+ "akzent": "#7c3aed", # Violett - Schranken, Niveaulinien
+ "text": "#334155", # Slate - Beschriftung
+ "gedaempft": "#64748b", # Slate hell - Nebeninformation
+ "linie": "#94a3b8", # Hilfslinien
+ "flaeche": "#f1f5f9", # Hinterlegte Flaechen
+}
+
+
+def neue_figur(breite: float = 7.6, hoehe: float = 4.6, **kwargs):
+ """Figure und Achse in der Standardgroesse des Buchs."""
+ return plt.subplots(figsize=(breite, hoehe), **kwargs)
+
+
+def speichere(figur, name: str) -> str:
+ """Schreibt bilder_04/.svg und meldet den Pfad.
+
+ Nur SVG: Das PDF bindet die Bilder ueber \\includesvg (inkscape) ein, und
+ PNG-Zweitfassungen gab es in diesem Projekt schon einmal - sie wurden von
+ nirgendwo referenziert und mussten wieder geloescht werden."""
+ figur.tight_layout()
+ os.makedirs(BILDER, exist_ok=True)
+ pfad = os.path.join(BILDER, f"{name}.svg")
+ figur.savefig(pfad, format="svg", dpi=160, bbox_inches="tight",
+ metadata={"Date": None})
+ plt.close(figur)
+ print(f"geschrieben: {pfad}")
+ return pfad