我有一个需要多次求解的模型,目标函数系数不同。当然,我希望在更新模型上花费尽可能少的时间。我当前的设置如下(简化):
抽象模型:
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模型的通常方式中,目标函数系数位于一个单独的向量中,所以改变它们不应该影响其他任何东西。)
在创建具体模型之前,您是否有理由定义抽象模型?如果您使用上面显示的规则定义具体模型,您应该能够只更新数据并重新求解模型,而不会产生大量开销,因为您不会重新定义目标对象。下面是一个简单的例子,我更改了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