Exception: @error: Equation Definition Equation without an equality (=) or inequality (>,<) in gekko optimization

251 Views Asked by At

I'm working on a cost minimization problem. I tried again and again, but I always have this error:

"Exception: @error: Equation Definition Equation without an equality (=) or inequality (>,<) (((((150555-x1))(1.5)))(0.014428))(((((162915-x1))(1.5)))(0.014428)) STOPPING..." error.

Could it be an equation error? I am not very good at Gekko. I heard that it gives optimal solution. How can I fix it? Thanks.

from gekko import GEKKO
import numpy as np

a1=np.array([ 93542, 128957, 150555, 162915, 138111, 167849,
       101090, 169190, 127892, 162915, 138111, 167849,
       101090, 169190, 127892 ])
a2=np.array([1394312, 1268702, 122504, 123269, 101303,  90893,
        99909,  96047,  97409, 122504, 123269, 101303,  90893,
        99909,  96047,  97409 ])
a3=np.array([133712, 121702, 126504, 22669, 10803,  90893,
        99009,  91047,  97409,  122504, 123269, 101303,  90893,
        99909,  96047,  97409])
a4=np.array([57428, 16631, 1567, 1264, 1462, 1434,
       107626, 106313,  90475, 100726, 442378, 407667,
        95518, 128901, 124170, 122504, 123269, 101303,  90893,
        99909,  96047,  97409 ])
a5=np.array([148428, 166371, 132867, 510264, 145462, 648634,
       107626, 195313,  90475, 105726, 122504, 123269, 101303,  90893,
        99909,  96047,  97409])

#definition variable
sa1=-np.sort(-a1)
sa2=-np.sort(-a2)
sa3=-np.sort(-a3)
#max8.
a1max8=sa1[7]
a2max8=sa2[7]
a3max8=sa3[7]
#max and min definition
a1min=np.min(a1)
a1max=np.max(a1)
a2min=np.min(a2)
a2max=np.max(a2)
a3min=np.min(a3)
a3max=np.max(a3)
a4min=np.min(a4)
a4max=np.max(a4)
a5min=np.min(a5)
a5max=np.min(a5)

# Initialize Model
m = GEKKO(remote=False)

#initialize variables
x,x1,x2,x3,x4 = [m.Var() for i in range(5)]

x= m.Var(lb=2000, ub=7000, name='x')
x1= m.Var(lb=a1min, ub=a1max, name='x1')
x2= m.Var(lb=a2min, ub=a2max, name='x2')
x3= m.Var(lb=a3min, ub=a3max, name='x3')
x4= m.Var(lb=a4min, ub=a4max, name='x4')
x5= m.Var(lb=a5min, ub=a5max, name='x5')

m.Equation(x1>=a1max8)
m.Equation(x2>=a2max8)
m.Equation(x3>=a3max8)

m.Obj((((((((x1-x)*1.3+x)*0.014428)+(a1-x1)*1.5*0.014428)+(((x2-x)*1.3+x)*0.014428)+((a2-x2)*1.5*0.014428)+
(((x3-x)*1.3+x)*0.014428)+((a3-x3)*1.5*0.014428)+
(((x4-x)*1.3+x)*0.014428)+((a4-x4)*1.5*0.014428)+
(((x5-x)*1.3+x)*0.014428)+((a5-x5)*1.5*0.014428)))))

m.options.IMODE = 3 
m.solve() 

print('Results')
print('x: ' + str(x.value))
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('x4: ' + str(x4.value))
print('x5: ' + str(x5.value))

Edit with Error Resolved

I am grateful for your help sir...I updated the model so my model is a bit more complicated. I don't get that error anymore. Although i chose Minimize model, the solution is the upper bound value. I wonder how can I solve this problem.

from gekko import GEKKO
import numpy as np

a1=np.array([ 93542, 128957, 150555, 162915, 138111, 167849,
       101090, 169190, 127892, 162915, 138111, 167849,
       101090, 169190, 127892 ])
a2=np.array([1394312, 1268702, 122504, 123269, 101303,  90893,
        99909,  96047,  97409, 122504, 123269, 101303,  90893,
        99909,  96047,  97409 ])
a3=np.array([133712, 121702, 126504, 22669, 10803,  90893,
        99009,  91047,  97409,  122504, 123269, 101303,  90893,
        99909,  96047,  97409])
