2017-01-24 96 views
1

修改我的代码,包括所有的参数和所涉及的变量:Pyomo总和由矢量

(d是Python的进口numpy的矩阵)

import pyomo 
from pyomo.environ import * 
from array import * 


import numpy as np 
import scipy as sp 
from diff_matrix import D ##N=10???? 
print(D) 


m =ConcreteModel() 
... 
m.n = Param(initialize = 10, within = Integers)    
m.Ns = Set(initialize = range(0,value(m.n))) 
m.x1 = Var(m.N, domain = Reals) 
m.D = Param(m.N, m.N, initialize=D) 

m.f_x1 = Var(m.N) 
def f_x1_definition(model,i): 
     return m.f_x1[i] == sum(m.x1[j]*m.D[i,j] for j in range(value(m.n))) 
m.f_x1_const = Constraint(m.Ns, rule = f_x1_definition) 

,但我得到下一个错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

任何帮助吗?

回答

0

最简单的事情是只使用Python sum()功能,而不是Pyomo summation()功能:

def f_x1_definition(model,i): 
    return model.f_x1[i] == sum(model.x1[j]*model.D[i,j] for j in range(value(model.n))) 

另外请注意,我颠倒的顺序Pyomo Varm.x1)和基质(m.D) 。根据你的其他问题(Importing a matrix from Python to Pyomo),我假设矩阵是一个NumPy矩阵。当乘以NumPy值和Pyomo组件(VarParam)时,请始终将Pyomo对象放在第一位。这是由于在当前版本的Pyomo中,NumPy运算符重载和Pyomo运算符重载(至少5.1)之间的冲突。


编辑1:注意逆转操作数的顺序:在你原来的问题,但并不清楚m.D被定义为一个Pyomo Param。 Pyomo对象在表达式中的顺序没有关系。当NumPy对象乘以Pyomo组件时,上述运算符超载问题仅为。此外,此时(通过Pyomo 5.1),Pyomo不支持矩阵代数 - 也就是矩阵矩阵或矩阵向量乘积。由于每个表达式都是标量表达式,因此交换操作中的项的排序(+,*)不会更改表达式的含义。

编辑2:您的错误与您最初发布的sum/summation无关。问题在于你如何初始化你的参数。在这个时候(通过Pyomo 5.1),你不能直接从numpy.ndarray初始化一个参数。您需要先将NumPy对象转换为Python字典,如下所示:

m.D = Param(m.N, m.N, initialize=dict(((i,j),D[i,j]) for i in m.N for j in m.N)) 
+0

非常感谢!我改变了它,但我仍然有一个错误... ValueError:具有多个元素的数组的真值是不明确的。使用a.any()或a.all()任何想法? :) – Michael

+0

在我们诊断您的问题之前,您需要提供更多的模型。具体来说,你如何定义'm.f_x1','m.x1'和'm.D'。还要注意:如果你使用'model'作为规则(函数)的第一个参数,那么你需要在函数内部使用'model'。 – jsiirola