Python 如何正确设置带约束和多重优化的scipy.OPTIME最小化?
我是Python新手,在scipy.optimize的最小化部分遇到了一些问题。我已经建立了一个简单的例子来说明我正在尝试做什么。我的目标是确定最低采购量的项目,也尽量减少库存 我购买的所有东西都分为两个产品-25%进入产品A,75%进入产品B。产品A的一个单元大小为100,而产品B的单元大小为300。我的最低购买量为100,最高购买量为2000 下面的代码是我的目标函数的设置Python 如何正确设置带约束和多重优化的scipy.OPTIME最小化?,python,optimization,scipy,constraints,minimization,Python,Optimization,Scipy,Constraints,Minimization,我是Python新手,在scipy.optimize的最小化部分遇到了一些问题。我已经建立了一个简单的例子来说明我正在尝试做什么。我的目标是确定最低采购量的项目,也尽量减少库存 我购买的所有东西都分为两个产品-25%进入产品A,75%进入产品B。产品A的一个单元大小为100,而产品B的单元大小为300。我的最低购买量为100,最高购买量为2000 下面的代码是我的目标函数的设置 import math from scipy.optimize import minimize unitsize =
import math
from scipy.optimize import minimize
unitsize = [100, 300]
proportion = [0.25, 0.75]
minpurchase = 100
maxpurchase = 2000
def stock (purchase):
test = []
for i in xrange(len(unitsize)):
product_purchase = purchase * proportion[i]
units = math.floor(product_purchase / unitsize[i])
y = product_purchase - (units * unitsize[i])
test.append(y)
z = sum(test)
return z
我已经测试了stock函数,它似乎按预期工作。例如,当我调用stock(500)、stock(400)和stock(300)时,它分别正确地返回100、0和300
然后,我尝试按照下面的步骤实现最小化,并根据最小和最大购买金额进行约束
< P>但是,当我用一个初始猜测为零开始时,它会返回100的结果,我认为这个结果是错误的,因为它会导致100个库存,而没有完整的单位。例如,我预计结果为400(库存为零)。同样的问题也会发生,例如,当初始猜测为100时
cons = ({'type': 'ineq', 'fun': lambda x: x[0] - minpurchase},
{'type': 'ineq', 'fun': lambda x: x[0] + maxpurchase}
)
print minimize(lambda x: stock(x[0]), [0],
method='COBYLA',
constraints = cons,
options={'maxiter':10000})
status: 1
nfev: 106
maxcv: -0.0
success: True
fun: 100.0
x: array([ 100.])
message: 'Optimization terminated successfully.'
当我以500的初始猜测开始时,返回的结果在400是正确的。然而,当例如从1900开始时,它也返回1600作为结果,因为在该点上库存也为零
两个问题:
testvalues = [1000,2000]
for j in range(len(testvalues)):
print minimize(lambda x: stock(x[0]), testvalues[j],
method='COBYLA',
constraints = cons,
options={'maxiter':10000})
[...]
IndexError: too many indices for array
非常感谢任何帮助和指点,我整天都在努力让它工作。这个错误是因为COBYLA方法不处理边界。只有BFGS、L-BFGS-B和SLSQP方法可以。见:
您的第二个条件是
x[0]+maxpurchase>=0
,它不限制最大购买量。此外,对于简单边界,使用bounds
参数可能比使用约束更有效。谢谢你的评论-我想我没有正确理解如何设置约束。你能帮我理解怎么正确地写吗?我已经研究了边界,但是我得到了这个错误“RuntimeWarning:Method COBYLA无法处理边界”