a4=np.array([57428, 16631, 1567, 1264, 1462, 1434,
       107626, 106313,  90475, 100726, 442378, 407667,
        95518, 128901, 124170, 122504, 123269, 101303,  90893,
        99909,  96047,  97409 ])
a5=np.array([148428, 166371, 132867, 510264, 145462, 648634,
       107626, 195313,  90475, 105726, 122504, 123269, 101303,  90893,
        99909,  96047,  97409,50000])

#definition variable
sa1=-np.sort(-a1)
sa2=-np.sort(-a2)
sa3=-np.sort(-a3)
#max8.
a1max8=sa1[7]
a2max8=sa2[7]
a3max8=sa3[7]
#max and min definition
a1min=np.min(a1)
a1max=np.max(a1)
a2min=np.min(a2)
a2max=np.max(a2)
a3min=np.min(a3)
a3max=np.max(a3)
a4min=np.min(a4)
a4max=np.max(a4)
a5min=np.min(a5)
a5max=np.min(a5)

# Initialize Model
m = GEKKO(remote=False)

#initialize variables
x,x1,x2,x3,x4,x5 = [m.Var() for i in range(6)]

x= m.Var(lb=2000, ub=7000, name='x')
x1= m.Var(lb=a1min, ub=a1max, name='x1')
x2= m.Var(lb=a2min, ub=a2max, name='x2')
x3= m.Var(lb=a3min, ub=a3max, name='x3')
x4= m.Var(lb=a4min, ub=a4max, name='x4')
x5= m.Var(lb=a5min, ub=a5max, name='x5')

m.Equation(x1>=a1max8)
m.Equation(x2>=a2max8)
m.Equation(x3>=a3max8)

m.Minimize((((((((x1-x)*1.3+x)*0.014428)+(sum(a1-x1))*1.5*0.014428)+\
              (((x2-x)*1.3+x)*0.014428)+((sum(a2-x2))*1.5*0.014428)+\
              (((x3-x)*1.3+x)*0.014428)+((sum(a3-x3))*1.5*0.014428)+\
              (((x4-x)*1.3+x)*0.014428)+((sum(a4-x4))*1.25*0.014428)+\
              (((x5-x)*1.3+x)*0.014428)+((sum(a5-x5))*1.1*0.014428)))))

m.solve() 

print('Results')
print('x: ' + str(x.value))
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('x4: ' + str(x4.value))
print('x5: ' + str(x5.value))

this is the result

Results
x: [7000.0]
x1: [169190.0]
x2: [1394312.0]
x3: [133712.0]
x4: [1264.0000155]
x5: [50000.0]
1

There are 1 best solutions below

0
On

The problem is in the objective function

m.Obj((((((((x1-x)*1.3+x)*0.014428)+(a1-x1)*1.5*0.014428)+\
   (((x2-x)*1.3+x)*0.014428)+((a2-x2)*1.5*0.014428)+\
   (((x3-x)*1.3+x)*0.014428)+((a3-x3)*1.5*0.014428)+\
   (((x4-x)*1.3+x)*0.014428)+((a4-x4)*1.5*0.014428)+\
   (((x5-x)*1.3+x)*0.014428)+((a5-x5)*1.5*0.014428)))))

where there is a size mismatch between the single value of x1-x5 as a gekko variable and the multiple values of a1-a5 as numpy arrays. You can fix this by switching to a single value of a1[0]-a5[0].

# for the first values of a1-a5 with a1[0]-a5[0]
m.Minimize((((((((x1-x)*1.3+x)*0.014428)+(a1[0]-x1)*1.5*0.014428)+\
              (((x2-x)*1.3+x)*0.014428)+((a2[0]-x2)*1.5*0.014428)+\
              (((x3-x)*1.3+x)*0.014428)+((a3[0]-x3)*1.5*0.014428)+\
              (((x4-x)*1.3+x)*0.014428)+((a4[0]-x4)*1.5*0.014428)+\
              (((x5-x)*1.3+x)*0.014428)+((a5[0]-x5)*1.5*0.014428)))))

You can also have multiple minimize functions in a loop that have the difference with a1[i]-a5[i] as individual values.

# for all values of a1-a5
y = [x1,x2,x3,x4,x5]
a = [a1,a2,a3,a4,a5]
for i in range(5):
    for j in range(len(a1)):
        m.Minimize((a[i][j]-y[i])*1.5*0.014428)

