'Maximum polynomial degree is 2' docplex's error

228 Views Asked by At

I am using docplex (docplex.md.model) for a minimization problem, and my objective function has a product of three variables (one continuous and two binaries), when running the code I got this error:

DOcplexException: Cannot multiply -x1*x21 by x2, some terms would have degree >= 3. Maximum polynomial degree is 2.

How can I solve this issue?

And thank you.

1

There are 1 best solutions below

1
On

2 options with CPLEX:

  1. You use CPOptimizer and then you can write whatever constraint you need.

Within Easy optimization python see Non Linear function

from docplex.cp.model import CpoModel

mdl = CpoModel(name='buses')
nbbus40 = mdl.integer_var(0,1000,name='nbBus40')
nbbus30 = mdl.integer_var(0,1000,name='nbBus30')
mdl.add(nbbus40*40 + nbbus30*30 >= 300)

#non linear objective
mdl.minimize(mdl.exponent(nbbus40)*500 + mdl.exponent(nbbus30)*400)

msol=mdl.solve()

print(msol[nbbus40]," buses 40 seats")
print(msol[nbbus30]," buses 30 seats") 

But you need to turn your float decision variable into an expression

See https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoodecimalcpo.py

from docplex.cp.model import CpoModel

mdl = CpoModel(name='buses')

#now suppose we can book a % of buses not only complete buses

scale=100
scalenbbus40 = mdl.integer_var(0,1000,name='scalenbBus40')
scalenbbus30 = mdl.integer_var(0,1000,name='scalenbBus30')

nbbus40= scalenbbus40 / scale
nbbus30= scalenbbus30 / scale

 

mdl.add(nbbus40*40 + nbbus30*30 >= 310)
mdl.minimize(nbbus40*500 + nbbus30*400)

msol=mdl.solve()

print(msol[scalenbbus40]/scale," buses 40 seats")
print(msol[scalenbbus30]/scale," buses 30 seats")
  1. You stay with MIP but you change your constraint.

See multiply 2 binary variables

#suppose we want z=x*y

from docplex.mp.model import Model
mdl = Model(name='mutiply binary decision variables')

x = mdl.binary_var(name='x')
y = mdl.binary_var(name='y')

z= mdl.binary_var(name='z')

mdl.add(x+y<=1+z)
mdl.add(z<=x)
mdl.add(z<=y)

mdl.add(z==1)

# We could also write
#mdl.add(z==mdl.min(x,y))
# or
#mdl.add(z==(mdl.logical_and((x==1),(y==1))))


mdl.solve()

decisionVars=[x,y,z]

for v in decisionVars:
    print(v.name," = ",v.solution_value)

and multiply binary and other variable

from docplex.mp.model import Model
mdl = Model(name='mutiply binary by decision variable')

b = mdl.binary_var(name='b')
x = mdl.integer_var(name='x',lb=0,ub=10)

bx= mdl.integer_var(name='bx')

mdl.maximize(x)

mdl.add(bx<=7)

mdl.add(mdl.if_then((b==0),(bx==0)))
mdl.add(mdl.if_then((b==1),(bx==x)))

mdl.solve()

decisionVars=[b,x]

for v in decisionVars:
    print(v.name," = ",v.solution_value)