最近在跟着B站的平成最强假面骑士学习数学建模,我是想走python路径的,同时也是一个刚刚入门数学建模的小白,现将学习到1.3的笔记记录一下,顺带发现了一个错误并加以修正
KKT
附上视频例题
视频代码复现:
from scipy.optimize import minimize
import numpy as np
def func(x):
return 10.5+0.3*x[0]+0.32*x[1]+0.3*x[2]+0.0007*x[0]**2+0.0004*x[1]**2+0.00045*x[2]**2
cons=({"type":'eq','func':lambda x:x[0]+x[1]+x[2]-700})
b1,b2,b3=(100,200),(120,250),(150,300)
x0=np.array((180,230,290))
res=minimize(func,x0,method='BFGS',constraints=cons,bounds=(b1,b2,b3))
print(res)
运行结果如下:
翻译后发现是BFGS无法处理约束条件
在评论区回复后,假面骑士回复了我的消息,说可能是约束条件有冲突,让我使用不同的求解器去尝试一下
在csdn了一段时间后,了解了如何解决,在此感谢这篇文章的作者,我从他的代码段中找到了思路https://blog.csdn.net/sinat_17697111/article/details/81534935
即为,去掉bounds,给各参数赋上下限,在cons中手敲各参数的约束代码,如下
from scipy.optimize import minimize
import numpy as np
def fun(x):
return 10.5+0.3*x[0]+0.32*x[1]+0.3*x[2]+0.0007*x[0]**2+0.0004*x[1]**2+0.00045*x[2]**2
x0min,x0max,x1min,x1max,x2min,x2max=100,200,120,250,150,300
#给三个变量赋上下限
cons=({"type":'eq','fun':lambda x:x[0]+x[1]+x[2]-700},\
{"type":'ineq','fun':lambda x : x[0] - x0min},\
{"type":'ineq','fun':lambda x : -x[0] + x0max},\
{"type":'ineq','fun':lambda x : x[1] - x1min},\
{"type":'ineq','fun':lambda x : -x[1] + x1max},\
{"type":'ineq','fun':lambda x : x[2] - x2min},\
{"type":'ineq','fun':lambda x : -x[2] + x2max})
# 约束条件 分为 eq 和 ineq
#eq表示 函数结果等于0 ; ineq 表示 表达式大于等于0
#tips:由于ineq为f(x)≥0,
#所以在遇到上限时需要在等式左边加一个负号,由于f(max)≥f(x0),所以-f(x0)+f(max)≥0
x0=np.array((180,230,290))
res=minimize(fun,x0,method='SLSQP',constraints=cons)
print(res)
运行结果如下:
输出了正确结果
疑问: 源代码中函数定义为func,在改进代码中换成了fun,原因是当采用func时,会出现如下报错
不知为何,将【func】换回【fun】后即可正常运行
请教一下各位