Der einzige Punkt, der in diesem Projekt je als "blockiert" gefuehrt wurde,
ist erledigt. Die Begruendung lautete: Die VRP-Instanz sei ein synthetisches
100 x 100-km-Raster ohne Geokoordinaten, eine echte Karte verlange also
ENTWEDER eine neue Instanz (und damit zwei Dutzend neue abgedruckte Zahlen)
ODER eine willkuerliche Verankerung.
Es gibt einen dritten Weg, und er ist exakt. Eine azimutal-aequidistante
Projektion um den Schwerpunkt des Rasters bildet die 17 Punkte so auf Laenge
und Breite ab, dass die Grosskreisdistanzen mit den Rasterdistanzen
uebereinstimmen:
festes cos(Breite) Median 0,360 % Maximum 2,003 %
cos der eigenen Breite Median 0,351 % Maximum 0,908 %
azimutal-aequidistant Median 0,000 % Maximum 0,001 %
Ein Meter auf hundert Kilometer. Kein abgedruckter Wert aendert sich, die
Gesamtstrecke bleibt bei 619 km, das SVG ist byte-identisch geblieben.
Zwei Befunde stuetzten die Entscheidung: "100 x 100 km Raster" steht nur in
zwei Codekommentaren, nirgends im Fliesstext; und der didaktische Punkt der
Bildunterschrift - die sich kreuzenden Touren, die KEIN Fehler sind - wird auf
einer Karte deutlicher.
erzeuge_vrp_touren.py schreibt jetzt SVG UND Karte aus einem Lauf. Ein zweites
Skript haette erneut geloest, und die Routing-Bibliothek arbeitet heuristisch.
pruefe_projektion() bricht ab, wenn die Verzerrung 0,01 % ueberschreitet - die
Zahl im Buch wird bei jedem Lauf bewiesen.
Neu im Build: die Marke {karte:name}, aufgeloest zu einem <iframe> (Leaflets
Stylesheet soll nicht in die Buchseite greifen), im PDF zum Verweissatz - wie
bei {plotly:}. --check bewacht jetzt beide Markenarten auf Existenz der Datei;
gegengeprueft mit einer absichtlich falschen Marke.
Zwei Vorkehrungen, die ohne Messung nicht aufgefallen waeren:
* Folium vergibt jedem Element eine uuid4 - jeder Lauf erzeugte eine andere
Datei. normalisiere() ersetzt sie durch fortlaufende Nummern; zwei Laeufe
liefern jetzt dieselbe Pruefsumme.
* Folium bindet ZEHN CDN-Ressourcen ein (jQuery, Bootstrap, Glyphicons,
FontAwesome, awesome-markers ...). Gebraucht werden ZWEI. leaflet.js und
leaflet.css liegen jetzt in web_04/assets/, die uebrigen acht entfallen.
Nachgeprueft: Die Karte benutzt ausschliesslich L.*-Aufrufe. Ohne Netz
fehlen nur die Kacheln, Marker und Touren bleiben sichtbar.
Gegenrechnung an vier Strecken: Depot -> K1 misst auf der Karte 27,20 km, die
Distanzmatrix sagt 27 - die Differenz stammt aus deren int(), nicht aus der
Geographie.
Veroeffentlicht: 8 Dateien uebertragen, alle dreizehn HTTP-Proben richtig, die
Karte auf dem Server unter 200 erreichbar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
116 lines
4.2 KiB
TOML
116 lines
4.2 KiB
TOML
# Paketbeschreibung fuer die Beispielprogramme des Buchs
|
|
# "Optimierte Entscheidungsfindung mit Python".
|
|
#
|
|
# Zweck: schlanke, gezielt zusammengestellte Umgebungen. Wer nur die ersten
|
|
# Kapitel durcharbeitet, braucht weder yfinance noch FastAPI.
|
|
#
|
|
# pip install -e . # Grundausstattung, traegt den Grossteil des Buchs
|
|
# pip install -e ".[finance]" # Teil "Anwendungen": Markowitz, CVaR, Handelsmaschine
|
|
# pip install -e ".[large-scale]" # HiGHS, Pyomo, linopy, polars
|
|
# pip install -e ".[api]" # Kapitel "Testen, Messen, Ausliefern"
|
|
# pip install -e ".[figures]" # nur zum Neuerzeugen der Diagramme
|
|
# pip install -e ".[dev]" # Tests
|
|
# pip install -e ".[alles]" # alles zusammen - siehe Warnung unten
|
|
#
|
|
# ACHTUNG, Solverkonflikt: ortools und highspy bringen jeweils eine eigene
|
|
# HiGHS-Kopie mit und lassen sich nicht im selben Prozess importieren. ortools
|
|
# steht deshalb in der Grundausstattung, highspy erst in [large-scale] - wer nur
|
|
# "pip install -e ." nutzt, kann in den Konflikt gar nicht geraten. cvxpy zieht
|
|
# ein installiertes highspy bei der Solver-Erkennung selbst mit hinein, [finance]
|
|
# loest ihn also indirekt ebenfalls aus. Die Programme des Buchs umgehen das
|
|
# durch getrennte Prozesse (Muster: Ein_System_Vier_Ansaetze.py); ausfuehrlich
|
|
# steht es im Kapitel "Das Python-Oekosystem fuer OR".
|
|
#
|
|
# Die Datei ergaenzt
|
|
# Operations_Research_mit_Python_Version_04_Programme/requirements.txt und
|
|
# ersetzt sie nicht: Jene ist im Buch abgedruckt und installiert bewusst alles
|
|
# auf einen Schlag.
|
|
|
|
[build-system]
|
|
requires = ["setuptools>=68"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "or-mit-python"
|
|
version = "4.0.0"
|
|
description = "Beispielprogramme zum Buch 'Optimierte Entscheidungsfindung mit Python'"
|
|
readme = "README.md"
|
|
requires-python = ">=3.10"
|
|
authors = [{ name = "Dieter Schlüter", email = "dieter.schlueter@linix.de" }]
|
|
keywords = ["operations-research", "optimierung", "linear-programming",
|
|
"constraint-programming", "milp", "lehrbuch"]
|
|
|
|
# Grundausstattung: traegt die Kapitel bis einschliesslich Graphen und Touren.
|
|
# scipy liefert linprog/milp, ortools den CP-SAT-Solver und pywraplp.
|
|
dependencies = [
|
|
"numpy>=2.5.2",
|
|
"scipy>=1.17.1",
|
|
"pandas>=3.0.1",
|
|
"matplotlib>=3.10.8",
|
|
"openpyxl>=3.1.5", # kein direkter Import: Excel-Motor hinter pandas
|
|
"pydantic>=2.12",
|
|
"ortools>=9.15.6755",
|
|
# cvxpy gehoert in die Grundausstattung, nicht in [finance]: Es wird von
|
|
# 13 Programmen gebraucht, darunter dreien im Kapitel Unsicherheit, lange
|
|
# vor dem Finanzteil. Es zieht KEIN highspy nach - der Solverkonflikt
|
|
# entsteht erst mit [large-scale].
|
|
"cvxpy>=1.9.2",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
# Teil "Anwendungen - Energiewirtschaft und Finanzmaerkte"
|
|
finance = [
|
|
"scikit-learn>=1.8.0",
|
|
"yfinance>=1.2.0",
|
|
]
|
|
|
|
# Groessere Modelle, alternative Solver und Modellierungsschichten
|
|
large-scale = [
|
|
"highspy>=1.15.1",
|
|
"Pyomo>=6.7",
|
|
"linopy>=0.3",
|
|
"polars>=1.0",
|
|
]
|
|
|
|
# Kapitel "Testen, Messen, Ausliefern": der Optimierungsdienst
|
|
api = [
|
|
"fastapi>=0.115",
|
|
"uvicorn>=0.30",
|
|
"httpx>=0.27", # Selbsttest des Dienstes ueber den TestClient
|
|
]
|
|
|
|
# Nur zum Neuerzeugen der Diagramme in bilder_04/ - fuer das Lesen und
|
|
# Ausfuehren des Buchs nicht noetig. graphviz braucht zusaetzlich das
|
|
# Kommandozeilenwerkzeug 'dot' aus dem Betriebssystempaket.
|
|
figures = [
|
|
"plotly>=6.0",
|
|
"graphviz>=0.20",
|
|
"folium>=0.19", # die Leaflet-Karte der VRP-Touren
|
|
]
|
|
|
|
dev = [
|
|
"pytest>=8.0",
|
|
]
|
|
|
|
# Die 25 Kapitel-Notebooks im Browser ausfuehren - ohne dass jemand etwas
|
|
# installieren muss. Das Kurs-Image (Dockerfile) bringt diese Gruppe mit.
|
|
notebook = [
|
|
"jupyterlab>=4.0",
|
|
]
|
|
|
|
# pymoo wird im Buch als Bibliothek fuer genetische Algorithmen empfohlen
|
|
# (Kapitel Metaheuristiken), aber von keinem Beispielprogramm importiert.
|
|
# Deshalb steht es hier eigenstaendig und nicht in der Grundausstattung.
|
|
empfehlungen = [
|
|
"pymoo>=0.6",
|
|
]
|
|
|
|
alles = [
|
|
"or-mit-python[finance,large-scale,api,figures,dev,notebook,empfehlungen]",
|
|
]
|
|
|
|
[tool.setuptools]
|
|
# Die Beispielprogramme sind ein erzeugtes Artefakt (extract_programme_04.py)
|
|
# und kein installierbares Paket - hier wird nur der Abhaengigkeitsbaum
|
|
# beschrieben.
|
|
packages = []
|