kleine Änderungen
This commit is contained in:
parent
0f9c815b86
commit
dc088fa214
47 changed files with 183868 additions and 573 deletions
14
OR_HTML_04/lp.html
generated
14
OR_HTML_04/lp.html
generated
|
|
@ -250,9 +250,10 @@
|
|||
<h2 id="sec:lp-der-simplex-algorithmus-schritt-fuer-schritt">5.4 Der Simplex-Algorithmus Schritt für Schritt</h2>
|
||||
<p>Der von George Dantzig 1947 formulierte Simplex-Algorithmus nutzt den Fundamentalsatz aus <a href="fundament.html#kap-fundament">Kapitel 2</a>: <strong>Das Optimum liegt in einer Ecke.</strong> Statt alle Ecken aufzuzählen, wandert er von Ecke zu Ecke — und zwar immer in Richtung Verbesserung.</p>
|
||||
<figure>
|
||||
<img src="bilder_04/kap_lp_simplex_ecken.svg" alt="Abb. 5.1: Derselbe zulässige Bereich, aber der Weg der Handrechnung weiter unten: vom Ursprung über (0; 8) zum Optimum (7,5; 5). Drei der fünf Ecken werden besucht, keine zweimal — das ist der ganze Gewinn gegenüber dem Aufzählen aller Ecken. Erzeugt von bilder_04/erzeuge_polyeder.py." />
|
||||
<figcaption aria-hidden="true">Abb. 5.1: Derselbe zulässige Bereich, aber der Weg der Handrechnung weiter unten: vom Ursprung über (0; 8) zum Optimum (7,5; 5). Drei der fünf Ecken werden besucht, keine zweimal — das ist der ganze Gewinn gegenüber dem Aufzählen aller Ecken. Erzeugt von <code>bilder_04/erzeuge_polyeder.py</code>.</figcaption>
|
||||
<img src="bilder_04/kap_lp_simplex_ecken.svg" alt="Abb. 5.1: Derselbe zulässige Bereich, aber der Weg der Handrechnung weiter unten: vom Ursprung über (0; 8) zum Optimum (7,5; 5). Drei der fünf Ecken werden besucht, keine zweimal — das ist der ganze Gewinn gegenüber dem Aufzählen aller Ecken. Punktiert die Niveaulinien der Zielfunktion, der Pfeil ihr Gradient \mathbf{c}. Erzeugt von bilder_04/erzeuge_polyeder.py." />
|
||||
<figcaption aria-hidden="true">Abb. 5.1: Derselbe zulässige Bereich, aber der Weg der Handrechnung weiter unten: vom Ursprung über (0; 8) zum Optimum (7,5; 5). Drei der fünf Ecken werden besucht, keine zweimal — das ist der ganze Gewinn gegenüber dem Aufzählen aller Ecken. Punktiert die Niveaulinien der Zielfunktion, der Pfeil ihr Gradient <span class="math inline">\mathbf{c}</span>. Erzeugt von <code>bilder_04/erzeuge_polyeder.py</code>.</figcaption>
|
||||
</figure>
|
||||
<p><strong>Was Sie in der Abbildung sehen.</strong> Durch jede besuchte Ecke läuft genau eine Niveaulinie — die Linien sind nicht gewählt, sondern die Zielwerte 0 €, 2.000 € und 2.375 € der drei Ecken. Der Simplex schiebt diese Linie in Richtung des Pfeils so weit hinaus, wie das Polyeder es zulässt. Dass er dabei an einer Ecke anhält und nicht mittendrin, ist keine Eigenheit des Verfahrens, sondern der Fundamentalsatz: Weiter geht es nur noch hinaus.</p>
|
||||
<h3 id="der-ablauf">Der Ablauf</h3>
|
||||
<ol type="1">
|
||||
<li><strong>Initialisierung.</strong> Starte an einer bekannten Ecke — meist dem Ursprung <span class="math inline">\mathbf{x} = \mathbf{0}</span>, bei dem alle Schlupfvariablen ihre Kapazität aufnehmen: <span class="math inline">\mathbf{s} = \mathbf{b}</span>. Das ist zulässig, solange <span class="math inline">\mathbf{b} \ge \mathbf{0}</span>.</li>
|
||||
|
|
@ -736,6 +737,11 @@ Optimum nach 2 Pivotschritten erreicht.
|
|||
<p><strong>Satz.</strong> Besitzt das primale Problem eine endliche Optimallösung <span class="math inline">\mathbf{x}^*</span>, so besitzt auch das duale eine Optimallösung <span class="math inline">\mathbf{y}^*</span>, und die Zielwerte sind <strong>exakt gleich</strong>: <span class="math display">\mathbf{c}^\top\mathbf{x}^* = \mathbf{b}^\top\mathbf{y}^*</span></p>
|
||||
</blockquote>
|
||||
<p>Prüfen wir das an unserem Beispiel: <span class="math inline">\mathbf{b}^\top\mathbf{y}^* = 40 \cdot 12{,}5 + 60 \cdot 31{,}25 + 8 \cdot 0 = 500 + 1875 + 0 = 2375</span> ✓ — identisch mit <span class="math inline">Z^* = 2375</span>.</p>
|
||||
<figure>
|
||||
<img src="bilder_04/kap_lp_dualitaets_bruecke.svg" alt="Abb. 5.3: Beide Probleme geometrisch, gerechnet mit Dualitaet_Nachweis.py. Rechts ist die Ebene y_3 = 0 gezeichnet — zulässig, weil das Marktlimit x_1 \le 8 bei x_1^* = 7{,}5 nicht bindet und deshalb y_3^* = 0 gilt. Erzeugt von bilder_04/erzeuge_dualitaets_bruecke.py." />
|
||||
<figcaption aria-hidden="true">Abb. 5.3: Beide Probleme geometrisch, gerechnet mit <code>Dualitaet_Nachweis.py</code>. Rechts ist die Ebene <span class="math inline">y_3 = 0</span> gezeichnet — zulässig, weil das Marktlimit <span class="math inline">x_1 \le 8</span> bei <span class="math inline">x_1^* = 7{,}5</span> nicht bindet und deshalb <span class="math inline">y_3^* = 0</span> gilt. Erzeugt von <code>bilder_04/erzeuge_dualitaets_bruecke.py</code>.</figcaption>
|
||||
</figure>
|
||||
<p><strong>Was Sie in der Abbildung sehen.</strong> Die beiden Tafeln haben nichts gemeinsam: verschiedene Achsen, verschiedene Einheiten, links ein geschlossenes Polyeder, rechts ein nach oben offener Bereich. Links wird maximiert, rechts minimiert. Und doch steht an beiden Optima dieselbe Zahl — 2.375 €. Genau das behauptet der Satz, und mehr ist an ihm nicht zu sehen.</p>
|
||||
<p>Das lässt sich auch unabhängig von der Handrechnung nachweisen: Primal- und Dualproblem werden als <strong>zwei getrennte, voneinander unabhängige LPs</strong> aufgestellt und gelöst — wenn der starke Dualitätssatz stimmt, müssen beide denselben Zielwert liefern, ohne dass eines vom anderen „weiß“.</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/usr/bin/env python3</span></span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
|
|
@ -1126,8 +1132,8 @@ Pruefung: komplementaerer Schlupf fuer alle Ressourcen erfuellt.
|
|||
<h2 id="sec:lp-entartung">5.9 Wann Schattenpreise lügen: Entartung und Toleranzen</h2>
|
||||
<p>Der vorige Abschnitt hat gezeigt, wie wertvoll Schattenpreise sind. Dieser zeigt die zwei Fälle, in denen sie eine Entscheidung <strong>nicht</strong> tragen — und wie man beide erkennt, bevor jemand auf ihrer Grundlage eine Maschine kauft.</p>
|
||||
<figure>
|
||||
<img src="bilder_04/kap_lp_entartung.svg" alt="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." />
|
||||
<figcaption aria-hidden="true">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 <code>bilder_04/erzeuge_entartung_polyeder.py</code>.</figcaption>
|
||||
<img src="bilder_04/kap_lp_entartung.svg" alt="Abb. 5.4: 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." />
|
||||
<figcaption aria-hidden="true">Abb. 5.4: 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 <code>bilder_04/erzeuge_entartung_polyeder.py</code>.</figcaption>
|
||||
</figure>
|
||||
<p><strong>Was Sie in der Abbildung sehen.</strong> 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.</p>
|
||||
<h3 id="fall-1-entartung">Fall 1: Entartung</h3>
|
||||
|
|
|
|||
Loading…
Reference in a new issue