Как перебрать переменную решения Gurobi в интегрированном нормальном распределении, которое включает возведение в степень - PullRequest
0 голосов
/ 13 января 2020

Моя проблема: Итерации по Gurobi "Var" переменная решения создает TypeError: '<' не поддерживается между экземплярами 'Var' и 'int' </strong> и проблема с экспонента (т.е. ** / pow ())

Ключевая информация по оптимизации Gurobi:

  • Функция цели: для трех элементов максимизировать сумму (цена * ожидаемое значение )
  • Ожидаемое значение рассчитывается по двум определенным формулам:
  • 1) PDF = функция плотности вероятности
  • 2) EV = ожидаемое значение, которое представляет собой интеграцию PDF по конкретный c интеграл
  • переменная решения "upperBound" должна максимизировать верхнюю границу этого интеграла, нижняя граница - 0

ниже модели:

from gurobipy import *
import pandas as pd, numpy as np, scipy.integrate as integrate
import math

mu = pd.DataFrame(np.array([10, 15]), index = ["product1", "product2"])
sigma = pd.DataFrame(np.array([1, 1.5]), index = mu.index.values)
price = pd.Series(np.array([10, 10]), index = mu.index.values)

m = Model("maxUpperBound")
ub = m.addVars(mu.index.values, vtype=GRB.INTEGER, name="upperBound")

def PDF (y, mu, sigma):
    return y * (1.0 / (sigma * (2.0 * math.pi)**(1/2)) * math.exp(-1.0 * (y - mu)**2 / (2.0 * (sigma**2))))

def EV(ub, mu, sigma):
    lb = 0
    value, error = integrate.quad(PDF, lb, ub, args=(mu, sigma))
    return value

m.setObjective(
    quicksum(
        price.loc[i] * EV(ub[i], mu.loc[i], sigma.loc[i])
        for i in mu.index.values
    ),
    GRB.MAXIMIZE)

m.addConstr(
    (quicksum(ub[i]
              for i in mu.index.values)
     <= 100),
    "Limit100"
)

m.optimize()

for v in m.getVars():
    print(v.varName, v.x)

Ответы [ 2 ]

0 голосов
/ 17 января 2020

Gurobi не может оптимизировать по отношению к функции PDF, поскольку это не смешанные целочисленные задачи, состоящие из линейных (выпуклых или невыпуклых) квадратичных c или ограничений / целей второго порядка.

Вместо этого решил эту проблему, рассчитав ожидаемое значение авансом для каждой комбинации product_ub. ub может принимать значения от 0 до 100 (см. ограничение). Затем использовали ожидаемое значение в целевой функции.

0 голосов
/ 14 января 2020

Ваш код немного сложен для чтения, но эти строки, вероятно, вызывают ошибку:

ub = m.addVars(mu.index.values, vtype=GRB.INTEGER, name="upperBound")
...
for ub in ub[i]:

ub - это tupledict, а ub[i] будет ссылаться на один объект Var. Вы не можете перебрать одну переменную.

Я думаю, вы хотите написать что-то вроде этого:

for ub_i in ub:

РЕДАКТИРОВАТЬ

Проблема была решено на форуме Gurobi :

tldr: Целевая функция слишком сложна и не может быть обработана Gurobi в этой форме.

...