gpt4 book ai didi

pyomo 编写模型似乎很慢

转载 作者:行者123 更新时间:2023-12-03 19:34:30 27 4
gpt4 key购买 nike

我有一个相当大的模型(大约 500 万个变量和约束)。

构建时间是几分钟,求解时间也是几分钟(使用 gurobi)

但是写模型需要很长时间(大约2小时)

这是我使用 model.write('model.lp', io_options={'symbolic_solver_labels': True}) 的时候能够记录它

如果我使用 SolverFactory,时间差不多。和 solve直接来自pyomo的模型

这是一个小例子,我知道这个模型对于 gurobi 来说是微不足道的,所以我没有在这里比较求解时间和构建时间,但我不明白为什么这么长,我认为问题可能来自磁盘写入速度,但似乎磁盘从不重载,几乎不使用

import pyomo.environ as pyo
import time

size = 500000

model = pyo.ConcreteModel()
model.set = pyo.RangeSet(0, size)
model.x = pyo.Var(model.set, within=pyo.Reals)
model.constrList = pyo.ConstraintList()
for i in range(size):
model.constrList.add(expr = model.x[i] >= 1)
model.obj = pyo.Objective(expr=sum(model.x[i] for i in range(size)), sense=pyo.minimize)

opt = pyo.SolverFactory('gurobi')

_time = time.time()
res = opt.solve(model)
print(">>> total time () in {:.2f}s".format(time.time() - _time))

print(res)

结果是整个求解函数的时间为27秒,而gurobi的求解时间仅为4秒。

最佳答案

从我加速 pyomo 模型生成的轨迹来看,您需要首先对过程的哪个部分减慢它进行基准测试。 (这确实是性能调整的一般建议)

所以我把你的代码放到一个函数中:

def main():
size = 500000

model = pyo.ConcreteModel()
model.set = pyo.RangeSet(0, size)
model.x = pyo.Var(model.set, within=pyo.Reals)
model.constrList = pyo.ConstraintList()
for i in range(size):
model.constrList.add(expr = model.x[i] >= 1)
model.obj = pyo.Objective(expr=sum(model.x[i] for i in range(size)), sense=pyo.minimize)
return model

所以我可以通过 ipython 中的线路分析器运行:
In [1]: %load_ext line_profiler                                                                                                                                                                         

In [2]: import test_pyo

In [3]: %lprun -f test_pyo.main test_pyo.main()

这表明大部分时间都花在了 上model.constrList.add(expr = model.x[i] >= 1) .

通过将其移动到基于规则的约束中,我没有看到太大的改进,所以我决定尝试手动构建表达式,就像在 PyPSA code 中一样.

import pyomo.environ as pyo
import time
from pyomo.core.expr.numeric_expr import LinearExpression
from pyomo.core.base.constraint import _GeneralConstraintData
from pyomo.core.base.numvalue import NumericConstant

def main():
size = 500000

model = pyo.ConcreteModel()
model.set = pyo.RangeSet(0, size)
model.x = pyo.Var(model.set, within=pyo.Reals)
setattr(model, "constraint", pyo.Constraint(model.set, noruleinit=True))
v = getattr(model, "constraint")
for i in v._index:
v._data[i] = _GeneralConstraintData(None, v)
expr = LinearExpression()
expr.linear_vars = [model.x[i]]
expr.linear_coefs = [1]
expr.constant = 0
v._data[i]._body = expr
v._data[i]._equality = False
v._data[i]._lower = NumericConstant(1)
v._data[i]._upper = None

model.obj = pyo.Objective(expr=pyo.quicksum(model.x[i] for i in range(size)), sense=pyo.minimize)
return model

这似乎带来了大约 50% 的性能提升。线分析器显示,现在花费大量时间在创建集合、空的 LinearExpression 对象以及创建目标上。摆弄目标可能会改善一些事情。

关于pyomo 编写模型似乎很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51269351/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com