简体   繁体   中英

Optimisation problem with two pandas dataframes using GEKKO

I have two dataframes with the same format looking like the following:

df1

            Value_0  Value_1  Value_2 ...
Date                                        
2020-11-07  7.830    19.630   30.584  ...
2020-11-08  11.100   34.693   40.589  ...
2020-11-09  12.455   34.693   41.236  ...
.
.
.

df2

            Value_0  Value_1  Value_2 ...
Date                                        
2020-11-07  153.601  61.014   55.367  ...
2020-11-08  119.011  70.560   49.052  ...
2020-11-09  133.925  103.417  61.651  ...
.
.
.

I'm trying to:

  1. Make a linear interpolation between each consecutive matching points (so y1 = df1.Value_0, y2 = df1.Value_1, x1 = df2.Value_0, x2 = df2.Value_1).
  2. Maximize the product of df1 and df2 for each Date and column pair considering all posible values from the interpolation.

My current approach is the following (This goes inside a loop to evaluate each pair of columns and then store the optimisation only for the highest value, but I'm neglecting it here for sake of simplicity):

i = 0 # Example for only one use case

# Initial model
m = gekko()

# Variables         
y1 = np.array(df1['Value_'+str(i)])
y2 = np.array(df1['Value_'+str(i+1)])
x1 = np.array(df2['Value_'+str(i)])
x2 = np.array(df2['Value_'+str(i+1)])

s = [None]*len(y1)
c = [None]*len(y1)
ex = [None]*len(y1)

for j in range(len(y1)):
    s[j] = (y1[j]-y2[j])/(x1[j]-x2[j]) # slope
    c[j] = (x1[j]*y2[j] - x2[j]*y1[j])/(x1[j]-x2[j]) # y intersect
    ex[j] = -c[j]/s[j] # x intersect
    
p = m.Var(lb=0, ub=y2) # specific boundaries for case when i=0
n = m.Var(lb=x2, ub=ex) # specific boundaries for case when i=0

# Constraint
m.Equation((s[j]*n)+c[j]==p for j in range(len(y1))) # equation of a line

# Objective function
m.Maximize(n*p)

m.solve(disp=False)

#print('p:'+str(p.value))
#print('n:'+str(n.value))

It's my first time using Gekko and I'm getting "@error: Inequality Definition invalid inequalities: z > x < y". I would appreciate any clues regarding what's wrong with the code/variables definition.

The lower and upper bound needs to be a single value, unless you define a separate variable for each data row. Is this a suitable replacement?

p = m.Var(lb=0, ub=max(y2))
n = m.Var(lb=min(x2), ub=max(ex))

Try using IMODE=2 to define the equation once and apply it to each data row. Here is a modification of the script that runs in mode 2.

from gekko import gekko
import numpy as np

# Initial model
m = gekko()

# Variables
ns = 10
y1 = np.random.rand(ns)
y2 = np.random.rand(ns)+1
x1 = np.random.rand(ns)
x2 = np.random.rand(ns)+1

s = [None]*len(y1)
c = [None]*len(y1)
ex = [None]*len(y1)

for j in range(len(y1)):
    # slope
    s[j] = (y1[j]-y2[j])/(x1[j]-x2[j])
    # y-intercept
    c[j] = (x1[j]*y2[j] - x2[j]*y1[j])/(x1[j]-x2[j])
    # x-intercept
    ex[j] = -c[j]/s[j]

s = m.Param(s); c = m.Param(c)
p = m.Var(lb=0, ub=max(y2))
n = m.Var(lb=min(x2), ub=max(ex))

# Constraint
m.Equation(s*n+c==p)

m.options.IMODE=2

# Objective function
m.Maximize(n*p)

m.solve(disp=True)

If separate upper and lower bounds are needed for each interpolation, then create an array of variables such as:

p = m.Array(m.Var,ns,lb=0)
n = m.Array(m.Var,ns)

More information on the modes of calculation are shown in the documentation.

Unique Inequality Constraints for Each Data Row

If unique inequality constraints are required for each data row, use inequality constraints as an equation definition.

p = m.Var(lb=0)
n = m.Var()

# implement constraints
x2 = m.Param(x2)
y2 = m.Param(y2)
ex = m.Param(ex)

m.Equation(p<y2)
m.Equations([n>x2,n<ex])

Below is a full script with the inequality constraints. The problem may be infeasible if all of the inequality constraints cannot be simultaneously satisfied.

from gekko import gekko
import numpy as np

# Initial model
m = gekko()

# Variables
ns = 10
y1 = np.random.rand(ns)
y2 = np.random.rand(ns)+1
x1 = np.random.rand(ns)
x2 = np.random.rand(ns)+1

s = [None]*len(y1)
c = [None]*len(y1)
ex = [None]*len(y1)

for j in range(len(y1)):
    # slope
    s[j] = (y1[j]-y2[j])/(x1[j]-x2[j])
    # y-intercept
    c[j] = (x1[j]*y2[j] - x2[j]*y1[j])/(x1[j]-x2[j])
    # x-intercept
    ex[j] = -c[j]/s[j]

s = m.Param(s); c = m.Param(c)
p = m.Var(lb=0)
n = m.Var()

# implement constraints
x2 = m.Param(x2)
y2 = m.Param(y2)
ex = m.Param(ex)

m.Equation(p<y2)
m.Equations([n>x2,n<ex])

# Constraint
m.Equation(s*n+c==p)

m.options.IMODE=2

# Objective function
m.Maximize(n*p)

m.solve(disp=True)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM