Glossar-Links: Fachbegriffe im Fließtext automatisch verlinken
Auto-Linking im Build: Glossar-Begriffe werden im Fließtext automatisch
erkannt und als Link auf den Glossar-Eintrag gesetzt — erste Nennung je
Begriff je Datei, dezent gestrichelte Unterstreichung im HTML, hyperref
im PDF. Kein manuelles Markieren bei Textänderungen nötig.
Neue Infrastruktur:
- glossar_eintraege_04.py: glossar_slug() + LINK_TEXTE-Map (automatisch
generiert aus EINTRAEGEN + Abkürzungs-Extraktion)
- erzeuge_glossar_04.py: jeder Eintrag bekommt {#gloss:<slug>}-Anchor
- build_version_04.py: resolve_glossar() — Auto-Linking + {gl:}-Marke
- web_04/site.css: .glossar-link (dezent, nicht wie Navigationslink)
5 neue Glossar-Einträge (waren als Begriff im Text, aber nicht im Glossar):
Solver, Scheduling, Graphen, Backtest, DCP (Disciplined Convex Programming)
Schutzmechanismen:
- Code-Blöcke, Inline-Code, {idx:}/{ref:}-Marken, Markdown-Links und
Überschriften werden nicht verlinkt
- Verschachtelung verhindert: 'CP-SAT-Solver' als Ganzes, nicht 'CP'+[
-'SAT'+[-'Solver'
- 'OR' als 2-Zeichen-Abkürzung nicht auto-verlinkt (False Positive in
'OR-Tools'); {gl:OR} als manuelle Marke
- Glossar selbst nicht auto-verlinkt (sonst Self-Links)
- reflow_markdown(): ::: als Block-Grenze (sonst kollabiert fenced div)
619 Glossar-Links im Gesamtdokument, 239 Anchor im Glossar, 34 im Vorwort.
This commit is contained in:
parent
81ddb02d5c
commit
e8abb66d75
52 changed files with 4316 additions and 1921 deletions
22
OR_HTML_04/metaheuristiken.html
generated
22
OR_HTML_04/metaheuristiken.html
generated
|
|
@ -103,9 +103,9 @@
|
|||
<div class="card card-blick">
|
||||
<blockquote>
|
||||
<p><strong>📌 Kapitel auf einen Blick</strong></p>
|
||||
<p><strong>Worum geht es?</strong> Um den Fall, für den die bisherigen Kapitel keine Antwort haben: Das Problem ist zu groß, der Solver kommt im Zeitlimit nicht zu einem brauchbaren Ergebnis — und eine Entscheidung muss trotzdem heute fallen.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="milp.html#kap-milp">Kapitel 6</a> und <a href="cpsat.html#kap-cpsat">Kapitel 7</a>, insbesondere <a href="milp.html#sec:milp-gap">Abschnitt 6.8</a> (MIP-Gap und Schranke).</p>
|
||||
<p><strong>Danach können Sie:</strong> eine lokale Suche mit ihrer entscheidenden Zutat — der Kostenänderung in O(1) — selbst schreiben, die Temperatur eines Simulated Annealing ausmessen statt raten, den Umschlagpunkt zwischen exakt und heuristisch für Ihr eigenes Problem bestimmen, und mit Large Neighborhood Search beides kombinieren.</p>
|
||||
<p><strong>Worum geht es?</strong> Um den Fall, für den die bisherigen Kapitel keine Antwort haben: Das Problem ist zu groß, der <a href="anhang-glossar.md#gloss:solver" class="glossar-link">Solver</a> kommt im Zeitlimit nicht zu einem brauchbaren Ergebnis — und eine Entscheidung muss trotzdem heute fallen.</p>
|
||||
<p><strong>Voraussetzungen:</strong> <a href="milp.html#kap-milp">Kapitel 6</a> und <a href="cpsat.html#kap-cpsat">Kapitel 7</a>, insbesondere <a href="milp.html#sec:milp-gap">Abschnitt 6.8</a> (<a href="anhang-glossar.md#gloss:mip-gap" class="glossar-link">MIP-Gap</a> und Schranke).</p>
|
||||
<p><strong>Danach können Sie:</strong> eine lokale Suche mit ihrer entscheidenden Zutat — der Kostenänderung in O(1) — selbst schreiben, die Temperatur eines <a href="anhang-glossar.md#gloss:simulated-annealing" class="glossar-link">Simulated Annealing</a> ausmessen statt raten, den Umschlagpunkt zwischen exakt und heuristisch für Ihr eigenes Problem bestimmen, und mit Large Neighborhood Search beides kombinieren.</p>
|
||||
<p><strong>Zeitbedarf:</strong> ca. 5 Stunden.</p>
|
||||
<p><strong>Programme:</strong><br />
|
||||
<code>Simulated_Annealing.py</code><br />
|
||||
|
|
@ -223,7 +223,7 @@ Optimal : Weiss -> Elfenbein -> Beige -> Rot -> Dunkelrot -> Sc
|
|||
<ol type="1">
|
||||
<li>… erklären, warum eine lokale Suche ohne <strong>Kostenänderung in O(1)</strong> praktisch wertlos ist.</li>
|
||||
<li>… Simulated Annealing implementieren und seine Starttemperatur <strong>an der Zuggröße</strong> kalibrieren statt am Zielfunktionswert.</li>
|
||||
<li>… den Beitrag der Metaheuristik gegen die einfachere Alternative abgrenzen — reines Bergsteigen — statt ihn ihr gutzuschreiben.</li>
|
||||
<li>… den Beitrag der <a href="anhang-glossar.md#gloss:metaheuristik" class="glossar-link">Metaheuristik</a> gegen die einfachere Alternative abgrenzen — reines Bergsteigen — statt ihn ihr gutzuschreiben.</li>
|
||||
<li>… den <strong>Umschlagpunkt</strong> bestimmen, ab dem eine Metaheuristik den exakten Solver schlägt, und begründen, warum diese Zahl problemspezifisch ist.</li>
|
||||
<li>… erklären, warum ein exakter Lauf auch dann dazugehört, wenn Sie am Ende die heuristische Lösung einsetzen.</li>
|
||||
<li>… Large Neighborhood Search aufsetzen: zerstören, exakt reparieren, übernehmen.</li>
|
||||
|
|
@ -278,14 +278,14 @@ Optimal : Weiss -> Elfenbein -> Beige -> Rot -> Dunkelrot -> Sc
|
|||
<p><strong>Ohne Formel gesagt:</strong> „Sortiere die Aufträge so, dass möglichst wenig geputzt werden muss.“</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
<p>Wer die Aufgabe als Graph liest, erkennt sie wieder: Es ist ein <strong>asymmetrisches Rundreiseproblem</strong> (<a href="graphen.html#kap-graphen">Kapitel 8</a>) mit offenem Ende. Das ist eine gute und eine schlechte Nachricht. Gut, weil damit alles bekannt ist, was man über das Problem wissen kann. Schlecht, weil dazu gehört, dass es NP-schwer ist.</p>
|
||||
<p>Wer die Aufgabe als Graph liest, erkennt sie wieder: Es ist ein <strong>asymmetrisches Rundreiseproblem</strong> (<a href="graphen.html#kap-graphen">Kapitel 8</a>) mit offenem Ende. Das ist eine gute und eine schlechte Nachricht. Gut, weil damit alles bekannt ist, was man über das Problem wissen kann. Schlecht, weil dazu gehört, dass es <a href="anhang-glossar.md#gloss:np-schwer" class="glossar-link">NP-schwer</a> ist.</p>
|
||||
<blockquote>
|
||||
<p><strong>📖 Definition: Metaheuristik</strong></p>
|
||||
<p>Ein <strong>Verfahrensrahmen</strong>, der eine vorhandene Lösung schrittweise verändert und dabei steuert, welche Veränderungen übernommen werden. „Meta“, weil der Rahmen nichts über das Problem weiß: Er braucht nur eine Startlösung, einen Zug und eine Bewertung. Dieselbe Mechanik läuft über Tourenplanung, Personaleinsatz und Portfolioauswahl.</p>
|
||||
<p>Der Preis dafür steht in derselben Zeile: Ein Verfahren, das nichts über das Problem weiß, kann auch nichts über die Güte seines Ergebnisses sagen. Es liefert eine Lösung, <strong>keine Schranke</strong>.</p>
|
||||
</blockquote>
|
||||
<h3 id="die-instanz">Die Instanz</h3>
|
||||
<p>Alle Programme dieses Kapitels benutzen dieselbe Aufgabe. Die Rüstzeit setzt sich aus zwei Teilen zusammen: einem unregelmäßigen Reinigungsaufwand zwischen den Produktfamilien und einem Zuschlag für den Wechsel von Dunkel nach Hell.</p>
|
||||
<p>Alle Programme dieses Kapitels benutzen dieselbe Aufgabe. Die <a href="anhang-glossar.md#gloss:ruestzeit" class="glossar-link">Rüstzeit</a> setzt sich aus zwei Teilen zusammen: einem unregelmäßigen Reinigungsaufwand zwischen den Produktfamilien und einem Zuschlag für den Wechsel von Dunkel nach Hell.</p>
|
||||
<p>Eine Feinheit der Instanz ist wichtiger, als sie aussieht: Die <strong>Zahl der Produktfamilien wächst mit der Auftragszahl</strong> (eine Familie je zehn Aufträge). Bei fester Familienzahl würde das Problem mit wachsendem <span class="math inline">n</span> nämlich <em>leichter</em> — der Plan bestünde irgendwann aus ein paar großen Blöcken, und jede Faustregel fände ihn. Beim ersten Entwurf dieses Kapitels ist mir genau das passiert: Die Metaheuristik verbesserte bei 60 Aufträgen um 30 %, bei 200 Aufträgen um 0 %. Nicht weil sie versagte, sondern weil es nichts mehr zu verbessern gab.</p>
|
||||
<hr />
|
||||
<h2 id="sec:metaheuristiken-lokale-suche">9.4 Lokale Suche: der Zug und seine Kosten</h2>
|
||||
|
|
@ -1052,7 +1052,7 @@ Und warum die Starttemperatur ausgemessen gehoert:
|
|||
<span id="cb6-230"><a href="#cb6-230" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"exakter Lauf dazu, wenn man am Ende die heuristische Loesung einsetzt:"</span>)</span>
|
||||
<span id="cb6-231"><a href="#cb6-231" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"nicht wegen seiner Loesung, sondern wegen seiner Schranke."</span>)</span>
|
||||
<span id="cb6-232"><a href="#cb6-232" aria-hidden="true" tabindex="-1"></a> <span class="bu">print</span>(<span class="st">"="</span> <span class="op">*</span> <span class="dv">88</span>)</span></code></pre></div>
|
||||
<p><strong>Erwartete Ausgabe</strong> (die CP-SAT-Spalten sind hardwareabhängig, siehe Programmkopf):</p>
|
||||
<p><strong>Erwartete Ausgabe</strong> (die <a href="anhang-glossar.md#gloss:cp-sat" class="glossar-link">CP-SAT</a>-Spalten sind hardwareabhängig, siehe Programmkopf):</p>
|
||||
<pre><code>========================================================================================
|
||||
AB WANN LOHNT SICH DIE METAHEURISTIK?
|
||||
========================================================================================
|
||||
|
|
@ -1106,7 +1106,7 @@ nicht wegen seiner Loesung, sondern wegen seiner Schranke.
|
|||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: right;">60</td>
|
||||
<td><strong>Exakt.</strong> CP-SAT beweist das Optimum in 2 Sekunden. Die Metaheuristik liegt 3,8 % daneben — und wüsste es nicht.</td>
|
||||
<td><strong>Exakt.</strong> <a href="anhang-glossar.md#gloss:constraint-programming-cp" class="glossar-link">CP</a>-<a href="anhang-glossar.md#gloss:sat-boolean-satisfiability" class="glossar-link">SAT</a> beweist das Optimum in 2 Sekunden. Die Metaheuristik liegt 3,8 % daneben — und wüsste es nicht.</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: right;">200</td>
|
||||
|
|
@ -1128,7 +1128,7 @@ nicht wegen seiner Loesung, sondern wegen seiner Schranke.
|
|||
<hr />
|
||||
<h2 id="sec:metaheuristiken-lns">9.7 Large Neighborhood Search</h2>
|
||||
<p>Die Tabelle oben endet mit einem Widerspruch. Bei 500 Aufträgen scheitert der exakte Solver an der <strong>Größe</strong>; die Metaheuristik scheitert an der <strong>Kleinheit ihrer Züge</strong> — sie verschiebt jeweils einen einzigen Auftrag und kann eine ganze Passage nicht auf einmal umbauen.</p>
|
||||
<p><strong>Large Neighborhood Search</strong> (LNS) setzt beide ein, jeden für das, was er kann:</p>
|
||||
<p><strong>Large Neighborhood Search</strong> (<a href="anhang-glossar.md#gloss:large-neighborhood-search-lns" class="glossar-link">LNS</a>) setzt beide ein, jeden für das, was er kann:</p>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 50%" />
|
||||
|
|
@ -1616,7 +1616,7 @@ Abstand zum Optimum.
|
|||
<td>Wenn es eine natürliche „Kreuzung“ zweier Lösungen gibt. Für Reihenfolgen ist genau das der schwierige Teil. Bibliothek: <code>pymoo</code>.</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td><strong>Tabu-Suche</strong></td>
|
||||
<td><strong><a href="anhang-glossar.md#gloss:tabu-suche" class="glossar-link">Tabu-Suche</a></strong></td>
|
||||
<td>Bergsteigen, das zuletzt gemachte Züge eine Zeit lang verbietet.</td>
|
||||
<td>Wenn die Suche zwischen zwei Zuständen pendelt. Oft mit weniger Kalibrierung als Annealing.</td>
|
||||
</tr>
|
||||
|
|
@ -1676,7 +1676,7 @@ Abstand zum Optimum.
|
|||
<h2 id="sec:metaheuristiken-zusammenfassung">9.13 Zusammenfassung</h2>
|
||||
<ul>
|
||||
<li>Eine <strong>Faustregel</strong> ist selten dumm, aber immer kurzsichtig: Sie bewertet einen Schritt danach, was er kostet, nicht danach, was er übrig lässt.</li>
|
||||
<li><strong>Lokale Suche</strong> steht und fällt mit der Kostenänderung in <span class="math inline">O(1)</span>. Wer den Zug über die volle Zielfunktion bewertet, misst am Ende seine Implementierung statt des Verfahrens.</li>
|
||||
<li><strong>Lokale Suche</strong> steht und fällt mit der Kostenänderung in <span class="math inline">O(1)</span>. Wer den Zug über die volle <a href="anhang-glossar.md#gloss:zielfunktion" class="glossar-link">Zielfunktion</a> bewertet, misst am Ende seine Implementierung statt des Verfahrens.</li>
|
||||
<li><strong>Simulated Annealing</strong> nimmt Verschlechterungen mit <span class="math inline">e^{-\Delta/T}</span> an. <span class="math inline">T</span> und <span class="math inline">\Delta</span> haben dieselbe Einheit — die Temperatur gehört an der <strong>Zuggröße</strong> kalibriert, nicht am Zielfunktionswert. Die verbreitete Regel „20 bis 50 % Annahmequote“ war auf dieser Aufgabe falsch.</li>
|
||||
<li>Der <strong>schlechteste Zwischenwert</strong> ist die beste Diagnosezahl eines Annealing-Laufs: Er zeigt eine zu heiße Starttemperatur sofort, ohne dass man das Ergebnis abwarten muss.</li>
|
||||
<li>Rechnen Sie <strong>immer</strong> das simple Bergsteigen mit. Hier lieferte es 93 % des Ertrags.</li>
|
||||
|
|
|
|||
Loading…
Reference in a new issue