简体   繁体   English

如何有效地将矩阵约束“Ax=b”添加到 Pyomo model?

[英]How do I add a matrix constraint `Ax=b` to a Pyomo model efficiently?

I want to add the constraints Ax=b to a Pyomo model with my numpy arrays A and b as efficient as possible.我想将约束Ax=b添加到 Pyomo model 和我的numpy arrays Ab尽可能高效。 Unfortunately, the performance is very bad currently.不幸的是,目前的表现非常糟糕。 For the following example对于下面的例子

    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)
   

is takes almost 30 seconds because of the add statement and the huge amount of columns.由于 add 语句和大量的列,这需要将近 30 秒。 Is it possible to pass A , x , and b directly and fast instead of adding it row by row?是否可以直接快速地传递Axb而不是逐行添加?

The main thing that is slowing down your construction above is the fact that you are building the constraint list elements within a list comprehension, which is unnecessary and causes a lot of bloat.上面的构建速度变慢的主要原因是您列表推导中构建约束列表元素,这是不必要的并且会导致大量膨胀。

This line:这一行:

[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]

Constructs a list of the captured results of each ConstraintList.add() expression, which is a "rich" return.构造每个ConstraintList.add()表达式的捕获结果列表,这是一个“丰富”的返回。 That list is an unnecessary byproduct of the loop you desire to do over the add() function. Just change your generation scheme to either a loop or a generator (by using parens) to avoid that capture, as such:该列表是您希望通过add() function 执行的循环的不必要的副产品。只需将您的生成方案更改为循环或生成器(通过使用括号)以避免捕获,如下所示:

(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)

And the model construction time drops to about 0.02 seconds.而 model 的构建时间下降到大约 0.02 秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM