Pyomo在创建约束时调用函数。

huangapple go评论62阅读模式
英文:

Pyomo calling functions when creating constraints

问题

I'm trying to use a loop that creates constraints, where within each constraint, 2 functions are called that perform simple operations on some pyomo variables at a particular index, and then return a vector. An example code is as follows:

import pyomo.environ as pyo

def f(x, y):
    x0 = 2.0*x[1]
    x1 = 0.5*y
    return x0, x1

def g(x):
    x0 = x[0] - 5.0
    x1 = x[1] + 10.0
    return x0, x1

model = pyo.ConcreteModel()

N = 100
num_rows = range(2)
num_cols = range(N)

# Creating decision variables
model.x = pyo.Var(num_rows, num_cols, domain=pyo.Reals)
model.y = pyo.Var(num_cols, domain=pyo.Reals)

# Creating constraints in a loop
model.constraints = pyo.ConstraintList()
for k in range(N-1):
    model.constraints.add(expr=model.x[:,k+1] == model.x[:,k] + 0.5*f(model.x[:,k+1], model.y[k+1]) + 2.0*g(model.x[:,k]))

In the above example, the pyomo variables x and y at index k+1 are passed into the function f. This function then assigns x[0,k+1] = 2.0*x[1,k+1], and x[1,k+1] = 0.5*y[k+1]. The vector x[:,k+1] of dimension 2x1 is then returned by f.

Similarly, for the function g, the pyomo variable x at index k is passed into it, where we then assign x[0,k] = x[0,k] - 5.0 and x[1,k] = x[1,k] + 10.0. The vector x[:,k] of dimension 2x1 is then returned by g.

Currently the above code does not work, as I get the following error:

x0 = 2.0*x[1]
TypeError: unsupported operand type(s) for *: 'float' and 'IndexedComponent_slice'

Any help on how to use Python functions that manipulate and return pyomo variables would be appreciated. Thanks very much.

英文:

I'm trying to use a loop that creates constraints, where within each constraint, 2 functions are called that perform simple operations on some pyomo variables at a particular index, and then return a vector. An example code is as follows:

import pyomo.environ as pyo

def f(x, y):
    x0 = 2.0*x[1]
    x1 = 0.5*y
    return x0, x1

def g(x):
    x0 = x[0] - 5.0
    x1 = x[1] + 10.0
    return x0, x1

model = pyo.ConcreteModel()

N = 100
num_rows = range(2)
num_cols = range(N)

# Creating decision variables
model.x = pyo.Var(num_rows, num_cols, domain=pyo.Reals)
model.y = pyo.Var(num_cols, domain=pyo.Reals)

# Creating constraints in a loop
model.constraints = pyo.ConstraintList()
for k in range(N-1):
    model.constraints.add(expr=model.x[:,k+1] == model.x[:,k] + 0.5*f(model.x[:,k+1], model.y[k+1]) + 2.0*g(model.x[:,k]))

In the above example, the pyomo variables x and y at index k+1 are passed into the function f. This function then assigns x[0,k+1] = 2.0*x[1,k+1], and x[1,k+1] = 0.5*y[k+1]. The vector x[:,k+1] of dimension 2x1 is then returned by f.

Similarly, for the function g, the pyomo variable x at index k is passed into it, where we then assign x[0,k] = x[0,k] - 5.0 and x[1,k] = x[1,k] + 10.0. The vector x[:,k] of dimension 2x1 is then returned by g.

Currently the above code does not work, as I get the following error:

    x0 = 2.0*x[1]
TypeError: unsupported operand type(s) for *: 'float' and 'IndexedComponent_slice'

Any help on how to use Python functions that manipulate and return pyomo variables would be appreciated. Thanks very much.

答案1

得分: 1

当创建约束时,我不认为你可以像你尝试做的那样使用切片或“矢量化”。但在创建约束之前,你的构造会崩溃...

我也不认为在函数中尝试索引变量的切片是可能的... 你在这里的思维有点“太numpy”了。

在模型构建期间,坚持使用简单的表达式来定义约束。所以,在循环内将这个拆分成两个等式约束,你可能可以避免在过程中使用辅助函数的复杂性...

# 在循环中创建约束
model.constraints = pyo.ConstraintList()
for k in range(N-1):
    model.constraints.add(expr=model.x[0, k+1] == ...
    model.constraints.add(expr=model.x[1, k+1] == ...
英文:

When making constraints, I don't believe you can use slices or "vectorize" like you are trying to do. But your construct is crashing before the constraint is made...

I also don't think it is possible to index into a slice of a variable like you are trying to do in your functions... You are thinking "too numpy" here.

Stick with simple expressions for constraints during model construction. So, just break this out into two equality constraints within the loop, and you can probably avoid the complication of the helper function along the way...

# Creating constraints in a loop
model.constraints = pyo.ConstraintList()
for k in range(N-1):
    model.constraints.add(expr=model.x[0, k+1] == ...
    model.constraints.add(expr=model.x[1, k+1] == ...

huangapple
  • 本文由 发表于 2023年4月19日 16:48:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052497.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定