【问题标题】:How to iterate over external input list in pyomo objective function?如何在pyomo目标函数中迭代外部输入列表?
【发布时间】:2022-07-23 00:03:04
【问题描述】:

我正在尝试使用Gurobisolver 运行一个简单的 LP pyomo Concrete 模型:

import pyomo.environ as pyo
from pyomo.opt import SolverFactory

model = pyo.ConcreteModel()

nb_years = 3
nb_mins = 2
step = 8760*1.5
delta = 10000

#Range of hour
model.h = pyo.RangeSet(0,8760*nb_years-1)

#Individual minimums
model.min = pyo.RangeSet(0, nb_mins-1)

model.mins = pyo.Var(model.min, within=model.h, initialize=[i for i in model.min])

def maximal_step_between_mins_constraint_rule(model, min):

    next_min = min + 1 if min < nb_mins-1 else 0
    if next_min == 0: # We need to take circularity into account
        return 8760*nb_years - model.mins[min] + model.mins[next_min] <= step + delta
    return model.mins[next_min] - model.mins[min] <= step + delta

def minimal_step_between_mins_constraint_rule(model, min):

    next_min = min + 1 if min < nb_mins-1 else 0
    if next_min == 0: # We need to take circularity into account
        return 8760*nb_years - model.mins[min] + model.mins[next_min] >= step - delta
    return model.mins[next_min] - model.mins[min] >= step - delta

model.input_list = pyo.Param(model.h, initialize=my_input_list, within=pyo.Reals, mutable=False)

def objective_rule(model):

    return sum([model.input_list[model.mins[min]] for min in model.min])

model.maximal_step_between_mins_constraint= pyo.Constraint(model.min, rule=maximal_step_between_mins_constraint_rule)

model.minimal_step_between_mins_constraint= pyo.Constraint(model.min, rule=minimal_step_between_mins_constraint_rule)

model.objective = pyo.Objective(rule=objective_rule, sense=pyo.minimize)

opt = SolverFactory('gurobi')
results = opt.solve(model, options={'Presolve':2})

基本上,我试图在跨越 3 年的数据的输入列表 (which looks like this) 中找到两个小时,它们之间的距离受到限制,并且模型使两个值的总和最小化。

我将我的列表实现为固定值的参数,但是即使 mutable 设置为 False,运行我的模型也会产生此错误:

ERROR: Rule failed when generating expression for Objective objective with
    index None: RuntimeError: Error retrieving the value of an indexed item
    input_list: index 0 is not a constant value.  This is likely not what you
    meant to do, as if you later change the fixed value of the object this
    lookup will not change.  If you understand the implications of using non-
    constant values, you can get the current value of the object using the
    value() function.
ERROR: Constructing component 'objective' from data=None failed: RuntimeError:
    Error retrieving the value of an indexed item input_list: index 0 is not a
    constant value.  This is likely not what you meant to do, as if you later
    change the fixed value of the object this lookup will not change.  If you
    understand the implications of using non-constant values, you can get the
    current value of the object using the value() function.

知道为什么会出现此错误以及如何解决吗? 显然,将目标函数更改为sum([pyo.value(model.input_list[model.mins[min]]) for min in model.min]) 并不能解决我的问题。 我也尝试不使用 pyomo 参数(使用 sum([input_list[model.mins[min]] for min in model.min]) 之类的东西,但 pyomo 无法对其进行迭代并引发以下错误:

ERROR: Constructing component 'objective' from data=None failed: TypeError:
    list indices must be integers or slices, not _GeneralVarData

【问题讨论】:

    标签: python optimization linear-programming pyomo gurobi


    【解决方案1】:

    您的模型中有几个严重的语法和结构问题。并非所有元素都包含在您提供的代码中,但您(最少)需要修复这些:

    在这个sn-p中,你将每个变量的初始化为一个列表,这是无效的。从无变量初始化开始:

    model.mins = pyo.Var(model.min, within=model.h, initialize=[i for i in model.min])
    

    在这个总结中,您似乎使用了一个变量作为某些数据的索引。这是一个无效的构造。模型构建时变量的值为unkown。您需要重新制定:

    return sum([model.input_list[model.mins[min]] for min in model.min])
    

    我的建议:从非常小的块数据和pprint() 模型开始,并在尝试求解之前仔细阅读它的质量

    model.pprint()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      • 2021-10-28
      • 2023-03-10
      • 2017-02-15
      • 2020-02-06
      • 1970-01-01
      • 2021-08-04
      相关资源
      最近更新 更多