在构造更复杂的目标函数时,鲁比误差因子必须是一个常数



当我为我的优化目标函数使用一个相当直接的成本函数时,gurobi给出了一个答案,但是当我用math.log()函数甚至用i**2代替i*i使事情复杂化时,它会产生类似于以下之一的错误:

GurobiError: Divisor must be a constant

TypeError: a float is required

TypeError: unsupported operand type(s) for ** or pow(): 'Var' and 'int'

我试图将math.log((m-i)/i)重新制定为math.log(m-i)- math.log(i),这会产生浮动所需的错误。将i*i更改为i**2会产生不支持的错误。

现在我的问题是:是否不可能在Gurobi中创建更复杂的函数?还是我在别的地方弄错了?

这是我的模型的一个片段

from gurobipy import *
import pandas as pd
import numpy as np
import time
import math
start_time = time.time()

# example NL (i, 20, 0.08, -6.7, 301)
def cost(i, j, k, l, m):
    cost = (j - l)*i + k*i*i - l*(m - i) * (math.log((m - i) / i ))
    return cost

def utility(i, j, k, l):
    utility = j + k*i + l*i*i
    return utility
"""
def cost(i, j, k, l):
    cost = j + k*i + .5*l*i*i
    return cost
"""
# assign files to use as input and as output
outputfile = 'model1nodeoutput.csv'
inputfile = 'marketclearinginput.xlsx'
# define dataframes
dfdemand = pd.read_excel(inputfile, sheetname="demand", encoding='utf8')
dfproducer = pd.read_excel(inputfile, sheetname="producer", encoding='utf8')
m = Model("1NodeMultiPeriod")
dofprod = [m.addVar(lb=3.0, ub=300, name=h) for h in dfproducer['name']]
dofdem = [m.addVar(lb=3.0, ub=300, name=h) for h in dfdemand['name']]
# Integrate new variables
m.update()
# Set objective
m.setObjective(quicksum([utility(i, j, k, l) for i, j, k, l
                        in zip(dofdem, dfdemand['c'], dfdemand['a'], dfdemand['b'])]) -
               quicksum([cost(i, j, k, l, m) for i, j, k, l, m
                        in zip(dofprod, dfproducer['c'], dfproducer['a'], dfproducer['b'], dfproducer['Pmax'])]),
               GRB.MAXIMIZE)
# Set constraints
# Set constraints for producers
for i, j, k in zip(dofprod, dfproducer['Pmin'], dfproducer['Pmax']):
    m.addConstr(i >= j)
    m.addConstr(i <= k)
# Set constraints for demand
for i, j, k in zip(dofdem, dfdemand['Pmin'], dfdemand['Pmax']):
    m.addConstr(i >= j)
    m.addConstr(i <= k)
# Build the timestamp list, pd or np unique both possible, pd faster and preserves order
# Timestamps skips the first 3 symbols (example L1T2034 becomes 2034)
timestamps = pd.unique([i.varName[3:] for i in dofprod])
# Set constraint produced >= demanded (this should be te last constraint added for shadow variables)
for h in timestamps:
    m.addConstr(quicksum([i for i in dofprod if i.varName.endswith(h)]) >=
                quicksum([i for i in dofdem if i.varName.endswith(h)]))

m.optimize()

您的问题可能与robi quicksum()函数有关。可以试试sum()

最新更新