Nonlinear global optimization in pyomo (calling gurobi)
AnsweredHi there,
I am trying to solve a global optimization problem (with nonlinearities sin() and cos()) using Gurobi v11 in Pyomo.
I have follows the v11 manual to create a factor representation for this nonlinear task. However, when I run it, it complains that my constraint contains nonlinear terms that cannot be written to LP format. I also think that I set the solver options properly. Could you please see what is wrong? I have attached my code below.
import numpy as np
import json
from matplotlib import pyplot as plt
import pyomo.environ as pyo
import math as mt
import pandas as pds
model = pyo.ConcreteModel()
solver = pyo.SolverFactory('gurobi')
#solver.options['MIPGapAbs'] = absGap/2
solver.options['NonConvex'] = 2
solver.options['FuncNonlinear'] = 1
model.t = pyo.Var()
model.x1 = pyo.Var(bounds = (0.5,1.2))
model.x2 = pyo.Var(bounds = (0.5,1.2))
model.x3 = pyo.Var(bounds = (0.0,0.3))
model.x4 = pyo.Var(bounds = (0.0,0.3))
model.x5 = pyo.Var(bounds = (0.90909,1.0909))
model.x6 = pyo.Var(bounds = (0.90909,1.0909))
model.x7 = pyo.Var(bounds = (0.90909,1.0909))
model.x8 = pyo.Var(bounds = (0.5,0.3))
model.x9 = pyo.Var(bounds = (0.5,0.3))
model.x8n = pyo.Var(bounds = (0.3,0.5))
model.x9n = pyo.Var(bounds = (0.3,0.5))
model.z1 = pyo.Var()
model.z2 = pyo.Var()
model.z3 = pyo.Var()
model.z4 = pyo.Var()
model.z5 = pyo.Var()
model.z6 = pyo.Var()
model.z7 = pyo.Var()
model.z8 = pyo.Var()
model.z9 = pyo.Var()
model.z10 = pyo.Var()
model.z11 = pyo.Var()
model.z12 = pyo.Var()
model.z13 = pyo.Var()
model.z9n = pyo.Var()
model.z14 = pyo.Var()
model.z15 = pyo.Var()
model.z16 = pyo.Var()
model.z17 = pyo.Var()
model.z18 = pyo.Var()
model.C = pyo.Param(initialize = (48.4/50.176)*pyo.sin(0.25))
model.D = pyo.Param(initialize = (48.4/50.176)*pyo.cos(0.25))
model.constraintA1 = pyo.Constraint(expr = model.x8 + model.x8n == 0)
model.constraintA2 = pyo.Constraint(expr = model.x9 + model.x9n == 0)
model.constraintA3 = pyo.Constraint(expr = model.z1 == model.x5*model.x6)
model.constraintA4 = pyo.Constraint(expr = model.z2 == pyo.sin(model.x8n))
model.constraintA5 = pyo.Constraint(expr = model.z3 == pyo.cos(model.x8n))
model.constraintA6 = pyo.Constraint(expr = model.z4 == pyo.sin(model.x9n))
model.constraintA7 = pyo.Constraint(expr = model.z5 == pyo.cos(model.x9n))
model.constraintA8 = pyo.Constraint(expr = model.z6 == model.x5*model.x7)
model.constraint1 = pyo.Constraint(expr = 0.4model.x1 + 2*model.C*model.x5**2+model.z1*(model.D*model.z2model.C*model.z3)+model.z6*(model.D*model.z4model.C*model.z5) == 0)
model.constraintA9 = pyo.Constraint(expr = model.z7 == pyo.sin(model.x8))
model.constraintA10 = pyo.Constraint(expr = model.z8 == pyo.cos(model.x8))
model.constraintA11 = pyo.Constraint(expr = model.z9 == model.x8model.x9)
model.constraintA12 = pyo.Constraint(expr = model.z10 == pyo.sin(model.z9))
model.constraintA13 = pyo.Constraint(expr = model.z11 == pyo.cos(model.z9))
model.constraint2 = pyo.Constraint(expr = 0.4model.x2 + 2*model.C*model.x6**2 + model.z1*(model.D*model.z7  model.C*model.z8) + model.z6*(model.D*model.z10  model.C*model.z11) == 0)
model.constraint3 = pyo.Constraint(expr = 0.2model.x3 + 2*model.D*model.x5**2  model.z1*(model.C*model.z2 + model.D*model.z3)  model.z6*(model.C*model.z4 + model.D*model.z5) == 0)
model.constraint4 = pyo.Constraint(expr = 0.2model.x4 + 2*model.D*model.x6**2  model.z1*(model.C*model.z7 + model.D*model.z8)  model.z6*(model.C*model.z10 + model.D*model.z11) == 0)
model.constraintA14 = pyo.Constraint(expr = model.z12 == pyo.sin(model.x9))
model.constraintA15 = pyo.Constraint(expr = model.z13 == pyo.cos(model.x9))
model.constraintA16 = pyo.Constraint(expr = model.z9n == model.z9)
model.constraintA17 = pyo.Constraint(expr = model.z14 == pyo.sin(model.z9n))
model.constraintA18 = pyo.Constraint(expr = model.z15 == pyo.cos(model.z9n))
model.constraintA19 = pyo.Constraint(expr = model.z16 == model.x6*model.x7)
model.constraint5 = pyo.Constraint(expr = 0.8 + 2*model.C*model.x7**2 + model.z6*(model.D*model.z12  model.C*model.z13) + model.z16*(model.D*model.z14  model.C*model.z15) == 0)
model.constraint6 = pyo.Constraint(expr = 0.337 + 2*model.D*model.x7**2model.z6*(model.C*model.z12 + model.D*model.z13)  model.z16*(model.C*model.z14 + model.D*model.z15) == 0)
model.constraintA20 = pyo.Constraint(expr = model.z17 == 3000*model.x1+1000*model.x1**3)
model.constraintA21 = pyo.Constraint(expr = model.z18 == 2000*model.x2+666.667*model.x2**3)
model.constraint7 = pyo.Constraint(expr = model.t >= model.z17 + model.z18)
model.objective = pyo.Objective(expr = model.t, sense=pyo.minimize)
results = solver.solve(model)
Thanks,
Yingkai

Hi Yingkai,
It sounds like Pyomo wants to write the model to file, then invoke Gurobi via the command line. It seems to be running into an error when writing the file. If this is occurring with the latest version of Pyomo I would open up an issue at https://github.com/Pyomo/pyomo/issues
As a workaround, can you try and use the "persistent" interface, which builds the model in Gurobi directly:
solver = pyo.SolverFactory('gurobi_persistent')
Of course you could also use gurobipy to solve the issue. I'm sure ChatGPT could do a quick conversion between your Pyomo code to gurobipy code.
 Riley
0 
Hi Riley,
Thanks for your reply!
Even though I could not find the source again, several days ago, I found a post from Gurobi saying that to use nonlinear term such as sin in Gurobi, I have to use Model.addGenContrSin() in gurobipy. This function of Gurobi is just incompatible with Pyomo's modeling language.
Thanks,
Yingkai
0
Please sign in to leave a comment.
Comments
2 comments