检查 pyomo 模型和生成的 LP 文件格式是否有效并捕获 error/exception

Check if pyomo model and generated LP file format is valid and catch error/exception

我有一个 pyomo ConcreteModel(),我在另一个随机优化过程中反复求解,而模型上的一个或多个参数发生了变化。

基本流程可以描述如下:

# model is created as a pyomo.ConcreteModel()
for i in range(0, 10):    
    # change some parameter on the model
    opt = SolverFactory('gurobi', solver_io='lp')
    # how can I check here if the changed model/lp-file is valid?
    results = opt.solve(model)

现在我在模型和 LP file (see gist) 似乎包含 NaN 值的某些情况下收到错误消息:

ERROR: Solver (gurobi) returned non-zero return code (1)
ERROR: Solver log: Academic license - for non-commercial use only Error
    reading LP format file /tmp/tmp8agg07az.pyomo.lp at line 1453 Unrecognized
    constraint RHS or sense Neighboring tokens: " <= nan c_u_x1371_: +1 x434
    <= nan "

    Unable to read file Traceback (most recent call last):
      File "<stdin>", line 5, in <module> File
      "/home/cord/.anaconda3/lib/python3.6/site-
      packages/pyomo/solvers/plugins/solvers/GUROBI_RUN.py", line 61, in
      gurobi_run
        model = read(model_file)
      File "gurobi.pxi", line 2652, in gurobipy.read
      (../../src/python/gurobipy.c:127968) File "gurobi.pxi", line 72, in
      gurobipy.gurobi.read (../../src/python/gurobipy.c:125753)
    gurobipy.GurobiError: Unable to read model Freed default Gurobi
    environment

当然,第一个想法是防止设置这些 NaN 值。但我不知道它们为什么会发生,并且想弄清楚模型何时因 NaN 导致的错误结构而崩溃。

我知道我可以从 SolverFactory() 对象中捕获求解器状态和终止条件。但是由于无效的更改值,错误显然发生在求解过程之前的某个地方。

我怎样才能在求解 i 之前为不同的求解器捕获这些类型的错误。 e.在应用求解器之前检查 model/lp-file 是否有效?有什么方法吗? check_model() 如果模型(无效)有效或类似的东西,它会提供 TrueFalse

提前致谢!

如果您知道错误是在更改参数值时发生的,那么您可以测试一下所有相关参数值的总和是否为有效数字。毕竟NaN + 3 = NaN.

既然您得到了 NaN,我猜您是使用 Pandas 从 Excel 电子表格中导入参数值?有一种方法可以将所有 NaN 转换为默认数字。

参数检查代码示例:

>>> from pyomo.environ import *
>>> m = ConcreteModel()
>>> m.p1 = Param(initialize=1)
>>> m.p2 = Param(initialize=2)
>>> for p in m.component_data_objects(ctype=Param):
...     print(p.name)
... 
p1
p2
>>> import numpy
>>> m.p3 = Param(initialize=numpy.nan)
>>> import math
>>> math.isnan(value(sum(m.component_data_objects(ctype=Param))))
True

索引、可变参数:

>>> from pyomo.environ import *
>>> m = ConcreteModel()
>>> m.i = RangeSet(2)
>>> m.p = Param(m.i, initialize={1: 1, 2:2}, mutable=True)
>>> import math
>>> import numpy
>>> math.isnan(value(sum(m.component_data_objects(ctype=Param))))
False
>>> m.p[1] = numpy.nan
>>> math.isnan(value(sum(m.component_data_objects(ctype=Param))))
True