简体   繁体   中英

From PuLP to GEKKO: Syntax Mapping for Constraints, Objective Function

I'm working on a Staff Assignment Problem that was initially modeled in PuLP . However, during the development, some constraints as well as the objective became non-linear. After comparing some packages, I chose GEKKO , but somehow can't get my optimization up and running.

I'm facing two issues:

1. Constraint formulation

Let's assume I have simple constraints like these .

In PuLP I have something like:

# Each position p must be assigned to exactly one employee e
for p in position_names:
    succession_prob += pulp.lpSum([X[p][e] for e in employee_names]) == 1

# Only employees e that are qualified for position p can be selected
for p in position_names:
    for e in employee_names:
        succession_prob += X[p][e] <= position_mapping[p][e]

And I tried to do something like this in GEKKO :

# Each position p must be assigned to exactly one employee e
for p in range(len(position_names)):
    m.Equation(sum(X[p][e] for e in range(len(employee_names))) == 1)

# Only employees e that are qualified for position p can be selected
for p in range(len(position_names)):
    for e in range(len(employee_names)):
        m.Equation(X[p][e] <= position_mapping.iloc[e][p])

This doesn't give me an error but I'm not sure whether it is correct. However I get an error when I try to split the (rather complex) objective function:

2. Split objective function

# Dummy functions
numerator = pulp.lpSum(some expression)
denominator = pulp.lpSum(some other expression)

succession_prob += numerator / denominator

Again I tried to do something like this in GEKKO :

numerator = m.Param(some expression)
denominator = m.Param(some other expression)

# Objective function: RCD moves -> max
m.Obj((numerator / denominator)*(-1))

>>> ERROR: unsupported operand type(s) for *: 'float' and 'generator'

I'm wondering whether my code for the constraints correct (choice of variable types etc.), as well as how to fix the split objective. I'm grateful for any help, as I already tried out different variables and just can't it running.

For #1 your constraint formulation looks correct. You can check what Gekko writes by opening the run folder with m.open_folder() and open the .apm file with a text editor. It lists all of the equations, parameters, variables, and objective statements.

For #2 you may have something else wrong besides what you included there. Also, parameter values are fixed - the objective function typically has variable types that are adjusted by the optimizer. Otherwise, if the objective function consists of only parameter values then it is a constant that won't influence the solution except add or substract a constant from the objective.

Below is a simple program that you can use to investigate how Gekko is writing the model .apm file.

from gekko import GEKKO
import pandas as pd
m = GEKKO()
print(m._path)
x = m.Array(m.Var,(3,4))

mydict = [{'a': 1, 'b': 2, 'c': 3, 'd': 4},
           {'a': 100, 'b': 200, 'c': 300, 'd': 400},
           {'a': 1000, 'b': 2000, 'c': 3000, 'd': 4000 }]
w = pd.DataFrame(mydict)
y = [0,2]
z = [1,3]

for p in range(len(y)):
    m.Equation(sum(x[p][e] for e in range(len(z)))==1)

for p in range(len(y)):
    for e in range(len(z)):
        m.Equation(x[p][e] < w.iloc[e][p])

for p in range(np.size(x,0)):
    for e in range(np.size(x,1)):
        m.Obj(x[p][e]**2)

m.solve(disp=True)
print(x)
m.open_folder()

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