BYU-PRISM / GEKKO

GEKKO Python for Machine Learning and Dynamic Optimization
https://machinelearning.byu.edu
Other
573 stars 102 forks source link

How to handle conditional constraints in Gekko nonlinear optimization ?? #113

Closed tazuddin90 closed 3 years ago

tazuddin90 commented 3 years ago

Variable x1, X2;

Constraints:(with if statement)

If x1/x2>2: x1+x2>=10; Else: x1-x2>=5

Minimize: x1+x2+5

APMonitor commented 3 years ago

Use the m.if3() switch function to produce a 1 (True) or 0 (False) for the if statement. This binary switch is used to turn on or off equations.

from gekko import GEKKO

m = GEKKO()
x1,x2 = m.Array(m.Var,2,lb=-10,ub=10)
b = m.if3(x1/x2-2,0,1)         # binary switch
m.Equation(b*(x1+x2-10)>=0)    # x1+x2>=10 with True switch
m.Equation((1-b)*(x1-x2-5)>=0) # x1-x2>=5 with False switch
m.Minimize(x1+x2+5)
m.solve()

print(b.value[0])
print(x1.value[0])
print(x2.value[0])

Please ask future questions such as this on Stack Overflow with tag [gekko]. GitHub issues are typically geared towards feature enhancements or to report bugs with the software.

tazuddin90 commented 3 years ago

Thank you very much for your help. Now it is working fine..

tazuddin90 commented 3 years ago

Is it possible to use function as a constraint ?

Eg. Input Variables - x1, x2, x3

def fun(x1,x2,x3): if (x1>2): return x1+x2+x3+5; else: return x1-x2-3

I want to use this function as constraints like this.

m.Equation( fun(x1,x2,x3)>=2)

Minimize x1x2x3.

APMonitor commented 3 years ago

It isn't a problem to use a function but the condition needs to be as a m.if3() function. Here is additional information on conditional statements: https://apmonitor.com/wiki/index.php/Main/ConditionalStatements

def fun(x1,x2,x3):
   return m.if3(2-x1,x1+x2+x3+5,x1-x2-3)

m.Equation(fun(x1,x2,x3)>=2)
m.Minimize(x1*x2*x3)
tazuddin90 commented 3 years ago

Thank you very much for your reply. Actually my function is much more complicated in real case. I am unable to put it in this format

The function is as follows-

Function defination

def fun (x1,x2,x3):
      import tflite_runtime.interpreter as tflite
      interpreter = tf.lite.Interpreter (model_path = "modelpath/fire_lite_model.tflite")

      interpreter.allocate_tensors()

      input_details = interpreter.get_input_details()
      output_details = interpreter.get_output_details()

      input = [[5*x1, 2*x2, 3*x5]]
      input = np.float32(input)

      interpreter.set_tensor(input_details[0]['index'], input)
      interpreter.invoke()

      output_data = interpreter.get_tensor(output_details[0]['index'])

      return output_data

The objective function is also like this.

Is it possible to handle using GEKKO ?

APMonitor commented 3 years ago

Gekko needs to have all of the equations expressed with Gekko variables and equations so that it can compile the equations into bytecode and provide exact derivatives to the gradient-based solvers. Black box models are not allowed with Gekko. If it is 2 variables then you can create a b-spline or if the function is one variable then you can create a c-spline to approximate the original function. Your function has 3 variables so there isn't currently an approximation method for those. Maybe try Scipy.optimize.minimize if you do need to optimize with a black box model.

tazuddin90 commented 3 years ago

Thank you very much for your reply. Actually my function is much more complicated in real case. I am unable to put it in this format

The function is as follows-

Function defination

Variables = x1, x2,x3 def fun (x1,x2,x3): import tflite_runtime.interpreter as tflite

  interpreter = tf.lite.Interpreter (model_path = "modelpath/fire_lite_model.tflite")

  interpreter.allocate_tensors()

  input_details = interpreter.get_input_details()
  output_details = interpreter.get_output_details()

  input = [[5x1, 2x2, 3x5]]

  interpreter.set_tensor(input_details[0]['index'], input)
  interpreter.invoke()

  output_data = interpreter.get_tensor(output_details[0]['index'])

  return output_data

The objective function is also like this.

Is it possible to handle using GEKKO ?

Thank you so much for the info. I will try with scipy.