От PuLP к GEKKO: сопоставление синтаксиса для ограничений, целевая функция - PullRequest
1 голос
/ 02 июля 2019

Я работаю над проблемой назначения персонала , которая была первоначально смоделирована в PuLP. Однако во время разработки некоторые ограничения, а также цель стали нелинейными. После сравнения некоторых пакетов я выбрал GEKKO , но почему-то не могу запустить мою оптимизацию.

У меня две проблемы:

1. Формулировка ограничения

Давайте предположим, что у меня есть простые ограничения, такие как эти .

В PuLP У меня есть что-то вроде:

# 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]

И я попытался сделать что-то подобное в 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])

Это не дает мне ошибки, но я не уверен, правильно ли это. Однако я получаю сообщение об ошибке при попытке разбить (довольно сложную) целевую функцию:

2. Сплит-функция цели

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

succession_prob += numerator / denominator

Снова я попытался сделать что-то подобное в 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'

Мне интересно, правильный ли мой код для ограничений (выбор типов переменных и т. Д.), А также как исправить цель разделения. Я благодарен за любую помощь, так как я уже опробовал различные переменные и просто не могу его запустить.

1 Ответ

1 голос
/ 08 июля 2019

Для # 1 ваша формулировка ограничения выглядит правильно.Вы можете проверить, что пишет Gekko, открыв папку run с помощью m.open_folder() и открыв файл .apm в текстовом редакторе.В нем перечислены все уравнения, параметры, переменные и объективные утверждения.

Для # 2 у вас может быть что-то другое, кроме того, что вы там включили.Кроме того, значения параметров являются фиксированными - целевая функция обычно имеет типы переменных, которые настраиваются оптимизатором.В противном случае, если целевая функция состоит только из значений параметров, то это константа, которая не будет влиять на решение, кроме как добавить или вычесть константу из цели.

Ниже приведена простая программа, которую вы можете использовать для исследованиякак Гекко пишет файл модели .apm.

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()
...