2017-10-06 87 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),請將其值放入一個變量中。