提问者:小点点

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


我有一个需要多次求解的模型,目标函数系数不同。当然,我希望在更新模型上花费尽可能少的时间。我当前的设置如下(简化):

抽象模型:

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,对于较大的情况,需要几秒钟。有没有更新目标函数更快的方法?(毕竟,在保存LP模型的通常方式中,目标函数系数位于一个单独的向量中,所以改变它们不应该影响其他任何东西。)


共1个答案

匿名用户

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

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