如何在包括求幂的集成正态分布中迭代 Gurobi 决策变量
How to iterate over a Gurobi decision variable in an integrated normal distribution that includes exponentiation
我的问题:遍历 Gurobi "Var" 决策变量 创建 TypeError: '<' 在 'Var' 和 'Var' 的实例之间不支持'int' 和 求幂问题 (即 **/ pow())
Gurobi优化关键信息:
- Objective 函数:对于三个项目最大化(价格 * 期望值)
的总和
- 预期值通过两个定义的公式计算:
- 1) PDF = 概率密度函数
- 2) EV = 期望值,它是 PDF 在 a 上的积分
具体积分
- 决策变量"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)
您的代码有点难以阅读,但这些行可能会导致错误:
ub = m.addVars(mu.index.values, vtype=GRB.INTEGER, name="upperBound")
...
for ub in ub[i]:
ub
是一个元组字典,而 ub[i]
将引用一个 Var 对象。您不能迭代单个 Var.
我猜你想写这样的东西:
for ub_i in ub:
编辑
问题已在 Gurobi forum:
中解决
tldr: objective 功能太复杂,Gurobi 无法以这种形式处理。
Gurobi 无法针对 PDF 函数进行优化,因为这不是由线性、(凸或非凸)二次或二阶组成的混合整数问题 constraints/objective。
而是通过预先计算每个 product_ub 组合的预期值来解决这个问题。 ub 可以取 0 到 100 之间的值(参见约束)。此后在 objective 函数中使用预期值。
我的问题:遍历 Gurobi "Var" 决策变量 创建 TypeError: '<' 在 'Var' 和 'Var' 的实例之间不支持'int' 和 求幂问题 (即 **/ pow())
Gurobi优化关键信息:
- Objective 函数:对于三个项目最大化(价格 * 期望值) 的总和
- 预期值通过两个定义的公式计算:
- 1) PDF = 概率密度函数
- 2) EV = 期望值,它是 PDF 在 a 上的积分 具体积分
- 决策变量"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)
您的代码有点难以阅读,但这些行可能会导致错误:
ub = m.addVars(mu.index.values, vtype=GRB.INTEGER, name="upperBound")
...
for ub in ub[i]:
ub
是一个元组字典,而 ub[i]
将引用一个 Var 对象。您不能迭代单个 Var.
我猜你想写这样的东西:
for ub_i in ub:
编辑
问题已在 Gurobi forum:
中解决tldr: objective 功能太复杂,Gurobi 无法以这种形式处理。
Gurobi 无法针对 PDF 函数进行优化,因为这不是由线性、(凸或非凸)二次或二阶组成的混合整数问题 constraints/objective。
而是通过预先计算每个 product_ub 组合的预期值来解决这个问题。 ub 可以取 0 到 100 之间的值(参见约束)。此后在 objective 函数中使用预期值。