ここでこれを行う方法の1つです。
import sympy as sp
(ベクトル)変数およびパラメータを定義します。
# vector size (integer, user input):
n = 2
# vector variables:
x = sp.var('x0:'+str(n), positive = True)
y = sp.var('y0:'+str(n), positive = True)
# vector parameters:
p = sp.var('p0:'+str(n), positive = True)
q = sp.var('q0:'+str(n), positive = True)
# scalar parameters
b = sp.var('b', real = True)
c = sp.var('c', real = True)
# Lagrange multiplier for sum constraint:
l = sp.var('lambda')
目的関数:
U = reduce(lambda xi, xj: xi * xj, [(xi/pi)**b * (yi/qi)**c for xi,pi,yi,qi in zip(x,p,y,q)],1)
U
(X0/P0)**のb *(×1/P1)** b *(y0/q0)** c *(y1/q1)** c
ラグランジャン:
L = U + l * (sum(x+y)-1)
KKT条件(各リスト要素がゼロに等しくなければならない):
KKT = sp.simplify([sp.numer(sp.together(sp.diff(L, xi))) for xi in x]+\
[sp.numer(sp.together(sp.diff(L, xi))) for yi in y] + [sp.diff(L, l)])
Iソルバを助けるために誘導体のみ分子考えました。これは、このアプローチに基づくいくつかの解は、対応するゼロ分母のために無効である可能性があることを意味する(手動でチェックする必要がある)。
溶液は、パラメータb
とc
の一般的な値については、Sympyは溶液を与えることができないと思わ
sp.solve(KKT,sp.flatten([x,y,l]))
として今得ることができます。しかし、これらのパラメータの特定の選択肢について解決策を得ることができる。たとえば、b=2
とc=2
ために、与えられた溶液を
[{lambda: y0**2*y1**2*(y0 + y1 - 1)**3/(4*p0**2*p1**2*q0**2*q1**2),
x0: -y0/2 - y1/2 + 1/2,
x1: -y0/2 - y1/2 + 1/2}]
SymPy行列を含んでいます。私はベクトルを表すために列行列を使うことに頼ってきました。しかし、MatrixやMatrixSymbolオブジェクトを使ってこの解答を書き直すには、議論された最適化問題や、十分な高度なSymPyユーザーに精通していません。 – chrstphrchvz