Gekko Non-Linear optimization, object type error in constraint function evaluating if statement

2024/11/14 20:29:15

I'm trying to solve a non-linear optimization problem. I've duplicated my issue by creating the code below. Python returns TypeError: object of type 'int' has no len(). How can I include an IF statement in my constraint functions?

Console prints the following:

  File "<ipython-input-196-8d29d410dcea>", line 1, in <module>runfile('C:/Users/***/Documents/***/Project/untitled.py', wdir='C:/Users/***/Documents/***/***/Project')File "C:\Users\***\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 704, in runfileexecfile(filename, namespace)File "C:\Users\***\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfileexec(compile(f.read(), filename, 'exec'), namespace)File "C:/Users/***/Documents/***/***/Project/untitled.py", line 27, in <module>m.Equation(Cx(x1,x2,x3,x4) < 0)File "C:/Users/***/Documents/***/***/Project/untitled.py", line 17, in Cxif K > 15:File "C:\Users\***\Anaconda3\lib\site-packages\gekko\gk_operators.py", line 25, in __len__return len(self.value)File "C:\Users\***\Anaconda3\lib\site-packages\gekko\gk_operators.py", line 134, in __len__return len(self.value)TypeError: object of type 'int' has no len()

-

from gekko import GEKKO
m = GEKKO()def Cr(x1,x2,x3,x4):return (x1*x4*(x1+x2+x3)+x3**2)def Cw(x1,x2,x3,x4):return x1*x2*x3*x4def Ck(x1,x2,x3,x4):return x1*x2*x3*x4+1def Cx(x1,x2,x3,x4):K = Ck(x1,x2,x3,x4)if K > 15:  #Issue hereK = 15return x1**2+x2**2+x3**2+x4**2 - Kx1 = m.Var(value=1,lb=-5000,ub=5000)
x2 = m.Var(value=1,lb=-5000,ub=5000)
x3 = m.Var(value=1,lb=-5000,ub=5000)
x4 = m.Var(value=1,lb=-5000,ub=5000)m.Equation(Cw(x1,x2,x3,x4) >= 14)
m.Equation(Cx(x1,x2,x3,x4) < 0)m.Obj(Cr(x1,x2,x3,x4))m.solve(disp=False)
print(x1.value)
print(x2.value)
print(x3.value)
print(x4.value)

-

I am looking to have GEKKO run with the IF statement in the constraint, I'm not concerned if the optimization problem in the code has a solution. Thank you in advance.

Answer

(Disclaimer: i don't know this lib or what it will do for you)

The if-statement makes this problen non-differentiable which invalidates the assumption of NLP solvers (like Ipopt).

In terms of MINLP solvers (Bonmin, Couenne), this could be achieved by reformulation (and the resulting problem is differentiable when the needed auxiliary binary variables have been relaxed). It's hardly questionable to expect the lib to do it for you.

So it seems you need to play by the rules of some MINLP model like for example described by Bonmin here. There is no concept for "if-based branching".

Either introduce an indicator-variable like it's common in the MIP world, see here. Ignoring the overhead the idea would be something like:

K_ = Ck(x1,x2,x3,x4)
I = K_ > 15 (binary variable; see link for formulation idea)return x1**2+x2**2+x3**2+x4**2 - I*15 - (1-I) * K_

This is an MINLP then.

You might get away without using an additional binary variable (and touching MINLPs) when interpreting your equation like:

return x1**2+x2**2+x3**2+x4**2 - min(Ck(x1,x2,x3,x4), 15)

This is also non-differentiable, but can be easily reformulated (with a quirk) like:

return x1**2+x2**2+x3**2+x4**2 - A# extra constraints
A <= Ck(x1,x2,x3,x4)
A <= 15

if we could enforce moving towards the biggest A possible. This means, it must be part of the objective:

m.Obj(Cr(x1,x2,x3,x4) + c * A) (if it's a maximization problem)

This would be a NLP then, but the value of c needs some care (it must be big enough).

https://en.xdnf.cn/q/71821.html

Related Q&A

Store large dictionary to file in Python

I have a dictionary with many entries and a huge vector as values. These vectors can be 60.000 dimensions large and I have about 60.000 entries in the dictionary. To save time, I want to store this aft…

Python: override __str__ in an exception instance

Im trying to override the printed output from an Exception subclass in Python after the exception has been raised and Im having no luck getting my override to actually be called.def str_override(self):…

How hide/show a field upon selection of a radio button in django admin?

models.pyfrom django.db import models from django.contrib.auth.models import UserSTATUS_CHOICES = ((1, Accepted),(0, Rejected),) class Leave(models.Model):----------------status = models.IntegerField(c…

format/round numerical legend label in GeoPandas

Im looking for a way to format/round the numerical legend labels in those maps produced by .plot() function in GeoPandas. For example:gdf.plot(column=pop2010, scheme=QUANTILES, k=4)This gives me a lege…

Python pickle crash when trying to return default value in __getattr__

I have a dictionary like class that I use to store some values as attributes. I recently added some logic(__getattr__) to return None if an attribute doesnt exist. As soon as I did this pickle crashe…

How to download google source code for android

As you know, there is a list of several hundred projects in https://android.googlesource.com/. Id like to download them all in windows machine. According to Googles document,To install, initialize, and…

Compute on pandas dataframe concurrently

Is it feasible to do multiple group-wise calculation in dataframe in pandas concurrently and get those results back? So, Id like to compute the following sets of dataframe and get those results one-by…

How do I go about writing a program to send and receive sms using python?

I have looked all over the net for a good library to use in sending and receiving smss using python but all in vain!Are there GSM libraries for python out there?

Persist Completed Pipeline in Luigi Visualiser

Im starting to port a nightly data pipeline from a visual ETL tool to Luigi, and I really enjoy that there is a visualiser to see the status of jobs. However, Ive noticed that a few minutes after the l…

How to assign python requests sessions for single processes in multiprocessing pool?

Considering the following code example:import multiprocessing import requestssession = requests.Session() data_to_be_processed = [...]def process(arg):# do stuff with arg and get urlresponse = session.…