2016-09-18 116 views
1

我正在用SciPy練習,並且在嘗試使用fmin_slsqp時遇到錯誤。我設定了一個問題,我想最大化一個目標函數U,給定一組約束。python fmin_slsqp - 帶約束的錯誤

我有兩個控制變量x [0,t]和x [1,t],正如你所看到的,它們是由t(時間段)索引的。目標函數爲:

def obj_fct(x, alpha,beta,Al): 
U = 0 
x[1,0] = x0 
for t in trange: 
    U = U - beta**t * ((Al[t]*L)**(1-alpha) * x[1,t]**alpha - x[0,t]) 
return U 

的約束在這兩個變量定義的,其中一個從一個週期(T)鏈路的變量到另一個(T-1)。

def constr(x,alpha,beta,Al): 
return np.array([ 
    x[0,t], 
    x[1,0] - x0, 
    x[1,t] - x[0,t] - (1-delta)*x[1,t-1] 
    ]) 

最後,這裏採用的是fmin_slsqp的:

sol = fmin_slsqp(obj_fct, x_init, f_eqcons=constr, args=(alpha,beta,Al)) 

撇開事實,有更好的方法來解決這樣的動力問題,我的問題是關於語法。當運行這個簡單的代碼時,出現以下錯誤:

Traceback (most recent call last): 
    File "xxx", line 34, in <module> 
    sol = fmin_slsqp(obj_fct, x_init, f_eqcons=constr, args=(alpha,beta,Al)) 
    File "D:\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py", line 207, in fmin_slsqp 
    constraints=cons, **opts) 
    File "D:\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py", line 311, in _minimize_slsqp 
    meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['eq']])) 
    File "D:\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py", line 311, in <listcomp> 
    meq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['eq']])) 
    File "xxx", line 30, in constr 
    x[0,t], 
IndexError: too many indices for array 
[Finished in 0.3s with exit code 1] 

我在做什麼錯?

碼的初始部分,所述參數分配值,是:

from scipy.optimize import fmin_slsqp 
import numpy as np 

T = 30 
beta = 0.96 
L = 1 
x0 = 1 
gl = 0.02 
alpha = 0.3 
delta = 0.05 
x_init = np.array([1,0.1]) 

A_l0 = 1000 
Al = np.zeros((T+1,1)) 
Al[1] = A_l0 

trange = np.arange(1,T+1,1, dtype='Int8') # does not include period zero 
for t in trange: Al[t] = A_l0*(1 + gl)**(t-1) 
+0

x_init被錯誤地指定。它應該是: x_init = np.ones((2,T + 1)) x_init [:,0] = [1,0.1] –

回答

0

x傳遞到您的目標和約束函數陣列將是一個一維陣列(就像你x_init是)。您無法爲具有兩個索引的一維數組編制索引,因此諸如x[1,0]x[0,t]等表達式將生成錯誤。

+0

好的。我實際上錯誤地定義了x_init,現在是: x_init = np.ones((2,T + 1)) x_init [:,0] = [1,0.1] 錯誤依然存在。那麼只有一維數組可以傳遞給函數? –

+0

是的,你必須改變'x'的定義。而不是一個形狀爲「(2,T + 1)」的二維數組,使其成爲長度爲2 *(T + 1)的一維數組。 –

+0

謝謝,這有幫助 –