我正在尝试使用SymPy解决约束最小化问题。对于固定数量的变量,例如w1, w2
,我可以通过以下方式进行操作:
from sympy import *
w1, w2 = var('w1, w2', real = True)
n1, n2 = symbols('n1, n2', integer = True)
p1, p2 = symbols('p1, p2', real = True)
f = w1**2 / (n1 * p1) + w2**2 / (n2 * p2)
g = w1 + w2 - 1
lam = symbols('lambda', real = True)
L = f - lam * g
gradL = [diff(L, c) for c in [w1, w2]]
KKT_eqs = gradL + [g]
stationary_points = solve(KKT_eqs, [w1, w2, lam], dict = True)
我们是否能够解决k
个变量数目的变量的问题?我尝试了以下方法:
from sympy import *
i = symbols('i', cls = Idx)
k = symbols('k', integer = True)
w = IndexedBase('w', real = True)
n = IndexedBase('n', integer = True)
p = IndexedBase('p', real = True)
f = summation(w[i]**2 / (n[i] * p[i]), (i, 1, k))
g = summation(w[i], (i, 1, k)) - 1
lam = symbols('lambda', real = True)
L = f - lam * g
但是,我无法弄清楚如何采用其余的代码。
(我是python的新手,请多多包涵。)
答案 0 :(得分:0)
您可以做的一件事是在具体案例中寻找一种模式:
>>> from sympy import *
... from sympy.abc import i
... w = IndexedBase('w')
... np = IndexedBase('np')
... lam = symbols('lambda', real = True)
... def go(n):
... ww = [w[i] for i in range(n)]
... f = Add(*[wi**2/np[i] for i,wi in enumerate(ww)])
... g = Add(*ww) - 1
... L = f - lam * g
... gradL = [diff(L, c) for c in ww]
... KKT_eqs = gradL + [g]
... return solve(KKT_eqs, ww + [lam], dict = True)
>>> go(2)
[{lambda: 2/(np[0] + np[1]), w[0]: np[0]/(np[0] + np[1]), w[1]: np[1]/(np[0] + np[1])}]
>>> go(3)
[{lambda: 2/(np[0] + np[1] + np[2]), w[0]: np[0]/(np[0] + np[1] + np[2]), w[1]: np[1]/(np[0] + np[1] + np[2]), w[2]: np[2]/(np[0] + np[1] + np[2])}]
注意:由于n[i]*p[i]
总是一起出现,因此这两个变量已合并为一个。您看到解决方案的模式了吗?如果不尝试,请尝试go(4)
。
要在没有具体见识的情况下进行概括,您也许可以使用MatrixExpr
做些事情。