Ich arbeite an einem Programm in Python, in dem ein kleiner Teil die Optimierung eines Systems von Gleichungen/Ungleichungen beinhaltet. Im Idealfall hätte ich das tun wollen, was in Modelica gemacht werden kann, schreibe die Gleichungen aus und lasse den Solver sich darum kümmern.Python - Optimiere das System der Ungleichungen
Der Betrieb von Solvern und lineare Programmierung ist ein wenig außerhalb meiner Komfortzone, aber ich habe mich trotzdem entschieden. Das Problem ist, dass der allgemeine Entwurf des Programms objektorientiert ist, und es gibt viele verschiedene Kombinationsmöglichkeiten, um die Gleichungen zu bilden, sowie einige Nichtlinearitäten, so dass ich nicht in der Lage war, dies in eine lineare Programmierung zu übersetzen Problem (aber ich könnte falsch liegen).
Nach einigen Recherchen fand ich, dass der Z3 Löser schien zu tun, was ich wollte. Ich kam mit diesem (das sieht aus wie ein typischer Fall von dem, was Ich mag würde optimieren):
from z3 import *
a = Real('a')
b = Real('b')
c = Real('c')
d = Real('d')
e = Real('e')
g = Real('g')
f = Real('f')
cost = Real('cost')
opt = Optimize()
opt.add(a + b - 350 == 0)
opt.add(a - g == 0)
opt.add(c - 400 == 0)
opt.add(b - d * 0.45 == 0)
opt.add(c - f - e - d == 0)
opt.add(d <= 250)
opt.add(e <= 250)
opt.add(cost == If(f > 0, f * 50, f * 0.4) + e * 40 + d * 20 +
If(g > 0, g * 50, g * 0.54))
h = opt.minimize(cost)
opt.check()
opt.lower(h)
opt.model()
Jetzt das funktioniert, und gibt mir das Ergebnis, das ich will, obwohl es nicht extrem schnell zu sein (ich muß solche Systeme mehrere tausend Mal lösen). Aber ich bin mir nicht sicher, ob ich das richtige Werkzeug für den Job verwende (Z3 ist ein "Theorembeweiser").
Die API ist im Grunde genau das, was ich brauche, aber ich wäre neugierig, wenn andere Pakete eine ähnliche Syntax erlauben. Oder sollte ich versuchen, das Problem anders zu formulieren, um einen Standard-LP-Ansatz zu ermöglichen? (obwohl ich keine Ahnung habe, wie)
Ein LP-Solver sollte in der Lage sein, dies in etwa 0 Sekunden zu lösen, da dies wirklich winzig ist. –
Ja, aber wie kann ich eine Reihe von "if" Bedingungen in der Funktion verwalten? Die Lösungen, die ich gesehen habe, scheinen irgendwie hackisch zu sein und würden in meinem Fall nicht wirklich funktionieren. –
Ich denke, dass dies mit Hilfe der Variablenaufteilung implementiert werden kann. Ie. Einführung nicht negativer Variablen 'fplus, fmin'. Fügen Sie die Einschränkung 'f = fplus-fmin' hinzu. Das erste 'if' wird dann:' 50 fplus-0.4 fmin'. –