There are a few packages available for MINLP solutions in Python including pyomo
and gekko
. Here is a way to solve an MINLP problem with Python Gekko (a package that I maintain) as a simple example. Install the gekko
package that includes the APOPT MINLP solver with pip
:
pip install gekko
MINLP Solution
Gekko also solves Mixed Integer Nonlinear Programming (MINLP) problems such as:
from gekko import GEKKO
m = GEKKO(remote=False)
x = m.Array(m.Var,5,lb=0,ub=1,integer=True)
def f(x):
return ((5+x[0])/(4+x[1])) \
+(365.54/(3+x[2]))/(375.88/(3+x[3]))\
+(379.75/(3+x[4]))
m.Minimize(f(x))
m.Equation(sum(x)==2)
m.options.SOLVER=1
m.solve()
print(x)
This gives the solution:
Iter: 1 I: 0 Tm: 0.00 NLPi: 4 Dpth: 0 Lvs: 3 Obj: 9.69E+01 Gap: NaN
--Integer Solution: 9.69E+01 Lowest Leaf: 9.69E+01 Gap: 2.89E-04
Iter: 2 I: 0 Tm: 0.00 NLPi: 1 Dpth: 1 Lvs: 3 Obj: 9.69E+01 Gap: 2.89E-04
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 9.000000001833541E-003 sec
Objective : 96.9099912206023
Successful solution
---------------------------------------------------
[[0.0] [1.0] [0.0] [0.0] [1.0]]
The APOPT solver uses a branch and bound solution approach with Nonlinear Programming (NLP) sub-problems to find integer solutions. There are several additional packages listed here: Python Mixed Integer Linear Programming for MILP (and some with MINLP) solvers. The Scipy package will have a Mixed Integer Linear Programming (MILP) solver at the next release, but this doesn't help with your MINLP problem. Gurobi, CPLEX, and Mosel-Xpress are the leaders in MILP/MIQP solvers, but are all commercial solvers. I also recently added an answer to the post you referenced: Restrict scipy.optimize.minimize to integer values in your search for an MINLP solver. If your problem can be reformulated to MILP then this opens up your solution to many other packages.
MILP Solution
Here is a script example that solves a linear programming problem with variables that are restricted to binary values (0 or 1) by specifying upper and lower bounds with integer=True
:
from gekko import GEKKO
m = GEKKO()
x,y = m.Array(m.Var,2,integer=True,lb=0,ub=1)
m.Maximize(y)
m.Equations([-x+y<=1,
3*x+2*y<=12,
2*x+3*y<=12])
m.options.SOLVER = 1
m.solve()
print('Objective: ', -m.options.OBJFCNVAL)
print('x: ', x.value[0])
print('y: ', y.value[0])
This generates the solution:
Iter: 1 I: 0 Tm: 0.00 NLPi: 2 Dpth: 0 Lvs: 0 Obj: -1.00E+00 Gap: 0.00E+00
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 1.369999999951688E-002 sec
Objective : -1.00000000000000
Successful solution
---------------------------------------------------
Objective: 1.0
x: 1.0
y: 1.0