pyomo 中 objective 函数的有效更新(用于重新求解)

efficient update of objective function in pyomo (for re-solving)

我有一个模型需要多次求解,具有不同的 objective 函数系数。 自然地,我想花尽可能少的时间更新模型。 我当前的设置如下(简化):

抽象模型:

def obj_rule(m):
    return sum(Dist[m, n] * m.flow[m,n] for (m,n) in m.From * m.To)
m.obj = Objective(rule=obj_rule, sense=minimize)

解决后,我以这种方式更新具体模型实例mi,我们在Dist:

中添加新值
mi.obj = sum(Dist[m, n] * mi.flow[m,n] for (m,n) in mi.From * mi.To)

但是,我发现更新行花费了很多时间 - 大约。整体解决方案时间的 1/4,对于更大的情况需要几秒钟。 有没有更快的方法来更新 objective 函数? (毕竟,在通常保存 LP 模型的方式中,objective 函数系数位于一个单独的向量中,因此更改它们应该不会影响任何其他内容。)

您是否有理由在创建具体模型之前定义抽象模型?如果您使用上面显示的规则定义您的具体模型,您应该能够更新您的数据并重新求解模型而不会产生大量开销,因为您没有重新定义 objective 对象。这是一个简单的示例,其中我更改了成本参数的值并重新求解。

import pyomo.environ as pyo
a = list(range(2)) # set the variables define over

#%% Begin basic model
model = pyo.ConcreteModel()
model.c = pyo.Param(a,initialize={0:5,1:3},mutable=True)

model.x = pyo.Var(a,domain = pyo.Binary)
model.con = pyo.Constraint(expr=model.x[0] + model.x[1] <= 1)

def obj_rule(model):
    return(sum(model.x[ind] * model.c[ind] for ind in a))

model.obj = pyo.Objective(rule=obj_rule,sense=pyo.maximize)

#%% Solve the first time
solver = pyo.SolverFactory('glpk')

res=solver.solve(model)
print('x[0]: {} \nx[1]: {}'.format(pyo.value(model.x[0]),
                                   pyo.value(model.x[1])))
# x[0]: 1
# x[1]: 0
      

#%% Update data and re-solve
model.c.reconstruct({0:0,1:5})

res=solver.solve(model)
print('x[0]: {} \nx[1]: {}'.format(pyo.value(model.x[0]),
                                   pyo.value(model.x[1])))
# x[0]: 0
# x[1]: 1