使用SymPy解决符号数量有限的约束优化问题

时间:2019-10-27 06:19:00

标签: python python-3.x sympy mathematical-optimization symbolic-math

我正在尝试使用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的新手,请多多包涵。)

1 个答案:

答案 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做些事情。