pyomo 写模型似乎很慢
Posted
技术标签:
【中文标题】pyomo 写模型似乎很慢【英文标题】:pyomo seems very slow to write models 【发布时间】:2018-12-18 13:01:38 【问题描述】:我有一个相当大的模型(大约 500 万个变量和约束)。
构建时间是几分钟,求解时间也是几分钟(使用 gurobi)
但是写模型需要很长时间(大约2小时)
如果我使用model.write('model.lp', io_options='symbolic_solver_labels': True)
可以记录它,这是时候
如果我直接使用pyomo的模型SolverFactory
和solve
,时间差不多
这里有一个小样本,我知道这个模型对于 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 :.2fs".format(time.time() - _time))
print(res)
结果是整个求解函数的时间为27 s,而gurobi的求解时间仅为4 s。
【问题讨论】:
【参考方案1】:检查您是否安装了最新版本的 pyomo 也是值得的。我最近从 v 5.5.0 更新到 5.6.8,发现构建 + 解决时间从 5 秒减少到 1 秒(对于一个明显比你的问题小得多的问题!)。
【讨论】:
【参考方案2】:从我加快 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 中的 line profiler 运行:
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 对象以及创建目标。调整目标可能会使事情变得更好。
【讨论】:
事实证明,如果您还手动为目标创建 LinearExpression,您可以获得另一个小的改进【参考方案3】:我认为你的隐含问题是“我怎样才能让它更快?”
如果写入时间有问题,您可以查看 Gurobi SolverFactory('gurobi', io_format='python')
的直接 python 接口。将symbolic_solver_labels
标志设置为True
几乎总是会增加模型的写入时间,因为组件名称查找可能很昂贵。
【讨论】:
感谢您的回答,io_format='python' 似乎对速度影响不大,对于符号标签,我通常只为调试编写模型,所以我需要标签 啊,所以您的首要任务是能够写出整个模型以进行调试?或者您只是想检查模型的某个部分? 编写模型时我并不关心速度,因为我只是在调试时使用它。直接从 pyomo 解决时,我的问题更多,我期望模型的构建时间在求解时间旁边可以忽略不计,但反过来,这就是我不明白的地方以上是关于pyomo 写模型似乎很慢的主要内容,如果未能解决你的问题,请参考以下文章
win10电脑打开此电脑资源管理器任务管理器软件等突然很慢很慢,cup内存磁盘利用率却很低
SAP migo这个事物代码在做操作的时候,多人操作同一个事务代码时很慢很慢,是啥原因?