I am working on a Python program in which a small part includes optimizing the system of equations / inequalities. Ideally, I would like to do the same as in Modelica, write out the equations and let the solver take care of this.
Solvers and linear programming went a little out of my comfort zone, but I decided to try it anyway. The problem is that the overall design of the program is object-oriented, and there are many different combinations for generating equations, as well as some non-linearities, so I could not translate this into linear programming problem (but I can be wrong).
After some research, I found that the Z3 solver did what I wanted. I came up with this (this seems like a typical case of what I would like to optimize):
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()
Now it works and gives me the result that I want, despite the fact that it is not very fast (I need to solve such systems several thousand times). But I'm not sure I'm using the right tool for the job (Z3 is a “theoretical breakthrough”).
The API is basically what I need, but I would be curious if other packages allow similar syntax. Or should I try to formulate the problem differently to allow a standard LP approach? (although I have no idea how)
source share