akh*_*hil 17 python mathematical-optimization cvxpy
在python中推荐的约束非线性优化包是什么?
我试图解决的具体问题是:
我有一个未知的X(Nx1),我有M(Nx1)u向量和M(NxN)s矩阵.
max [5th percentile of (ui_T*X), i in 1 to M]
st
0<=X<=1 and
[95th percentile of (X_T*si*X), i in 1 to M]<= constant
Run Code Online (Sandbox Code Playgroud)
当我开始解决这个问题时,我只有一点估计值u,s并且我能够解决上面的问题cvxpy.
我意识到,而不是一个估计u和s,我有整个值的分布,所以我想改变我的目标函数,以便我可以使用整个分布.上面的问题描述是我尝试以有意义的方式包含该信息.
cvxpy不能用来解决这个问题,我试过了scipy.optimize.anneal,但我似乎无法对未知值设置界限.我也看过了,pulp但它不允许非线性约束.
Sla*_*off 13
scipy 有一个壮观的包约束非线性优化.
您可以通过阅读optimize 文档开始,但这是SLSQP的一个示例:
minimize(func, [-1.0,1.0], args=(-1.0,), jac=func_deriv, constraints=cons, method='SLSQP', options={'disp': True})
Run Code Online (Sandbox Code Playgroud)
Mik*_*rns 13
虽然SLSQP算法scipy.optimize.minimize很好,但它有一些限制.第一个是它是一个QP求解器,所以它适用于适合二次规划范式的方程.但是如果你有功能限制会发生什么?此外,scipy.optimize.minimize不是全局优化器,因此您经常需要非常接近最终结果.
有一个受约束的非线性优化包(称为mystic)已经存在了几乎与scipy.optimize自身一样长- 我建议它作为处理任何一般约束非线性优化的首选.
例如,如果我理解您的伪代码,您的问题看起来像这样:
import numpy as np
M = 10
N = 3
Q = 10
C = 10
# let's be lazy, and generate s and u randomly...
s = np.random.randint(-Q,Q, size=(M,N,N))
u = np.random.randint(-Q,Q, size=(M,N))
def percentile(p, x):
x = np.sort(x)
p = 0.01 * p * len(x)
if int(p) != p:
return x[int(np.floor(p))]
p = int(p)
return x[p:p+2].mean()
def objective(x, p=5): # inverted objective, to find the max
return -1*percentile(p, [np.dot(np.atleast_2d(u[i]), x)[0] for i in range(0,M-1)])
def constraint(x, p=95, v=C): # 95%(xTsx) - v <= 0
x = np.atleast_2d(x)
return percentile(p, [np.dot(np.dot(x,s[i]),x.T)[0,0] for i in range(0,M-1)]) - v
bounds = [(0,1) for i in range(0,N)]
Run Code Online (Sandbox Code Playgroud)
因此,要处理您的问题mystic,您只需要指定边界和约束.
from mystic.penalty import quadratic_inequality
@quadratic_inequality(constraint, k=1e4)
def penalty(x):
return 0.0
from mystic.solvers import diffev2
from mystic.monitors import VerboseMonitor
mon = VerboseMonitor(10)
result = diffev2(objective, x0=bounds, penalty=penalty, npop=10, gtol=200, \
disp=False, full_output=True, itermon=mon, maxiter=M*N*100)
print result[0]
print result[1]
Run Code Online (Sandbox Code Playgroud)
结果看起来像这样:
Generation 0 has Chi-Squared: -0.434718
Generation 10 has Chi-Squared: -1.733787
Generation 20 has Chi-Squared: -1.859787
Generation 30 has Chi-Squared: -1.860533
Generation 40 has Chi-Squared: -1.860533
Generation 50 has Chi-Squared: -1.860533
Generation 60 has Chi-Squared: -1.860533
Generation 70 has Chi-Squared: -1.860533
Generation 80 has Chi-Squared: -1.860533
Generation 90 has Chi-Squared: -1.860533
Generation 100 has Chi-Squared: -1.860533
Generation 110 has Chi-Squared: -1.860533
Generation 120 has Chi-Squared: -1.860533
Generation 130 has Chi-Squared: -1.860533
Generation 140 has Chi-Squared: -1.860533
Generation 150 has Chi-Squared: -1.860533
Generation 160 has Chi-Squared: -1.860533
Generation 170 has Chi-Squared: -1.860533
Generation 180 has Chi-Squared: -1.860533
Generation 190 has Chi-Squared: -1.860533
Generation 200 has Chi-Squared: -1.860533
Generation 210 has Chi-Squared: -1.860533
STOP("ChangeOverGeneration with {'tolerance': 0.005, 'generations': 200}")
[-0.17207128 0.73183465 -0.28218955]
-1.86053344078
Run Code Online (Sandbox Code Playgroud)
mystic非常灵活,可以处理任何类型的约束(例如,等式,不等式),包括符号和功能约束.我将约束指定为上面的"惩罚",这是传统方式,因为它们在违反约束时对目标应用惩罚.
mystic还提供非线性内核转换,通过减少有效解的空间(即通过空间映射或内核转换)来约束解空间.
作为一个例子,这里mystic解决了一个打破很多QP求解器的问题,因为约束不是约束矩阵的形式.它正在优化压力容器的设计.
"Pressure Vessel Design"
def objective(x):
x0,x1,x2,x3 = x
return 0.6224*x0*x2*x3 + 1.7781*x1*x2**2 + 3.1661*x0**2*x3 + 19.84*x0**2*x2
bounds = [(0,1e6)]*4
# with penalty='penalty' applied, solution is:
xs = [0.72759093, 0.35964857, 37.69901188, 240.0]
ys = 5804.3762083
from mystic.symbolic import generate_constraint, generate_solvers, simplify
from mystic.symbolic import generate_penalty, generate_conditions
equations = """
-x0 + 0.0193*x2 <= 0.0
-x1 + 0.00954*x2 <= 0.0
-pi*x2**2*x3 - (4/3.)*pi*x2**3 + 1296000.0 <= 0.0
x3 - 240.0 <= 0.0
"""
cf = generate_constraint(generate_solvers(simplify(equations)))
pf = generate_penalty(generate_conditions(equations), k=1e12)
if __name__ == '__main__':
from mystic.solvers import diffev2
from mystic.math import almostEqual
from mystic.monitors import VerboseMonitor
mon = VerboseMonitor(10)
result = diffev2(objective, x0=bounds, bounds=bounds, constraints=cf, penalty=pf, \
npop=40, gtol=50, disp=False, full_output=True, itermon=mon)
assert almostEqual(result[0], xs, rel=1e-2)
assert almostEqual(result[1], ys, rel=1e-2)
Run Code Online (Sandbox Code Playgroud)
在这里找到这个以及大约100个这样的例子:https://github.com/uqfoundation/mystic.
我是作者,所以我有点偏颇.但是,偏见很小.mystic既成熟又受到良好支持,并且在解决硬约束非线性优化问题方面具有无与伦比的能力.
Joh*_*ren 10
正如其他人所评论的,SciPy 最小化包是一个很好的起点。我们还在Python Gekko 论文中回顾了许多其他优化包(参见第 4 节)。我在下面包含了一个示例(Hock Schittkowski #71 benchmark),其中包含Scipy.optimize.minimize.
import numpy as np
from scipy.optimize import minimize
def objective(x):
return x[0]*x[3]*(x[0]+x[1]+x[2])+x[2]
def constraint1(x):
return x[0]*x[1]*x[2]*x[3]-25.0
def constraint2(x):
sum_eq = 40.0
for i in range(4):
sum_eq = sum_eq - x[i]**2
return sum_eq
# initial guesses
n = 4
x0 = np.zeros(n)
x0[0] = 1.0
x0[1] = 5.0
x0[2] = 5.0
x0[3] = 1.0
# show initial objective
print('Initial SSE Objective: ' + str(objective(x0)))
# optimize
b = (1.0,5.0)
bnds = (b, b, b, b)
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'eq', 'fun': constraint2}
cons = ([con1,con2])
solution = minimize(objective,x0,method='SLSQP',\
bounds=bnds,constraints=cons)
x = solution.x
# show final objective
print('Final SSE Objective: ' + str(objective(x)))
# print solution
print('Solution')
print('x1 = ' + str(x[0]))
print('x2 = ' + str(x[1]))
print('x3 = ' + str(x[2]))
print('x4 = ' + str(x[3]))
Run Code Online (Sandbox Code Playgroud)
Python Gekko 也有同样的问题:
from gekko import GEKKO
m = GEKKO()
x1,x2,x3,x4 = m.Array(m.Var,4,lb=1,ub=5)
x1.value = 1; x2.value = 5; x3.value = 5; x4.value = 1
m.Equation(x1*x2*x3*x4>=25)
m.Equation(x1**2+x2**2+x3**2+x4**2==40)
m.Minimize(x1*x4*(x1+x2+x3)+x3)
m.solve(disp=False)
print(x1.value,x2.value,x3.value,x4.value)
Run Code Online (Sandbox Code Playgroud)
如果 SLSQP 无法解决您的问题,还有一个关于 Python 非线性规划求解器的更全面的讨论线程。如果您需要有关求解器方法的更多信息,可以使用我的工程设计优化课程材料。