Here is the complete script with both options:

from gekko import GEKKO
import numpy as np

a1=np.array([ 93542, 128957, 150555, 162915, 138111, 167849,
       101090, 169190, 127892, 162915, 138111, 167849,
       101090, 169190, 127892 ])
a2=np.array([1394312, 1268702, 122504, 123269, 101303,  90893,
        99909,  96047,  97409, 122504, 123269, 101303,  90893,
        99909,  96047,  97409 ])
a3=np.array([133712, 121702, 126504, 22669, 10803,  90893,
        99009,  91047,  97409,  122504, 123269, 101303,  90893,
        99909,  96047,  97409])
a4=np.array([57428, 16631, 1567, 1264, 1462, 1434,
       107626, 106313,  90475, 100726, 442378, 407667,
        95518, 128901, 124170, 122504, 123269, 101303,  90893,
        99909,  96047,  97409 ])
a5=np.array([148428, 166371, 132867, 510264, 145462, 648634,
       107626, 195313,  90475, 105726, 122504, 123269, 101303,  90893,
        99909,  96047,  97409])

#definition variable
sa1=-np.sort(-a1)
sa2=-np.sort(-a2)
sa3=-np.sort(-a3)
#max8.
a1max8=sa1[7]
a2max8=sa2[7]
a3max8=sa3[7]
#max and min definition
a1min=np.min(a1)
a1max=np.max(a1)
a2min=np.min(a2)
a2max=np.max(a2)
a3min=np.min(a3)
a3max=np.max(a3)
a4min=np.min(a4)
a4max=np.max(a4)
a5min=np.min(a5)
a5max=np.min(a5)

# Initialize Model
m = GEKKO(remote=False)

#initialize variables
x,x1,x2,x3,x4 = [m.Var() for i in range(5)]

x= m.Var(lb=2000, ub=7000, name='x')
x1= m.Var(lb=a1min, ub=a1max, name='x1')
x2= m.Var(lb=a2min, ub=a2max, name='x2')
x3= m.Var(lb=a3min, ub=a3max, name='x3')
x4= m.Var(lb=a4min, ub=a4max, name='x4')
x5= m.Var(lb=a5min, ub=a5max, name='x5')

m.Equation(x1>=a1max8)
m.Equation(x2>=a2max8)
m.Equation(x3>=a3max8)

# for the first values of a1-a5 with a1[0]-a5[0]
m.Minimize((((((((x1-x)*1.3+x)*0.014428)+(a1[0]-x1)*1.5*0.014428)+\
              (((x2-x)*1.3+x)*0.014428)+((a2[0]-x2)*1.5*0.014428)+\
              (((x3-x)*1.3+x)*0.014428)+((a3[0]-x3)*1.5*0.014428)+\
              (((x4-x)*1.3+x)*0.014428)+((a4[0]-x4)*1.5*0.014428)+\
              (((x5-x)*1.3+x)*0.014428)+((a5[0]-x5)*1.5*0.014428)))))

# for all values of a1-a5
y = [x1,x2,x3,x4,x5]
a = [a1,a2,a3,a4,a5]
for i in range(5):
    for j in range(len(a1)):
        m.Minimize((a[i][j]-y[i])*1.5*0.014428)

m.options.IMODE = 3 
m.solve() 

print('Results')
print('x: ' + str(x.value))
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('x4: ' + str(x4.value))
print('x5: ' + str(x5.value))

The other option is to switch to IMODE=2 and declare a1-a5 as m.Param() as:

m.options.IMODE=2
a1p = m.Param(a1)
a2p = m.Param(a2)
a3p = m.Param(a3)
a4p = m.Param(a4)
a5p = m.Param(a5)

IMODE=2 operates with the same equations on multiple data sets. I recommend the other options for now but this is an option if you want your code to run more efficiently for large-scale problems.

Response to Edit

The result is correct. The problem that you have posed is a linear programming problem so the solution is guaranteed to be optimal. The solver reports a successful solution when it satisfies the Karush Kuhn Tucker conditions. The reason that the variables go to their upper bounds is that you have 22 of -x1 (and the other variables too). If you are trying to perform regression to fit to a1 values then you may need to modify your objective function such as sum((a1-x1)**2).