{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Vorwort & Lesehilfe\n", "\n", "Begleitnotebook zu *Optimierte Entscheidungsfindung mit Python*. Die Codezellen sind identisch mit den im Buch abgedruckten Programmen.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Einmalig ausfuehren: installiert alle im Buch verwendeten Pakete.\n", "# Lokal in einer virtuellen Umgebung genauso gueltig wie in Google Colab.\n", "%pip install --quiet ortools highspy cvxpy scipy numpy pandas polars \\\n", " scikit-learn matplotlib plotly pyomo linopy pymoo pydantic openpyxl" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Installationstest {-}\n", "\n", "`Installationstest.py`\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#!/usr/bin/env python3\n", "\n", "# Installationstest.py\n", "\"\"\"\n", "Vorspann: Prüft die vollständige Kurs-Installation.\n", "Ausgabe: eine Zeile pro Paket plus ein gelöstes Mini-Modell je Solver-Familie.\n", "\"\"\"\n", "\n", "import importlib.metadata\n", "import importlib.util\n", "import logging\n", "import sys\n", "\n", "PAKETE = [\n", " (\"numpy\", \"Numerische Basis (Vektoren, Matrizen)\"),\n", " (\"scipy\", \"Wissenschaftliche Algorithmen, linprog/minimize\"),\n", " (\"pandas\", \"Tabellen und Zeitreihen\"),\n", " (\"matplotlib\", \"Diagramme\"),\n", " (\"ortools\", \"Google OR-Tools: CP-SAT und Routing\"),\n", " (\"highspy\", \"HiGHS-Solver, direkte Steuerung\"),\n", " (\"cvxpy\", \"Konvexe Optimierung (Portfolio, CVaR)\"),\n", " (\"sklearn\", \"Ledoit-Wolf-Shrinkage der Kovarianzmatrix\"),\n", " (\"yfinance\", \"Kursdatenbezug (nur die Finanzkapitel)\"),\n", "]\n", "\n", "# Nur auf Anwesenheit prüfen, NICHT importieren (siehe Kapitel Ökosystem):\n", "# - highspy: seine HiGHS-Bibliothek verträgt sich nicht mit der Kopie von\n", "# ortools im selben Prozess.\n", "# - cvxpy: importiert bei der Solver-Erkennung ein installiertes highspy\n", "# selbst mit und löst so denselben Konflikt aus. Importiert wird cvxpy\n", "# erst im Funktionstest, nachdem ortools bereits geladen ist.\n", "NUR_PRUEFEN = {\"highspy\", \"cvxpy\"}\n", "\n", "def paket_version(name: str) -> str:\n", " \"\"\"Liefert die installierte Version; ImportError, falls das Paket fehlt.\"\"\"\n", " if name in NUR_PRUEFEN:\n", " if importlib.util.find_spec(name) is None:\n", " raise ImportError(name) # nicht installiert\n", " try:\n", " # Version aus den Metadaten — das Modul wird ja nicht geladen\n", " return importlib.metadata.version(name)\n", " except importlib.metadata.PackageNotFoundError:\n", " return \"unbekannt\" # installiert, aber ohne Metadaten\n", " modul = importlib.import_module(name)\n", " return getattr(modul, \"__version__\", \"unbekannt\")\n", "\n", "def pruefe_pakete() -> list[str]:\n", " \"\"\"Prüft jedes Paket und meldet Version oder Fehlgrund.\"\"\"\n", " fehlend = []\n", " print(f\"Python-Version: {sys.version.split()[0]}\\n\")\n", " print(f\"{'Paket':<12} {'Version':<12} {'Zweck'}\")\n", " print(\"-\" * 78)\n", " for name, zweck in PAKETE:\n", " try:\n", " print(f\"{name:<12} {paket_version(name):<12} {zweck}\")\n", " except ImportError:\n", " print(f\"{name:<12} {'FEHLT':<12} {zweck}\")\n", " fehlend.append(name)\n", " return fehlend\n", "\n", "def teste_cp_sat() -> bool:\n", " \"\"\"Löst 'maximiere x+y unter x+2y<=10, x<=4' mit CP-SAT. Erwartet: x=4, y=3.\"\"\"\n", " from ortools.sat.python import cp_model\n", " modell = cp_model.CpModel()\n", " x = modell.NewIntVar(0, 4, \"x\")\n", " y = modell.NewIntVar(0, 10, \"y\")\n", " modell.Add(x + 2 * y <= 10)\n", " modell.Maximize(x + y)\n", " loeser = cp_model.CpSolver()\n", " status = loeser.Solve(modell)\n", " ok = status == cp_model.OPTIMAL and loeser.Value(x) == 4 and loeser.Value(y) == 3\n", " print(f\"CP-SAT : x={loeser.Value(x)}, y={loeser.Value(y)} -> {'OK' if ok else 'FEHLER'}\")\n", " return ok\n", "\n", "def teste_scipy_linprog() -> bool:\n", " \"\"\"Löst dasselbe Problem kontinuierlich mit HiGHS über SciPy. Erwartet: x=4, y=3.\"\"\"\n", " from scipy.optimize import linprog\n", " # linprog minimiert -> Zielfunktion negieren, um zu maximieren\n", " ergebnis = linprog(c=[-1, -1], A_ub=[[1, 2]], b_ub=[10],\n", " bounds=[(0, 4), (0, 10)], method=\"highs\")\n", " ok = ergebnis.success and abs(ergebnis.x[0] - 4) < 1e-6 and abs(ergebnis.x[1] - 3) < 1e-6\n", " print(f\"SciPy/HiGHS : x={ergebnis.x[0]:.2f}, y={ergebnis.x[1]:.2f} -> {'OK' if ok else 'FEHLER'}\")\n", " return ok\n", "\n", "def teste_cvxpy() -> bool:\n", " \"\"\"Minimiert (x-2)^2 unter x<=1 mit CVXPY. Erwartet: x=1.\"\"\"\n", " # CVXPY warnt beim Import, wenn sein HIGHS-Interface wegen der\n", " # HiGHS-Kollision (siehe Kapitel Ökosystem) nicht lädt — für diesen Test\n", " # folgenlos, deshalb die Warnung kurz stillstellen.\n", " logging.disable(logging.WARNING)\n", " import cvxpy as cp\n", " logging.disable(logging.NOTSET)\n", " x = cp.Variable()\n", " problem = cp.Problem(cp.Minimize(cp.square(x - 2)), [x <= 1])\n", " problem.solve()\n", " ok = problem.status == \"optimal\" and abs(x.value - 1.0) < 1e-6\n", " print(f\"CVXPY : x={x.value:.4f} -> {'OK' if ok else 'FEHLER'}\")\n", " return ok\n", "\n", "if __name__ == \"__main__\":\n", " # ortools' native Bibliothek zuerst laden (Kapitel Ökosystem): die zuerst\n", " # geladene HiGHS-Kopie gewinnt — und das soll die von ortools sein.\n", " if importlib.util.find_spec(\"ortools\") is not None:\n", " from ortools.sat.python import cp_model\n", "\n", " fehlend = pruefe_pakete()\n", " print(\"\\nSolver-Funktionstest\")\n", " print(\"-\" * 78)\n", " if fehlend:\n", " print(f\"Abbruch: Es fehlen {len(fehlend)} Pakete: {', '.join(fehlend)}\")\n", " print(\"Installation: pip install \" + \" \".join(\n", " \"scikit-learn\" if p == \"sklearn\" else p for p in fehlend))\n", " sys.exit(1)\n", "\n", " alle_ok = all([teste_cp_sat(), teste_scipy_linprog(), teste_cvxpy()])\n", " print(\"-\" * 78)\n", " print(\"Alles bereit — Sie können mit dem ersten Kapitel beginnen.\"\n", " if alle_ok else \"Mindestens ein Solver arbeitet fehlerhaft.\")\n", " sys.exit(0 if alle_ok else 1)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.11" } }, "nbformat": 4, "nbformat_minor": 5 }