operations_research/OR_HTML_04/programme/Matrixform.py
dschlueter b7af2f1d9a Version 04 als eigenes Repository
Erster Commit des Strangs "Optimierte Entscheidungsfindung mit Python"
(Version 04). Die Historie der 71 Commits bis zur Trennung bleibt im
uebergeordneten Repository OR_mit_Python liegen, das ab jetzt nur noch
Version_03 (eingefroren) verwaltet und Version_04/ ignoriert.

Bewusst kein "git subtree split": Der Pfad Version_04/ existiert erst seit
der Verzeichnistrennung, ein Split braechte daher nur 7 der 41 einschlaegigen
Commits - eine Teilhistorie, die vollstaendig aussieht und es nicht ist.

Stand: 5 Teile, 23 Kapitel, 5 Anhaenge, 292 Abschnitte, 703 Querverweise,
325 Indexmarken, 73 Beispielprogramme, 32 SVGs, 4 Plotly-Figuren,
25 Notebooks, PDF mit 715 Seiten.

Zusaetzlich in diesem Commit:

* pyproject.toml mit Abhaengigkeitsgruppen finance, large-scale, api,
  figures, dev, empfehlungen. Die abgedruckte requirements.txt bleibt
  unveraendert daneben bestehen. ortools steht in der Grundausstattung,
  highspy erst in [large-scale] - so kann der HiGHS-Symbolkonflikt bei der
  schlanken Installation gar nicht erst auftreten.

* Dabei zwei Funde: graphviz wird von erzeuge_architektur_diagramme.py
  importiert, fehlt aber in requirements.txt (jetzt in [figures]); pymoo
  steht in requirements.txt, wird aber von keinem Programm importiert,
  sondern nur im Kapitel Metaheuristiken empfohlen (jetzt in
  [empfehlungen]).

* NEUER_TITEL.md nach Kritik_und_Verbesserungsvorschlaege/ verschoben - es
  ist die Vorlage des Titelblatts, kein Bestandteil des Werks. Die beiden
  Fundstellen in PROGRESS.md und erzeuge_titelseite.py nachgezogen.

* PROGRESS.md nannte noch den Untertitel der ersten Fassung; auf den
  tatsaechlichen aus erzeuge_titelseite.py korrigiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 01:20:09 +02:00

54 lines
2.4 KiB
Python

#!/usr/bin/env python3
# Matrixform.py
"""
Kapitel Fundament: Von der ausgeschriebenen Form zur Matrixform - und zurück.
Zeigt, dass beide Schreibweisen dasselbe Modell beschreiben.
"""
import numpy as np
from scipy.optimize import linprog
# --- Modell in Matrixform -------------------------------------------------
# max 3*x1 + 5*x2 u.d.N. x1 <= 4, 2*x2 <= 12, 3*x1 + 2*x2 <= 18, x >= 0
c = np.array([3.0, 5.0]) # Ertragsvektor (Maximierung)
A = np.array([[1.0, 0.0], # Zeile 1: nur x1 kommt vor
[0.0, 2.0], # Zeile 2: nur x2 kommt vor
[3.0, 2.0]]) # Zeile 3: beide
b = np.array([4.0, 12.0, 18.0])
namen = ["Rohstoff A", "Rohstoff B", "Maschinenzeit"]
# --- Ausgeschriebene Form maschinell erzeugen ------------------------------
def zeige_ausgeschrieben(c, A, b, namen):
"""Druckt die Matrixform als lesbares Ungleichungssystem."""
terme = " + ".join(f"{c[j]:g}*x{j+1}" for j in range(len(c)))
print(f"max {terme}")
print("u.d.N.")
for i in range(A.shape[0]):
summanden = " + ".join(f"{A[i, j]:g}*x{j+1}"
for j in range(A.shape[1]) if A[i, j] != 0)
print(f" {summanden:<24} <= {b[i]:>5g} ({namen[i]})")
print(f" x1, ..., x{len(c)} >= 0")
zeige_ausgeschrieben(c, A, b, namen)
# --- Zulässigkeit eines Punktes prüfen ------------------------------------
def ist_zulaessig(x, A, b, toleranz=1e-9):
"""Prüft A x <= b und x >= 0 komponentenweise."""
verbrauch = A @ x # Matrix-Vektor-Produkt: alle Zeilen auf einmal
return bool(np.all(verbrauch <= b + toleranz) and np.all(x >= -toleranz))
for kandidat in [np.array([2.0, 6.0]), np.array([4.0, 3.0]), np.array([4.0, 6.0])]:
zulaessig = ist_zulaessig(kandidat, A, b)
zielwert = c @ kandidat
verbrauch = A @ kandidat
print(f"\nx = {kandidat} -> A x = {verbrauch} "
f"{'zulaessig' if zulaessig else 'UNZULAESSIG'}, Z = {zielwert:g}")
# --- Lösen: linprog minimiert, also c negieren -----------------------------
ergebnis = linprog(c=-c, A_ub=A, b_ub=b, bounds=[(0, None)] * len(c), method="highs")
print("\n" + "-" * 60)
print(f"Optimale Loesung: x* = {np.round(ergebnis.x, 4)}")
print(f"Optimaler Wert: Z* = {-ergebnis.fun:g}")
print("Hinweis: linprog minimiert, deshalb wurde c negiert und das")
print(" Ergebnis am Ende wieder mit -1 multipliziert.")