2017-10-06 138 views
0

目前,我正在研究我的毕业设计,但我的代码有一些麻烦。有没有人可以帮助我解决我的错误。我正试图优化用水产生的利润。TyperError:'函数'对象没有属性'_getitem_'

我得到的错误是下面的一个(出现在如果行的约束):

TypeError: 'function' object has no attribute '__getitem__' 

我的代码:

#constants 
Ymax=8    #tonne/ha 
ky=1.25 
Numbas=3   #3 subbasins 
Nummon=12   #12 months is a year. 
c_hydro=0.9   #Conversion rate m3 to kWh 
LBPmaize=316413  #LBP/tonne 
LBPhydro=55   #LBP/kWh 
alpha=0.7 
p1=0.35    #soil moisture depletion factor for no stress 

#parameters 
S0=[207.112, 150, 161.398] 
A=[74571.9, 1537.8, 6645.7]   #total area per subbasin 
a=[0.423, 0.959, 0.473]    #part of area used for irrigation 
R=[0.2, 0.3, 0.5] 

Qhydromatrix=[0,0,0,0,0,0,0,0,0,0,0,0, 
      0,0,0,0,0,0,0,0,0,0,0,0, 
      1,1,1,1,1,0,0,0,0,1,1,1] 

#Definitions 
def profit(x,sign=-1): 
    x=[]*(Numbas*Nummon) 
    return sign * (alpha*Yasum*LBPmaize) 

def ETa(x): 
    for i in range(0,(Nummon*Numbas)): 
     ETa=[]*(Numbas*Nummon) 
     if np.multiply(x,p1)>ETmax_maize: 
      ETa[i]=ETmax_maize[i] 
     else: 
      ETa[i]=np.multiply(x[i],p1) 
    return ETa 

def Yasum(ETa): 
    Yasum=0 
    for j in range(0,Numbas): 
     for i in range(0,Nummon): 
      ETasum=sum(ETa[j*Nummon:(j+1)*Nummon]) 
      ETmaxsum=sum(ETmax_maize[j*Nummon:(j+1)*Nummon]) 
      Ya=((-1*Ymax*ky)*(1-(ETasum/ETmaxsum))+Ymax)*A[j]*a[j] 
     Yasum=Yasum+Ya 
    return Yasum 

def constraint(x): 
    for j in range(0,Numbas): 
     for i in range(0,Nummon): 
      if (i-(j*Nummon))==0: 
       x[i+(j*Nummon)]-((1-R[j])*S0[j])+ETa[i+(j*Nummon)+11]-P[i+(j*Nummon)+11]-Rdown[i+(j*Nummon)] 
      else: 
       ETa[i+(j*Nummon)-1]-((1-R[j])*x[i+(j*Nummon)-1])+x[i+(j*Nummon)]-P[i+(j*Nummon)-1]-Rdown[i+(j*Nummon)] 
    return x 
con2=({'type':'ineq','fun':constraint}) 

x0=[100]*(Nummon*Numbas) 

sol=minimize(profit, x0,method='SLSQP', constraints=con2)   
+0

请注意'[] * n == []'。 – Elazar

+0

''__getitem__'由'[[]]'产生,就像索引列表,字典或数组时一样。这个错误意味着一个函数正在用'fn [']'而不是'fn(...)'来调用。 – hpaulj

回答

0

在一般情况下,这种错误意味着你有一个表达式f[x]其中f是一个函数。

你在你的代码中的几个问题,但错误来源于此行:

ETa[i+(j*Nummon)-1]-((1-R[j])*x[i+(j*Nummon)-1])+x[i+(j*Nummon)]-P[i+(j*Nummon)-1]-Rdown[i+(j*Nummon)] 
    #^this is a function 

你定义了一个名为ETa功能。您还可以使用名为ETa的局部变量。一般来说,这不是一个好主意。在最后一个函数中,这个名称中没有局部变量,因此名称在全局范围内查找 - 这是一个函数;函数不能以这种方式访问​​。

与您的代码的其他问题:

  • 在功能利润要指定的参数,而不是使用它:x=[]*(Numbas*Nummon)。这种改变是局部的,对传递给函数的参数没有影响。
  • 您在两个地方使用表格[] * some_number。这是没有意义的 - 重复空列表返回空列表。
  • 在函数constraint中,您将返回x,但不会以任何方式更改它。你打算从profit内改变它吗?因为你不能。
  • 在同一个函数中,ifelse分支继续评估表达式,但没有任何影响。

请注意,这些问题与您的代码的逻辑无关。

重要的作风问题:

  • 请使用snake_case变量名。这不会影响代码的行为,但可以帮助其他人阅读它,因此它会帮助您获得反馈。类似地,在运算符周围放置空格,例如=,+等。
  • 如果表达式变得太长,则使用局部变量将其分解为几个语句。
  • 如果表达式自身重复(例如上面的j * Nummon),请将其值放入一个变量中。
相关问题