python 如何有效地向Pyomo模型添加矩阵约束'Ax=B'?

2ic8powd  于 2023-01-08  发布在  Python
关注(0)|答案(1)|浏览(175)

我想用我的numpy数组Ab向Pyomo模型中添加约束Ax=b,但不幸的是,目前的性能非常差。

import time
    import numpy as np
    import pyomo.environ as pyo

    start = time.time()
    rows = 287
    cols = 2765
    A = np.random.rand(rows, cols)
    b = np.random.rand(rows)
    mdl = pyo.ConcreteModel()
    mdl.rows = range(rows)
    mdl.cols = range(cols)
    mdl.A = A
    mdl.b = b
    mdl.x_var = pyo.Var(mdl.cols, bounds=(0.0, None))

    mdl.constraints = pyo.ConstraintList()
    [mdl.constraints.add(sum(mdl.A[row, col] * mdl.x_var[col] for col in mdl.cols) <= mdl.b[row]) for row in mdl.rows]

    mdl.obj = pyo.Objective(expr=sum(mdl.x_var[col] for col in mdl.cols), sense=pyo.minimize)
    end = time.time()
    print(end - start)

由于add语句和大量的列,is几乎需要30秒,是否可以直接快速传递Axb,而不是逐行添加?

qnzebej0

qnzebej01#

上面减慢构建速度的主要原因是,您正在列表解析 * 内 * 构建约束列表元素,这是不必要的,并且会导致大量膨胀。
此行:

[mdl.constraints.add(sum(mdl.A[row, col] * mdl.x_var[col] for col in mdl.cols) <= mdl.b[row]) for row in mdl.rows]

构造每个ConstraintList.add()表达式捕获结果的 * 列表 *,这是一个"丰富"返回。该列表是您希望对add()函数执行的循环的不必要副产品。只需将生成方案更改为循环或生成器(通过使用括号)以避免捕获,如下所示:

(mdl.constraints.add(sum(mdl.A[row, col] * mdl.x_var[col] for col in mdl.cols) <= mdl.b[row]) for row in mdl.rows)

并且模型构建时间降至约0. 02秒。

相关问题